mirror of
https://github.com/correl/mage.git
synced 2025-04-02 03:18:09 -09:00
- Fixed #6919. Fixed other cards with the same issue.
This commit is contained in:
parent
2a7ac3fc9e
commit
c3de6bf8a0
8 changed files with 136 additions and 83 deletions
Mage.Sets/src/mage/cards/p
Mage/src/main/java/mage/abilities/keyword
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.p;
|
||||
|
||||
import mage.MageObject;
|
||||
|
@ -26,7 +25,8 @@ public final class PraetorsGrasp extends CardImpl {
|
|||
public PraetorsGrasp(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{B}");
|
||||
|
||||
// Search target opponent's library for a card and exile it face down. Then that player shuffles their library. You may look at and play that card for as long as it remains exiled.
|
||||
// Search target opponent's library for a card and exile it face down. Then that player
|
||||
//shuffles their library. You may look at and play that card for as long as it remains exiled.
|
||||
this.getSpellAbility().addEffect(new PraetorsGraspEffect());
|
||||
this.getSpellAbility().addTarget(new TargetOpponent());
|
||||
}
|
||||
|
@ -45,7 +45,9 @@ class PraetorsGraspEffect extends OneShotEffect {
|
|||
|
||||
public PraetorsGraspEffect() {
|
||||
super(Outcome.PlayForFree);
|
||||
staticText = "Search target opponent's library for a card and exile it face down. Then that player shuffles their library. You may look at and play that card for as long as it remains exiled";
|
||||
staticText = "Search target opponent's library for a card and exile it "
|
||||
+ "face down. Then that player shuffles their library. You may "
|
||||
+ "look at and play that card for as long as it remains exiled";
|
||||
}
|
||||
|
||||
public PraetorsGraspEffect(final PraetorsGraspEffect effect) {
|
||||
|
@ -62,15 +64,21 @@ class PraetorsGraspEffect extends OneShotEffect {
|
|||
Player opponent = game.getPlayer(source.getFirstTarget());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
if (controller != null && opponent != null && sourceObject != null) {
|
||||
if (controller != null
|
||||
&& opponent != null
|
||||
&& sourceObject != null) {
|
||||
TargetCardInLibrary target = new TargetCardInLibrary();
|
||||
if (controller.searchLibrary(target, source, game, opponent.getId())) {
|
||||
UUID targetId = target.getFirstTarget();
|
||||
Card card = opponent.getLibrary().getCard(targetId, game);
|
||||
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
|
||||
if (card != null && exileId != null) {
|
||||
game.informPlayers(controller.getLogName() + " moves the searched card face down to exile");
|
||||
card.moveToExile(exileId, sourceObject.getIdName(), source.getSourceId(), game);
|
||||
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(),
|
||||
source.getSourceObjectZoneChangeCounter());
|
||||
if (card != null
|
||||
&& exileId != null) {
|
||||
game.informPlayers(controller.getLogName() + " moves the searched "
|
||||
+ "card face down to exile");
|
||||
card.moveToExile(exileId, sourceObject.getIdName(),
|
||||
source.getSourceId(), game);
|
||||
card.setFaceDown(true, game);
|
||||
game.addEffect(new PraetorsGraspPlayEffect(card.getId()), source);
|
||||
game.addEffect(new PraetorsGraspRevealEffect(card.getId()), source);
|
||||
|
@ -110,12 +118,16 @@ class PraetorsGraspPlayEffect extends AsThoughEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
if (objectId.equals(cardId) && affectedControllerId.equals(source.getControllerId())) {
|
||||
if (objectId.equals(cardId)
|
||||
&& affectedControllerId.equals(source.getControllerId())) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
|
||||
if (exileId != null && controller != null) {
|
||||
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(),
|
||||
source.getSourceObjectZoneChangeCounter());
|
||||
if (exileId != null
|
||||
&& controller != null) {
|
||||
ExileZone exileZone = game.getExile().getExileZone(exileId);
|
||||
if (exileZone != null && exileZone.contains(cardId)) {
|
||||
if (exileZone != null
|
||||
&& exileZone.contains(cardId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -152,15 +164,21 @@ class PraetorsGraspRevealEffect extends AsThoughEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
if (objectId.equals(cardId) && affectedControllerId.equals(source.getControllerId())) {
|
||||
if (objectId.equals(cardId)
|
||||
&& affectedControllerId.equals(source.getControllerId())) {
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
|
||||
if (exileId != null && sourceObject != null) {
|
||||
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(),
|
||||
source.getSourceObjectZoneChangeCounter());
|
||||
if (exileId != null
|
||||
&& sourceObject != null) {
|
||||
ExileZone exileZone = game.getExile().getExileZone(exileId);
|
||||
if (exileZone != null && exileZone.contains(cardId)) {
|
||||
if (exileZone != null
|
||||
&& exileZone.contains(cardId)) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Card card = game.getCard(cardId);
|
||||
if (controller != null && card != null && game.getState().getZone(cardId) == Zone.EXILED) {
|
||||
if (controller != null
|
||||
&& card != null
|
||||
&& game.getState().getZone(cardId) == Zone.EXILED) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
|
@ -83,7 +82,7 @@ public class EntwineAbility extends StaticAbility implements OptionalAdditionalM
|
|||
if (!(ability instanceof SpellAbility)) {
|
||||
return;
|
||||
}
|
||||
Player player = game.getPlayer(controllerId);
|
||||
Player player = game.getPlayer(ability.getControllerId());
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -105,7 +104,7 @@ public class EntwineAbility extends StaticAbility implements OptionalAdditionalM
|
|||
@Override
|
||||
public void addOptionalAdditionalModeCosts(Ability ability, Game game) {
|
||||
if (additionalCost.isActivated()) {
|
||||
for (Iterator it = ((Costs) additionalCost).iterator(); it.hasNext(); ) {
|
||||
for (Iterator it = ((Costs) additionalCost).iterator(); it.hasNext();) {
|
||||
Cost cost = (Cost) it.next();
|
||||
if (cost instanceof ManaCostsImpl) {
|
||||
ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy());
|
||||
|
|
|
@ -50,8 +50,10 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
public class KickerAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
|
||||
|
||||
protected static final String KICKER_KEYWORD = "Kicker";
|
||||
protected static final String KICKER_REMINDER_MANA = "You may pay an additional {cost} as you cast this spell.";
|
||||
protected static final String KICKER_REMINDER_COST = "You may {cost} in addition to any other costs as you cast this spell.";
|
||||
protected static final String KICKER_REMINDER_MANA = "You may pay an additional "
|
||||
+ "{cost} as you cast this spell.";
|
||||
protected static final String KICKER_REMINDER_COST = "You may {cost} in addition "
|
||||
+ "to any other costs as you cast this spell.";
|
||||
|
||||
protected Map<String, Integer> activations = new ConcurrentHashMap<>(); // zoneChangeCounter, activations
|
||||
|
||||
|
@ -93,13 +95,15 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
}
|
||||
|
||||
public final OptionalAdditionalCost addKickerCost(String manaString) {
|
||||
OptionalAdditionalCost kickerCost = new OptionalAdditionalCostImpl(keywordText, reminderText, new ManaCostsImpl(manaString));
|
||||
OptionalAdditionalCost kickerCost = new OptionalAdditionalCostImpl(
|
||||
keywordText, reminderText, new ManaCostsImpl(manaString));
|
||||
kickerCosts.add(kickerCost);
|
||||
return kickerCost;
|
||||
}
|
||||
|
||||
public final OptionalAdditionalCost addKickerCost(Cost cost) {
|
||||
OptionalAdditionalCost kickerCost = new OptionalAdditionalCostImpl(keywordText, "-", reminderText, cost);
|
||||
OptionalAdditionalCost kickerCost = new OptionalAdditionalCostImpl(
|
||||
keywordText, "-", reminderText, cost);
|
||||
kickerCosts.add(kickerCost);
|
||||
return kickerCost;
|
||||
}
|
||||
|
@ -109,9 +113,10 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
cost.reset();
|
||||
}
|
||||
String key = getActivationKey(source, "", game);
|
||||
for (Iterator<String> iterator = activations.keySet().iterator(); iterator.hasNext(); ) {
|
||||
for (Iterator<String> iterator = activations.keySet().iterator(); iterator.hasNext();) {
|
||||
String activationKey = iterator.next();
|
||||
if (activationKey.startsWith(key) && activations.get(activationKey) > 0) {
|
||||
if (activationKey.startsWith(key)
|
||||
&& activations.get(activationKey) > 0) {
|
||||
activations.put(key, 0);
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +131,8 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
String key = getActivationKey(source, costText, game);
|
||||
if (kickerCosts.size() > 1) {
|
||||
for (String activationKey : activations.keySet()) {
|
||||
if (activationKey.startsWith(key) && activations.get(activationKey) > 0) {
|
||||
if (activationKey.startsWith(key)
|
||||
&& activations.get(activationKey) > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +156,8 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
amount += activations.get(key);
|
||||
}
|
||||
activations.put(key, amount);
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.KICKED, source.getSourceId(), source.getSourceId(), source.getControllerId()));
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.KICKED,
|
||||
source.getSourceId(), source.getSourceId(), source.getControllerId()));
|
||||
}
|
||||
|
||||
private String getActivationKey(Ability source, String costText, Game game) {
|
||||
|
@ -170,7 +177,7 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
@Override
|
||||
public void addOptionalAdditionalCosts(Ability ability, Game game) {
|
||||
if (ability instanceof SpellAbility) {
|
||||
Player player = game.getPlayer(controllerId);
|
||||
Player player = game.getPlayer(ability.getControllerId());
|
||||
if (player != null) {
|
||||
this.resetKicker(game, ability);
|
||||
for (OptionalAdditionalCost kickerCost : kickerCosts) {
|
||||
|
@ -183,14 +190,17 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
}
|
||||
// TODO: add AI support to find max number of possible activations (from available mana)
|
||||
// canPay checks only single mana available, not total mana usage
|
||||
if (kickerCost.canPay(ability, sourceId, controllerId, game)
|
||||
&& player.chooseUse(/*Outcome.Benefit*/Outcome.AIDontUseIt, "Pay " + times + kickerCost.getText(false) + " ?", ability, game)) {
|
||||
if (kickerCost.canPay(ability, sourceId, ability.getControllerId(), game)
|
||||
&& player.chooseUse(/*Outcome.Benefit*/Outcome.AIDontUseIt,
|
||||
"Pay " + times + kickerCost.getText(false) + " ?", ability, game)) {
|
||||
this.activateKicker(kickerCost, ability, game);
|
||||
if (kickerCost instanceof Costs) {
|
||||
for (Iterator itKickerCost = ((Costs) kickerCost).iterator(); itKickerCost.hasNext(); ) {
|
||||
for (Iterator itKickerCost = ((Costs) kickerCost).iterator(); itKickerCost.hasNext();) {
|
||||
Object kickerCostObject = itKickerCost.next();
|
||||
if ((kickerCostObject instanceof Costs) || (kickerCostObject instanceof CostsImpl)) {
|
||||
for (@SuppressWarnings("unchecked") Iterator<Cost> itDetails = ((Costs) kickerCostObject).iterator(); itDetails.hasNext(); ) {
|
||||
if ((kickerCostObject instanceof Costs)
|
||||
|| (kickerCostObject instanceof CostsImpl)) {
|
||||
for (@SuppressWarnings("unchecked") Iterator<Cost> itDetails
|
||||
= ((Costs) kickerCostObject).iterator(); itDetails.hasNext();) {
|
||||
addKickerCostsToAbility(itDetails.next(), ability, game);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
@ -43,7 +42,7 @@ import mage.players.Player;
|
|||
* mana cost. Any effects or prohibitions that would apply to casting a card
|
||||
* with these characteristics (and not the face-up cards characteristics) are
|
||||
* applied to casting this card. These values are the copiable values of that
|
||||
* objects characteristics. (See rule 613, "Interaction of Continuous Effects,"
|
||||
* object's characteristics. (See rule 613, "Interaction of Continuous Effects,"
|
||||
* and rule 706, "Copying Objects.") Put it onto the stack (as a face-down spell
|
||||
* with the same characteristics), and pay {3} rather than pay its mana cost.
|
||||
* This follows the rules for paying alternative costs. You can use morph to
|
||||
|
@ -52,13 +51,13 @@ import mage.players.Player;
|
|||
* spell had. The morph effect applies to the face-down object wherever it is,
|
||||
* and it ends when the permanent is turned face up. #
|
||||
*
|
||||
* 702.36c You cant cast a card face down if it doesnt have morph.
|
||||
* 702.36c You can't cast a card face down if it doesn't have morph.
|
||||
*
|
||||
* 702.36d If you have priority, you may turn a face-down permanent you control
|
||||
* face up. This is a special action; it doesnt use the stack (see rule 115).
|
||||
* face up. This is a special action; it doesn't use the stack (see rule 115).
|
||||
* To do this, show all players what the permanents morph cost would be if it
|
||||
* were face up, pay that cost, then turn the permanent face up. (If the
|
||||
* permanent wouldnt have a morph cost if it were face up, it cant be turned
|
||||
* permanent wouldn't have a morph cost if it were face up, it cant be turned
|
||||
* face up this way.) The morph effect on it ends, and it regains its normal
|
||||
* characteristics. Any abilities relating to the permanent entering the
|
||||
* battlefield dont trigger when its turned face up and dont have any effect,
|
||||
|
@ -73,10 +72,14 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
|
|||
|
||||
protected static final String ABILITY_KEYWORD = "Morph";
|
||||
protected static final String ABILITY_KEYWORD_MEGA = "Megamorph";
|
||||
protected static final String REMINDER_TEXT = "<i>(You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.)</i>";
|
||||
protected static final String REMINDER_TEXT_MEGA = "<i>(You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)</i>";
|
||||
protected static final String REMINDER_TEXT = "<i>(You may cast this card face down as a "
|
||||
+ "2/2 creature for {3}. Turn it face up any time for its morph cost.)</i>";
|
||||
protected static final String REMINDER_TEXT_MEGA = "<i>(You may cast this card face down "
|
||||
+ "as a 2/2 creature for {3}. Turn it face up any time for its megamorph "
|
||||
+ "cost and put a +1/+1 counter on it.)</i>";
|
||||
protected String ruleText;
|
||||
protected AlternativeCost2Impl alternateCosts = new AlternativeCost2Impl(ABILITY_KEYWORD, REMINDER_TEXT, new GenericManaCost(3));
|
||||
protected AlternativeCost2Impl alternateCosts = new AlternativeCost2Impl(
|
||||
ABILITY_KEYWORD, REMINDER_TEXT, new GenericManaCost(3));
|
||||
protected Costs<Cost> morphCosts;
|
||||
// needed to check activation status, if card changes zone after casting it
|
||||
private int zoneChangeCounter = 0;
|
||||
|
@ -166,7 +169,8 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
|
|||
@Override
|
||||
public boolean isActivated(Ability ability, Game game) {
|
||||
Card card = game.getCard(sourceId);
|
||||
if (card != null && card.getZoneChangeCounter(game) <= zoneChangeCounter + 1) {
|
||||
if (card != null
|
||||
&& card.getZoneChangeCounter(game) <= zoneChangeCounter + 1) {
|
||||
return alternateCosts.isActivated(game);
|
||||
}
|
||||
return false;
|
||||
|
@ -180,14 +184,17 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
|
|||
@Override
|
||||
public boolean askToActivateAlternativeCosts(Ability ability, Game game) {
|
||||
if (ability.getAbilityType() == AbilityType.SPELL) {
|
||||
Player player = game.getPlayer(controllerId);
|
||||
Player player = game.getPlayer(ability.getControllerId());
|
||||
Spell spell = game.getStack().getSpell(ability.getId());
|
||||
if (player != null && spell != null) {
|
||||
if (player != null
|
||||
&& spell != null) {
|
||||
this.resetMorph();
|
||||
spell.setFaceDown(true, game); // so only the back is visible
|
||||
if (alternateCosts.canPay(ability, sourceId, controllerId, game)) {
|
||||
if (player.chooseUse(Outcome.Benefit, "Cast this card as a 2/2 face-down creature for " + getCosts().getText() + " ?", ability, game)) {
|
||||
game.getState().setValue("MorphAbility" + ability.getSourceId(), "activated"); // Gift of Doom
|
||||
if (alternateCosts.canPay(ability, sourceId, ability.getControllerId(), game)) {
|
||||
if (player.chooseUse(Outcome.Benefit, "Cast this card as a 2/2 "
|
||||
+ "face-down creature for " + getCosts().getText() + " ?", ability, game)) {
|
||||
game.getState().setValue("MorphAbility"
|
||||
+ ability.getSourceId(), "activated"); // Gift of Doom
|
||||
activateMorph(game);
|
||||
// change mana costs
|
||||
ability.getManaCostsToPay().clear();
|
||||
|
@ -215,11 +222,12 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
|
|||
}
|
||||
}
|
||||
if (ability.getAbilityType() == AbilityType.PLAY_LAND) {
|
||||
Player player = game.getPlayer(controllerId);
|
||||
Player player = game.getPlayer(ability.getControllerId());
|
||||
if (player != null) {
|
||||
this.resetMorph();
|
||||
if (alternateCosts.canPay(ability, sourceId, controllerId, game)) {
|
||||
if (player.chooseUse(Outcome.Benefit, "Cast this card as a 2/2 face-down creature for " + getCosts().getText() + " ?", ability, game)) {
|
||||
if (alternateCosts.canPay(ability, sourceId, ability.getControllerId(), game)) {
|
||||
if (player.chooseUse(Outcome.Benefit, "Cast this card as a 2/2 "
|
||||
+ "face-down creature for " + getCosts().getText() + " ?", ability, game)) {
|
||||
activateMorph(game);
|
||||
// change mana costs
|
||||
ability.getManaCostsToPay().clear();
|
||||
|
|
|
@ -43,7 +43,8 @@ import mage.target.common.TargetControlledPermanent;
|
|||
public class NinjutsuAbility extends ActivatedAbilityImpl {
|
||||
|
||||
private final boolean commander;
|
||||
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("unblocked attacker you control");
|
||||
private static final FilterControlledCreaturePermanent filter =
|
||||
new FilterControlledCreaturePermanent("unblocked attacker you control");
|
||||
|
||||
static {
|
||||
filter.add(UnblockedPredicate.instance);
|
||||
|
@ -149,7 +150,8 @@ class ReturnAttackerToHandTargetCost extends CostImpl {
|
|||
for (UUID targetId : targets.get(0).getTargets()) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (permanent == null || controller == null) {
|
||||
if (permanent == null
|
||||
|| controller == null) {
|
||||
return false;
|
||||
}
|
||||
defendingPlayerId = game.getCombat().getDefenderId(permanent.getId());
|
||||
|
|
|
@ -58,7 +58,8 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost
|
|||
}
|
||||
|
||||
public final AlternativeCost2 addProwlCost(String manaString) {
|
||||
AlternativeCost2 prowlCost = new AlternativeCost2Impl(PROWL_KEYWORD, reminderText, new ManaCostsImpl(manaString));
|
||||
AlternativeCost2 prowlCost = new AlternativeCost2Impl(PROWL_KEYWORD,
|
||||
reminderText, new ManaCostsImpl(manaString));
|
||||
prowlCosts.add(prowlCost);
|
||||
return prowlCost;
|
||||
}
|
||||
|
@ -87,19 +88,21 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost
|
|||
@Override
|
||||
public boolean askToActivateAlternativeCosts(Ability ability, Game game) {
|
||||
if (ability instanceof SpellAbility) {
|
||||
Player player = game.getPlayer(controllerId);
|
||||
Player player = game.getPlayer(ability.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (ProwlCondition.instance.apply(game, ability)) {
|
||||
this.resetProwl();
|
||||
for (AlternativeCost2 prowlCost : prowlCosts) {
|
||||
if (prowlCost.canPay(ability, sourceId, controllerId, game)
|
||||
&& player.chooseUse(Outcome.Benefit, "Cast for " + PROWL_KEYWORD + " cost " + prowlCost.getText(true) + " ?", ability, game)) {
|
||||
if (prowlCost.canPay(ability, sourceId, ability.getControllerId(), game)
|
||||
&& player.chooseUse(Outcome.Benefit, "Cast for "
|
||||
+ PROWL_KEYWORD + " cost " + prowlCost.getText(true)
|
||||
+ " ?", ability, game)) {
|
||||
prowlCost.activate();
|
||||
ability.getManaCostsToPay().clear();
|
||||
ability.getCosts().clear();
|
||||
for (Iterator it = ((Costs) prowlCost).iterator(); it.hasNext(); ) {
|
||||
for (Iterator it = ((Costs) prowlCost).iterator(); it.hasNext();) {
|
||||
Cost cost = (Cost) it.next();
|
||||
if (cost instanceof ManaCostsImpl) {
|
||||
ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy());
|
||||
|
@ -149,8 +152,9 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost
|
|||
}
|
||||
|
||||
private void setReminderText(Card card) {
|
||||
reminderText =
|
||||
"(You may cast this for its prowl cost if you dealt combat damage to a player this turn with a creature that shared a creature type with {this}";
|
||||
reminderText
|
||||
= "(You may cast this for its prowl cost if you dealt combat damage to a "
|
||||
+ "player this turn with a creature that shared a creature type with {this}";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -161,4 +165,4 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost
|
|||
}
|
||||
return alterCosts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,15 @@ import java.util.Iterator;
|
|||
public class ReplicateAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
|
||||
|
||||
private static final String keywordText = "Replicate";
|
||||
private static final String reminderTextMana = "When you cast this spell, copy it for each time you paid its replicate cost. You may choose new targets for the copies.";
|
||||
private static final String reminderTextMana = "When you cast this spell, "
|
||||
+ "copy it for each time you paid its replicate cost."
|
||||
+ " You may choose new targets for the copies.";
|
||||
protected OptionalAdditionalCost additionalCost;
|
||||
|
||||
public ReplicateAbility(Card card, String manaString) {
|
||||
super(Zone.STACK, null);
|
||||
this.additionalCost = new OptionalAdditionalCostImpl(keywordText, reminderTextMana, new ManaCostsImpl(manaString));
|
||||
this.additionalCost = new OptionalAdditionalCostImpl(keywordText,
|
||||
reminderTextMana, new ManaCostsImpl(manaString));
|
||||
this.additionalCost.setRepeatable(true);
|
||||
setRuleAtTheTop(true);
|
||||
addSubAbility(new ReplicateTriggeredAbility());
|
||||
|
@ -77,12 +80,12 @@ public class ReplicateAbility extends StaticAbility implements OptionalAdditiona
|
|||
@Override
|
||||
public void addOptionalAdditionalCosts(Ability ability, Game game) {
|
||||
if (ability instanceof SpellAbility) {
|
||||
Player player = game.getPlayer(controllerId);
|
||||
Player player = game.getPlayer(ability.getControllerId());
|
||||
if (player != null) {
|
||||
this.resetReplicate();
|
||||
|
||||
boolean again = true;
|
||||
while (player.canRespond() && again) {
|
||||
while (player.canRespond()
|
||||
&& again) {
|
||||
String times = "";
|
||||
if (additionalCost.isRepeatable()) {
|
||||
int numActivations = additionalCost.getActivateCount();
|
||||
|
@ -91,10 +94,12 @@ public class ReplicateAbility extends StaticAbility implements OptionalAdditiona
|
|||
|
||||
// TODO: add AI support to find max number of possible activations (from available mana)
|
||||
// canPay checks only single mana available, not total mana usage
|
||||
if (additionalCost.canPay(ability, sourceId, controllerId, game)
|
||||
&& player.chooseUse(/*Outcome.Benefit*/Outcome.AIDontUseIt, new StringBuilder("Pay ").append(times).append(additionalCost.getText(false)).append(" ?").toString(), ability, game)) {
|
||||
if (additionalCost.canPay(ability, sourceId, ability.getControllerId(), game)
|
||||
&& player.chooseUse(/*Outcome.Benefit*/Outcome.AIDontUseIt,
|
||||
new StringBuilder("Pay ").append(times).append(
|
||||
additionalCost.getText(false)).append(" ?").toString(), ability, game)) {
|
||||
additionalCost.activate();
|
||||
for (Iterator it = ((Costs) additionalCost).iterator(); it.hasNext(); ) {
|
||||
for (Iterator it = ((Costs) additionalCost).iterator(); it.hasNext();) {
|
||||
Cost cost = (Cost) it.next();
|
||||
if (cost instanceof ManaCostsImpl) {
|
||||
ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy());
|
||||
|
@ -185,7 +190,8 @@ class ReplicateTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Replicate <i>(When you cast this spell, copy it for each time you paid its replicate cost. You may choose new targets for the copies.)</i>";
|
||||
return "Replicate <i>(When you cast this spell, copy it for each time you paid "
|
||||
+ "its replicate cost. You may choose new targets for the copies.)</i>";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,7 +211,8 @@ class ReplicateCopyEffect extends OneShotEffect {
|
|||
if (controller != null) {
|
||||
Spell spell = (Spell) this.getValue("ReplicateSpell");
|
||||
int replicateCount = (Integer) this.getValue("ReplicateCount");
|
||||
if (spell != null && replicateCount > 0) {
|
||||
if (spell != null
|
||||
&& replicateCount > 0) {
|
||||
// reset replicate now so the copies don't report x times Replicate
|
||||
Card card = game.getCard(spell.getSourceId());
|
||||
if (card != null) {
|
||||
|
@ -218,7 +225,8 @@ class ReplicateCopyEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
// create the copies
|
||||
StackObject newStackObject = spell.createCopyOnStack(game, source, source.getControllerId(), true, replicateCount);
|
||||
StackObject newStackObject = spell.createCopyOnStack(game, source,
|
||||
source.getControllerId(), true, replicateCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -115,9 +115,9 @@ public class SuspendAbility extends SpecialAction {
|
|||
* Gives the card the SuspendAbility
|
||||
*
|
||||
* @param suspend - amount of time counters, if Integer.MAX_VALUE is set
|
||||
* there will be {X} costs and X counters added
|
||||
* @param cost - null is used for temporary gained suspend ability
|
||||
* @param card - card that has the suspend ability
|
||||
* there will be {X} costs and X counters added
|
||||
* @param cost - null is used for temporary gained suspend ability
|
||||
* @param card - card that has the suspend ability
|
||||
*/
|
||||
public SuspendAbility(int suspend, ManaCost cost, Card card) {
|
||||
this(suspend, cost, card, false);
|
||||
|
@ -136,7 +136,8 @@ public class SuspendAbility extends SpecialAction {
|
|||
}
|
||||
StringBuilder sb = new StringBuilder("Suspend ");
|
||||
if (cost != null) {
|
||||
sb.append(suspend == Integer.MAX_VALUE ? "X" : suspend).append("—").append(cost.getText()).append(suspend
|
||||
sb.append(suspend == Integer.MAX_VALUE ? "X" : suspend).append("—")
|
||||
.append(cost.getText()).append(suspend
|
||||
== Integer.MAX_VALUE ? ". X can't be 0" : "");
|
||||
if (!shortRule) {
|
||||
sb.append(" <i>(Rather than cast this card from your hand, pay ")
|
||||
|
@ -174,8 +175,8 @@ public class SuspendAbility extends SpecialAction {
|
|||
ability.setControllerId(card.getOwnerId());
|
||||
game.getState().addOtherAbility(card, ability);
|
||||
|
||||
SuspendBeginningOfUpkeepInterveningIfTriggeredAbility ability1 =
|
||||
new SuspendBeginningOfUpkeepInterveningIfTriggeredAbility();
|
||||
SuspendBeginningOfUpkeepInterveningIfTriggeredAbility ability1
|
||||
= new SuspendBeginningOfUpkeepInterveningIfTriggeredAbility();
|
||||
ability1.setSourceId(card.getId());
|
||||
ability1.setControllerId(card.getOwnerId());
|
||||
game.getState().addOtherAbility(card, ability1);
|
||||
|
@ -213,7 +214,7 @@ public class SuspendAbility extends SpecialAction {
|
|||
return new ActivationStatus(object.isInstant()
|
||||
|| object.hasAbility(FlashAbility.getInstance(), game)
|
||||
|| null != game.getContinuousEffects().asThough(sourceId,
|
||||
AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game)
|
||||
AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game)
|
||||
|| game.canPlaySorcery(playerId), null);
|
||||
}
|
||||
|
||||
|
@ -267,7 +268,8 @@ class SuspendExileEffect extends OneShotEffect {
|
|||
}
|
||||
card.addCounters(CounterType.TIME.createInstance(suspend), source, game);
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers(controller.getLogName() + " suspends (" + suspend + ") " + card.getLogName());
|
||||
game.informPlayers(controller.getLogName()
|
||||
+ " suspends (" + suspend + ") " + card.getLogName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -305,7 +307,8 @@ class SuspendPlayCardAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "When the last time counter is removed from this card ({this}), if it's removed from the game, " + super.getRule();
|
||||
return "When the last time counter is removed from this card ({this}), "
|
||||
+ "if it's removed from the game, " + super.getRule();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -318,7 +321,8 @@ class SuspendPlayCardEffect extends OneShotEffect {
|
|||
|
||||
public SuspendPlayCardEffect() {
|
||||
super(Outcome.PlayForFree);
|
||||
this.staticText = "play it without paying its mana cost if able. If you can't, it remains removed from the game";
|
||||
this.staticText = "play it without paying its mana cost if able. "
|
||||
+ "If you can't, it remains removed from the game";
|
||||
}
|
||||
|
||||
public SuspendPlayCardEffect(final SuspendPlayCardEffect effect) {
|
||||
|
@ -426,7 +430,7 @@ class SuspendBeginningOfUpkeepInterveningIfTriggeredAbility extends ConditionalI
|
|||
|
||||
public SuspendBeginningOfUpkeepInterveningIfTriggeredAbility() {
|
||||
super(new BeginningOfUpkeepTriggeredAbility(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()),
|
||||
TargetController.YOU, false),
|
||||
TargetController.YOU, false),
|
||||
SuspendedCondition.instance,
|
||||
"At the beginning of your upkeep, if this card ({this}) is suspended, remove a time counter from it.");
|
||||
this.setRuleVisible(false);
|
||||
|
|
Loading…
Add table
Reference in a new issue