mirror of
https://github.com/correl/mage.git
synced 2024-11-28 19:19:55 +00:00
Real fix for 4125d1eb46
, updated outdated comments.
This commit is contained in:
parent
0136b986e4
commit
6e0184a38d
7 changed files with 50 additions and 35 deletions
|
@ -29,7 +29,7 @@ public final class AlchemistsVial extends CardImpl {
|
||||||
|
|
||||||
// When Alchemist's Vial enters the battlefield, draw a card.
|
// When Alchemist's Vial enters the battlefield, draw a card.
|
||||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)));
|
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 ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantAttackBlockTargetEffect(Duration.EndOfTurn), new ManaCostsImpl("{1}"));
|
||||||
ability.addCost(new TapSourceCost());
|
ability.addCost(new TapSourceCost());
|
||||||
ability.addCost(new SacrificeSourceCost());
|
ability.addCost(new SacrificeSourceCost());
|
||||||
|
|
|
@ -41,7 +41,7 @@ public final class BushmeatPoacher extends CardImpl {
|
||||||
this.power = new MageInt(2);
|
this.power = new MageInt(2);
|
||||||
this.toughness = new MageInt(4);
|
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 ability = new SimpleActivatedAbility(new BushmeatPoacherEffect(), new GenericManaCost(1));
|
||||||
ability.addCost(new TapSourceCost());
|
ability.addCost(new TapSourceCost());
|
||||||
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
|
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
|
||||||
|
|
|
@ -19,7 +19,6 @@ import mage.constants.Zone;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jmharmon
|
* @author jmharmon
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -32,7 +31,7 @@ public final class GoldenEgg extends CardImpl {
|
||||||
// When Golden Egg enters the battlefield, draw a card.
|
// When Golden Egg enters the battlefield, draw a card.
|
||||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)));
|
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 ability = new AnyColorManaAbility(new GenericManaCost(1));
|
||||||
ability.addCost(new TapSourceCost());
|
ability.addCost(new TapSourceCost());
|
||||||
ability.addCost(new SacrificeSourceCost());
|
ability.addCost(new SacrificeSourceCost());
|
||||||
|
|
|
@ -17,14 +17,21 @@ public class KinnanBonderProdigyTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSacrificedPermanent() {
|
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);
|
addCard(Zone.BATTLEFIELD, playerA, kinnan);
|
||||||
|
//
|
||||||
|
// {1}, {T}, Sacrifice Golden Egg: Add one mana of any color.
|
||||||
addCard(Zone.BATTLEFIELD, playerA, egg);
|
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},");
|
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},");
|
||||||
|
setChoice(playerA, "Red");
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hovermyr);
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hovermyr);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.END_TURN);
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
execute();
|
execute();
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
@ -36,15 +43,24 @@ public class KinnanBonderProdigyTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSacrificedToken() {
|
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.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);
|
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);
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hovermyr);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.END_TURN);
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
execute();
|
execute();
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
|
@ -494,9 +494,7 @@ public interface Ability extends Controllable, Serializable {
|
||||||
boolean activateAlternateOrAdditionalCosts(MageObject sourceObject, boolean noMana, Player controller, Game game);
|
boolean activateAlternateOrAdditionalCosts(MageObject sourceObject, boolean noMana, Player controller, Game game);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the object that actually existed while a ability triggered or an
|
* Return source object or LKI from battlefield
|
||||||
* ability was activated. If not set yet, the current object will be
|
|
||||||
* retrieved from the game.
|
|
||||||
*
|
*
|
||||||
* @param game
|
* @param game
|
||||||
* @return
|
* @return
|
||||||
|
@ -508,9 +506,9 @@ public interface Ability extends Controllable, Serializable {
|
||||||
int getSourceObjectZoneChangeCounter();
|
int getSourceObjectZoneChangeCounter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the object that actually existed while a ability triggerd or an
|
* Returns exists source object:
|
||||||
* ability was activated only if it has not changed zone meanwhile. If not
|
* - for not activated ability - returns exists object
|
||||||
* set yet, the current object will be retrieved from the game.
|
* - for activated ability - returns exists object or LKI (if it triggers from non battlefield, e.g. sacrifice cost);
|
||||||
*
|
*
|
||||||
* @param game
|
* @param game
|
||||||
* @return
|
* @return
|
||||||
|
@ -518,16 +516,19 @@ public interface Ability extends Controllable, Serializable {
|
||||||
MageObject getSourceObjectIfItStillExists(Game game);
|
MageObject getSourceObjectIfItStillExists(Game game);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the permanent that actually existed while the ability triggerd or
|
* See getSourceObjectIfItStillExists for details. Works with Permanent only.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* @param game
|
* @param game
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Permanent getSourcePermanentIfItStillExists(Game game);
|
Permanent getSourcePermanentIfItStillExists(Game game);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns source permanent info (actual or from LKI)
|
||||||
|
*
|
||||||
|
* @param game
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
Permanent getSourcePermanentOrLKI(Game game);
|
Permanent getSourcePermanentOrLKI(Game game);
|
||||||
|
|
||||||
String getTargetDescription(Targets targets, Game game);
|
String getTargetDescription(Targets targets, Game game);
|
||||||
|
|
|
@ -22,7 +22,6 @@ import mage.game.command.Emblem;
|
||||||
import mage.game.command.Plane;
|
import mage.game.command.Plane;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.PermanentToken;
|
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
import mage.game.stack.StackAbility;
|
import mage.game.stack.StackAbility;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
@ -374,10 +373,7 @@ public abstract class AbilityImpl implements Ability {
|
||||||
|
|
||||||
// fused spell contains 3 abilities (fused, left, right)
|
// fused spell contains 3 abilities (fused, left, right)
|
||||||
// fused cost added to fused ability, so no need cost modification for other parts
|
// fused cost added to fused ability, so no need cost modification for other parts
|
||||||
boolean needCostModification = true;
|
boolean needCostModification = !CardUtil.isFusedPartAbility(this, game);
|
||||||
if (CardUtil.isFusedPartAbility(this, game)) {
|
|
||||||
needCostModification = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//20101001 - 601.2e
|
//20101001 - 601.2e
|
||||||
if (needCostModification && sourceObject != null) {
|
if (needCostModification && sourceObject != null) {
|
||||||
|
@ -603,7 +599,7 @@ public abstract class AbilityImpl implements Ability {
|
||||||
manaSymbol = "W";
|
manaSymbol = "W";
|
||||||
}
|
}
|
||||||
if (manaSymbol == null) {
|
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++) {
|
for (int i = 0; i < amountMana; i++) {
|
||||||
manaString.append('{').append(manaSymbol).append('}');
|
manaString.append('{').append(manaSymbol).append('}');
|
||||||
|
@ -1094,7 +1090,7 @@ public abstract class AbilityImpl implements Ability {
|
||||||
}
|
}
|
||||||
MageObject object = game.getObject(this.sourceId);
|
MageObject object = game.getObject(this.sourceId);
|
||||||
if (object == null) { // e.g. sacrificed token
|
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: ")
|
return new StringBuilder(" activates: ")
|
||||||
.append(object != null ? this.formatRule(getModes().getText(), object.getLogName()) : getModes().getText())
|
.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) {
|
public MageObject getSourceObjectIfItStillExists(Game game) {
|
||||||
if (getSourceObjectZoneChangeCounter() == 0
|
if (getSourceObjectZoneChangeCounter() == 0
|
||||||
|| getSourceObjectZoneChangeCounter() == game.getState().getZoneChangeCounter(getSourceId())) {
|
|| getSourceObjectZoneChangeCounter() == game.getState().getZoneChangeCounter(getSourceId())) {
|
||||||
|
// exists or lki from battlefield
|
||||||
return game.getObject(getSourceId());
|
return game.getObject(getSourceId());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1259,15 +1256,11 @@ public abstract class AbilityImpl implements Ability {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Permanent getSourcePermanentOrLKI(Game game) {
|
public Permanent getSourcePermanentOrLKI(Game game) {
|
||||||
Permanent permanent = game.getPermanentOrLKIBattlefield(getSourceId());
|
Permanent permanent = getSourcePermanentIfItStillExists(game);
|
||||||
if (permanent instanceof PermanentToken) {
|
if (permanent == null) {
|
||||||
return permanent;
|
permanent = (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD, getSourceObjectZoneChangeCounter());
|
||||||
}
|
}
|
||||||
if (getSourceObjectZoneChangeCounter() == 0
|
return permanent;
|
||||||
|| getSourceObjectZoneChangeCounter() == game.getState().getZoneChangeCounter(getSourceId())) {
|
|
||||||
return game.getPermanent(getSourceId());
|
|
||||||
}
|
|
||||||
return (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD, getSourceObjectZoneChangeCounter());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -71,6 +71,12 @@ public interface Game extends MageItem, Serializable {
|
||||||
|
|
||||||
GameOptions getOptions();
|
GameOptions getOptions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return object or LKI from battlefield
|
||||||
|
*
|
||||||
|
* @param objectId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
MageObject getObject(UUID objectId);
|
MageObject getObject(UUID objectId);
|
||||||
|
|
||||||
MageObject getBaseObject(UUID objectId);
|
MageObject getBaseObject(UUID objectId);
|
||||||
|
|
Loading…
Reference in a new issue