mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
Some changes/fixes to conspire ability.
This commit is contained in:
parent
8e50c18d8c
commit
7b68604471
14 changed files with 234 additions and 128 deletions
|
@ -58,7 +58,7 @@ public class AEthertow extends CardImpl {
|
|||
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
|
||||
|
||||
// Conspire
|
||||
this.addAbility(new ConspireAbility(this));
|
||||
this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.ONE));
|
||||
}
|
||||
|
||||
public AEthertow(final AEthertow card) {
|
||||
|
|
|
@ -51,7 +51,7 @@ public class BarkshellBlessing extends CardImpl {
|
|||
this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn));
|
||||
|
||||
// Conspire
|
||||
this.addAbility(new ConspireAbility(this));
|
||||
this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.ONE));
|
||||
}
|
||||
|
||||
public BarkshellBlessing(final BarkshellBlessing card) {
|
||||
|
|
|
@ -50,7 +50,7 @@ public class BurnTrail extends CardImpl {
|
|||
this.getSpellAbility().addTarget(new TargetCreatureOrPlayer());
|
||||
|
||||
// Conspire
|
||||
this.addAbility(new ConspireAbility(this));
|
||||
this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.ONE));
|
||||
}
|
||||
|
||||
public BurnTrail(final BurnTrail card) {
|
||||
|
|
|
@ -51,7 +51,7 @@ public class DisturbingPlot extends CardImpl {
|
|||
this.getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard")));
|
||||
|
||||
// Conspire
|
||||
this.addAbility(new ConspireAbility(this));
|
||||
this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.ONE));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ public class GhastlyDiscovery extends CardImpl {
|
|||
this.getSpellAbility().addEffect(new GhastlyDiscoveryEffect());
|
||||
|
||||
// Conspire
|
||||
this.addAbility(new ConspireAbility(this));
|
||||
this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.NONE));
|
||||
}
|
||||
|
||||
public GhastlyDiscovery(final GhastlyDiscovery card) {
|
||||
|
|
|
@ -58,7 +58,7 @@ public class Giantbaiting extends CardImpl {
|
|||
this.getSpellAbility().addEffect(new GiantbaitingEffect());
|
||||
|
||||
// Conspire
|
||||
this.addAbility(new ConspireAbility(this));
|
||||
this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.NONE));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ public class GleefulSabotage extends CardImpl {
|
|||
this.getSpellAbility().addTarget(new TargetPermanent(new FilterArtifactOrEnchantmentPermanent()));
|
||||
|
||||
// Conspire
|
||||
this.addAbility(new ConspireAbility(this));
|
||||
this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.ONE));
|
||||
}
|
||||
|
||||
public GleefulSabotage(final GleefulSabotage card) {
|
||||
|
|
|
@ -50,7 +50,7 @@ public class MemorySluice extends CardImpl {
|
|||
this.getSpellAbility().addTarget(new TargetPlayer());
|
||||
|
||||
// Conspire
|
||||
this.addAbility(new ConspireAbility(this));
|
||||
this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.ONE));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ public class MineExcavation extends CardImpl {
|
|||
this.getSpellAbility().addTarget(new TargetCardInGraveyard(filter));
|
||||
|
||||
// Conspire
|
||||
this.addAbility(new ConspireAbility(this));
|
||||
this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.ONE));
|
||||
}
|
||||
|
||||
public MineExcavation(final MineExcavation card) {
|
||||
|
|
|
@ -64,7 +64,7 @@ public class TraitorsRoar extends CardImpl {
|
|||
this.getSpellAbility().addEffect(new TraitorsRoarEffect());
|
||||
|
||||
// Conspire
|
||||
this.addAbility(new ConspireAbility(this));
|
||||
this.addAbility(new ConspireAbility(getId(), ConspireAbility.ConspireTargets.ONE));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
@ -40,31 +39,31 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
|
|||
public class ConspireTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* 702.77. Conspire
|
||||
* 702.77a Conspire is a keyword that represents two abilities. The first is a static ability that functions
|
||||
* while the spell with conspire is on the stack. The second is a triggered ability that functions
|
||||
* while the spell with conspire is on the stack. “Conspire” means “As an additional cost to cast
|
||||
* this spell, you may tap two untapped creatures you control that each share a color with it” and
|
||||
* “When you cast this spell, if its conspire cost was paid, copy it. If the spell has any targets, you
|
||||
* may choose new targets for the copy.” Paying a spell’s conspire cost follows the rules for
|
||||
* paying additional costs in rules 601.2b and 601.2e–g.
|
||||
* 702.77. Conspire 702.77a Conspire is a keyword that represents two
|
||||
* abilities. The first is a static ability that functions while the spell
|
||||
* with conspire is on the stack. The second is a triggered ability that
|
||||
* functions while the spell with conspire is on the stack. “Conspire” means
|
||||
* “As an additional cost to cast this spell, you may tap two untapped
|
||||
* creatures you control that each share a color with it” and “When you cast
|
||||
* this spell, if its conspire cost was paid, copy it. If the spell has any
|
||||
* targets, you may choose new targets for the copy.” Paying a spell’s
|
||||
* conspire cost follows the rules for paying additional costs in rules
|
||||
* 601.2b and 601.2e–g.
|
||||
*
|
||||
* 702.77b If a spell has multiple instances of conspire, each is paid separately and triggers based on
|
||||
* its own payment, not any other instance of conspire
|
||||
* 702.77b If a spell has multiple instances of conspire, each is paid
|
||||
* separately and triggers based on its own payment, not any other instance
|
||||
* of conspire
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Burn Trail
|
||||
* Sorcery, 3R (4)
|
||||
* Burn Trail deals 3 damage to target creature or player.
|
||||
* Burn Trail Sorcery, 3R (4) Burn Trail deals 3 damage to target creature
|
||||
* or player.
|
||||
*
|
||||
* Conspire (As you cast this spell, you may tap two untapped creatures you
|
||||
* control that share a color with it. When you do, copy it and you may
|
||||
* choose a new target for the copy.)
|
||||
*
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testConspire() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
|
||||
|
@ -72,7 +71,6 @@ public class ConspireTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin");
|
||||
addCard(Zone.HAND, playerA, "Burn Trail");
|
||||
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Burn Trail", playerB);
|
||||
setChoice(playerA, "Yes");
|
||||
|
||||
|
@ -93,7 +91,6 @@ public class ConspireTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin");
|
||||
addCard(Zone.HAND, playerA, "Burn Trail");
|
||||
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Burn Trail", playerB);
|
||||
setChoice(playerA, "No");
|
||||
|
||||
|
@ -107,4 +104,50 @@ public class ConspireTest extends CardTestPlayerBase {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWortTheRaidmother() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 7);
|
||||
// When Wort, the Raidmother enters the battlefield, put two 1/1 red and green Goblin Warrior creature tokens onto the battlefield.
|
||||
// Each red or green instant or sorcery spell you cast has conspire.
|
||||
// (As you cast the spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose new targets for the copy.)
|
||||
addCard(Zone.HAND, playerA, "Wort, the Raidmother");
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Wort, the Raidmother");// {4}{R/G}{R/G}
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
setChoice(playerA, "Yes");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertPermanentCount(playerA, "Wort, the Raidmother", 1);
|
||||
assertGraveyardCount(playerA, "Lightning Bolt", 1);
|
||||
assertLife(playerB, 14);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWortTheRaidmotherWithConspireSpell() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 10);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin", 2);
|
||||
// When Wort, the Raidmother enters the battlefield, put two 1/1 red and green Goblin Warrior creature tokens onto the battlefield.
|
||||
// Each red or green instant or sorcery spell you cast has conspire.
|
||||
// (As you cast the spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose new targets for the copy.)
|
||||
addCard(Zone.HAND, playerA, "Wort, the Raidmother");
|
||||
addCard(Zone.HAND, playerA, "Burn Trail");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Wort, the Raidmother"); // {4}{R/G}{R/G}
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Burn Trail", playerB);
|
||||
setChoice(playerA, "Yes"); // use Conspire from Burn Trail itself
|
||||
setChoice(playerA, "Yes"); // use Conspire gained from Wort, the Raidmother
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertPermanentCount(playerA, "Wort, the Raidmother", 1);
|
||||
assertLife(playerB, 11);
|
||||
assertLife(playerA, 20);
|
||||
assertGraveyardCount(playerA, "Burn Trail", 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -445,7 +445,14 @@ public abstract class AbilityImpl implements Ability {
|
|||
public boolean activateAlternateOrAdditionalCosts(MageObject sourceObject, boolean noMana, Player controller, Game game) {
|
||||
boolean alternativeCostisUsed = false;
|
||||
if (sourceObject != null && !(sourceObject instanceof Permanent) && !(this instanceof FlashbackAbility)) {
|
||||
for (Ability ability : sourceObject.getAbilities()) {
|
||||
Abilities<Ability> abilities = null;
|
||||
if (sourceObject instanceof Card) {
|
||||
abilities = ((Card) sourceObject).getAbilities(game);
|
||||
} else {
|
||||
sourceObject.getAbilities();
|
||||
}
|
||||
if (abilities != null) {
|
||||
for (Ability ability : abilities) {
|
||||
// if cast for noMana no Alternative costs are allowed
|
||||
if (!noMana && ability instanceof AlternativeSourceCosts) {
|
||||
AlternativeSourceCosts alternativeSpellCosts = (AlternativeSourceCosts) ability;
|
||||
|
@ -461,6 +468,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
((OptionalAdditionalSourceCosts) ability).addOptionalAdditionalCosts(this, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
// controller specific alternate spell costs
|
||||
if (!noMana && !alternativeCostisUsed) {
|
||||
if (this.getAbilityType().equals(AbilityType.SPELL)) {
|
||||
|
|
|
@ -27,14 +27,16 @@
|
|||
*/
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.Costs;
|
||||
import mage.abilities.costs.OptionalAdditionalCost;
|
||||
import mage.abilities.costs.OptionalAdditionalCostImpl;
|
||||
import mage.abilities.costs.OptionalAdditionalSourceCosts;
|
||||
import mage.abilities.costs.common.TapTargetCost;
|
||||
|
@ -50,48 +52,77 @@ import mage.filter.predicate.permanent.TappedPredicate;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.game.stack.StackObject;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
/**
|
||||
* 702.77. Conspire 702.77a Conspire is a keyword that represents two abilities.
|
||||
* The first is a static ability that functions while the spell with conspire is
|
||||
* on the stack. The second is a triggered ability that functions while the
|
||||
* spell with conspire is on the stack. "Conspire" means "As an additional cost
|
||||
* to cast this spell, you may tap two untapped creatures you control that each
|
||||
* share a color with it" and "When you cast this spell, if its conspire cost
|
||||
* was paid, copy it. If the spell has any targets, you may choose new targets
|
||||
* for the copy." Paying a spell’s conspire cost follows the rules for paying
|
||||
* additional costs in rules 601.2b and 601.2e–g. 702.77b If a spell has
|
||||
* multiple instances of conspire, each is paid separately and triggers based on
|
||||
* its own payment, not any other instance of conspire. *
|
||||
/*
|
||||
* 702.77. Conspire
|
||||
* 702.77a Conspire is a keyword that represents two abilities.
|
||||
* The first is a static ability that functions while the spell with conspire is on the stack.
|
||||
* The second is a triggered ability that functions while the spell with conspire is on the stack.
|
||||
* "Conspire" means "As an additional cost to cast this spell,
|
||||
* you may tap two untapped creatures you control that each share a color with it"
|
||||
* and "When you cast this spell, if its conspire cost was paid, copy it.
|
||||
* If the spell has any targets, you may choose new targets for the copy."
|
||||
* Paying a spell’s conspire cost follows the rules for paying additional costs in rules 601.2b and 601.2e–g.
|
||||
* 702.77b If a spell has multiple instances of conspire, each is paid separately and triggers
|
||||
* based on its own payment, not any other instance of conspire. *
|
||||
*
|
||||
* @author jeffwadsworth heavily based off the replicate keyword by LevelX
|
||||
*/
|
||||
public class ConspireAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
|
||||
|
||||
private static final String keywordText = "Conspire";
|
||||
private static final String reminderTextCost = "<i>As you cast this spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose a new target for the copy.)</i>";
|
||||
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("two untapped creatures you control that share a color with it");
|
||||
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped creatures you control that share a color with it");
|
||||
protected static final String CONSPIRE_ACTIVATION_KEY = "ConspireActivation";
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(new TappedPredicate()));
|
||||
filter.add(new SharesColorWithSourcePredicate());
|
||||
}
|
||||
|
||||
Cost costConspire = new TapTargetCost(new TargetControlledPermanent(2, 2, filter, true));
|
||||
OptionalAdditionalCost conspireCost = new OptionalAdditionalCostImpl(keywordText, "-", reminderTextCost, costConspire);
|
||||
public enum ConspireTargets {
|
||||
|
||||
public ConspireAbility(Card card) {
|
||||
NONE,
|
||||
ONE,
|
||||
MORE
|
||||
}
|
||||
|
||||
private UUID conspireId;
|
||||
private String reminderText;
|
||||
private OptionalAdditionalCostImpl conspireCost;
|
||||
|
||||
/**
|
||||
* Unique Id for a ConspireAbility but may not change while a continuous
|
||||
* effect gives Conspire
|
||||
*
|
||||
* @param conspireId
|
||||
* @param conspireTargets controls the content of the reminder text
|
||||
*/
|
||||
public ConspireAbility(UUID conspireId, ConspireTargets conspireTargets) {
|
||||
super(Zone.STACK, null);
|
||||
setRuleAtTheTop(false);
|
||||
addSubAbility(new ConspireTriggeredAbility());
|
||||
this.conspireId = conspireId;
|
||||
switch (conspireTargets) {
|
||||
case NONE:
|
||||
reminderText = "As you cast this spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it.)";
|
||||
break;
|
||||
case ONE:
|
||||
reminderText = "As you cast this spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose a new target for the copy.)";
|
||||
break;
|
||||
case MORE:
|
||||
reminderText = "As you cast this spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose a new targets for the copy.)";
|
||||
break;
|
||||
}
|
||||
conspireCost = new OptionalAdditionalCostImpl(keywordText, "-", reminderText,
|
||||
new TapTargetCost(new TargetControlledPermanent(2, 2, filter, true)));
|
||||
addSubAbility(new ConspireTriggeredAbility(conspireId));
|
||||
}
|
||||
|
||||
public ConspireAbility(final ConspireAbility ability) {
|
||||
super(ability);
|
||||
conspireCost = ability.conspireCost;
|
||||
this.conspireId = ability.conspireId;
|
||||
this.conspireCost = ability.conspireCost.copy();
|
||||
this.reminderText = ability.reminderText;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -106,18 +137,21 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActivated() {
|
||||
if (conspireCost != null) {
|
||||
return conspireCost.isActivated();
|
||||
}
|
||||
return false;
|
||||
public UUID getConspireId() {
|
||||
return conspireId;
|
||||
}
|
||||
|
||||
public void resetConspire() {
|
||||
if (conspireCost != null) {
|
||||
conspireCost.reset();
|
||||
@Override
|
||||
public boolean isActivated() {
|
||||
throw new UnsupportedOperationException("Use ConspireAbility.isActivated(Ability ability, Game game) method instead!");
|
||||
}
|
||||
|
||||
public boolean isActivated(Ability ability, Game game) {
|
||||
Set<UUID> activations = (Set<UUID>) game.getState().getValue(CONSPIRE_ACTIVATION_KEY + ability.getId());
|
||||
if (activations != null) {
|
||||
return activations.contains(getConspireId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -125,9 +159,9 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
|
|||
if (ability instanceof SpellAbility) {
|
||||
Player player = game.getPlayer(controllerId);
|
||||
if (player != null) {
|
||||
this.resetConspire();
|
||||
if (player.chooseUse(Outcome.Benefit, new StringBuilder("Pay ").append(conspireCost.getText(false)).append(" ?").toString(), ability, game)) {
|
||||
conspireCost.activate();
|
||||
resetConspire(ability, game);
|
||||
if (player.chooseUse(Outcome.Benefit, "Pay " + conspireCost.getText(false) + " ?", ability, game)) {
|
||||
activateConspire(ability, game);
|
||||
for (Iterator it = ((Costs) conspireCost).iterator(); it.hasNext();) {
|
||||
Cost cost = (Cost) it.next();
|
||||
ability.getCosts().add(cost.copy());
|
||||
|
@ -137,6 +171,22 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
|
|||
}
|
||||
}
|
||||
|
||||
private void activateConspire(Ability ability, Game game) {
|
||||
Set<UUID> activations = (Set<UUID>) game.getState().getValue(CONSPIRE_ACTIVATION_KEY + ability.getId());
|
||||
if (activations == null) {
|
||||
activations = new HashSet<>();
|
||||
game.getState().setValue(CONSPIRE_ACTIVATION_KEY + ability.getId(), activations);
|
||||
}
|
||||
activations.add(getConspireId());
|
||||
}
|
||||
|
||||
private void resetConspire(Ability ability, Game game) {
|
||||
Set<UUID> activations = (Set<UUID>) game.getState().getValue(CONSPIRE_ACTIVATION_KEY + ability.getId());
|
||||
if (activations != null) {
|
||||
activations.remove(getConspireId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -167,13 +217,17 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
|
|||
|
||||
class ConspireTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
public ConspireTriggeredAbility() {
|
||||
private UUID conspireId;
|
||||
|
||||
public ConspireTriggeredAbility(UUID conspireId) {
|
||||
super(Zone.STACK, new ConspireEffect());
|
||||
this.conspireId = conspireId;
|
||||
this.setRuleVisible(false);
|
||||
}
|
||||
|
||||
private ConspireTriggeredAbility(final ConspireTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.conspireId = ability.conspireId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -188,73 +242,72 @@ class ConspireTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getSourceId().equals(this.sourceId)) {
|
||||
StackObject spell = game.getStack().getStackObject(this.sourceId);
|
||||
if (spell instanceof Spell) {
|
||||
Card card = game.getCard(spell.getSourceId());
|
||||
if (card != null) {
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
if (ability instanceof ConspireAbility) {
|
||||
if (((ConspireAbility) ability).isActivated()) {
|
||||
if (event.getSourceId().equals(getSourceId())) {
|
||||
Spell spell = game.getStack().getSpell(event.getSourceId());
|
||||
for (Ability ability : spell.getAbilities(game)) {
|
||||
if (ability instanceof ConspireAbility
|
||||
&& ((ConspireAbility) ability).getConspireId().equals(getConspireId())) {
|
||||
if (((ConspireAbility) ability).isActivated(spell.getSpellAbility(), game)) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setValue("ConspireSpell", spell);
|
||||
if (effect instanceof ConspireEffect) {
|
||||
((ConspireEffect) effect).setConspiredSpell(spell);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public UUID getConspireId() {
|
||||
return conspireId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Conspire: <i>As you cast this spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose a new target for the copy.)</i>";
|
||||
return "When you pay the conspire costs, copy it and you may choose a new target for the copy.";
|
||||
}
|
||||
}
|
||||
|
||||
class ConspireEffect extends OneShotEffect {
|
||||
|
||||
private Spell conspiredSpell;
|
||||
|
||||
public ConspireEffect() {
|
||||
super(Outcome.Copy);
|
||||
}
|
||||
|
||||
public ConspireEffect(final ConspireEffect effect) {
|
||||
super(effect);
|
||||
this.conspiredSpell = effect.conspiredSpell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Spell spell = (Spell) this.getValue("ConspireSpell");
|
||||
if (spell != null) {
|
||||
Card card = game.getCard(spell.getSourceId());
|
||||
if (controller != null && conspiredSpell != null) {
|
||||
Card card = game.getCard(conspiredSpell.getSourceId());
|
||||
if (card != null) {
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
if (ability instanceof ConspireAbility) {
|
||||
if (((ConspireAbility) ability).isActivated()) {
|
||||
((ConspireAbility) ability).resetConspire();
|
||||
}
|
||||
}
|
||||
}
|
||||
Spell copy = spell.copySpell();
|
||||
Spell copy = conspiredSpell.copySpell();
|
||||
copy.setControllerId(source.getControllerId());
|
||||
copy.setCopiedSpell(true);
|
||||
game.getStack().push(copy);
|
||||
copy.chooseNewTargets(game, source.getControllerId());
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers(new StringBuilder(controller.getLogName()).append(copy.getActivatedMessage(game)).toString());
|
||||
game.informPlayers(controller.getLogName() + copy.getActivatedMessage(game));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setConspiredSpell(Spell conspiredSpell) {
|
||||
this.conspiredSpell = conspiredSpell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConspireEffect copy() {
|
||||
return new ConspireEffect(this);
|
||||
|
|
|
@ -106,6 +106,7 @@ public abstract class StackObjImpl implements StackObject {
|
|||
public boolean chooseNewTargets(Game game, UUID targetControllerId, boolean forceChange, boolean onlyOneTarget, FilterPermanent filterNewTarget) {
|
||||
Player targetController = game.getPlayer(targetControllerId);
|
||||
if (targetController != null) {
|
||||
StringBuilder oldTargetDescription = new StringBuilder();
|
||||
StringBuilder newTargetDescription = new StringBuilder();
|
||||
// Fused split spells or spells where "Splice on Arcane" was used can have more than one ability
|
||||
Abilities<Ability> objectAbilities = new AbilitiesImpl<>();
|
||||
|
@ -118,6 +119,7 @@ public abstract class StackObjImpl implements StackObject {
|
|||
// Some spells can have more than one mode
|
||||
for (UUID modeId : ability.getModes().getSelectedModes()) {
|
||||
Mode mode = ability.getModes().get(modeId);
|
||||
oldTargetDescription.append(ability.getTargetDescription(mode.getTargets(), game));
|
||||
for (Target target : mode.getTargets()) {
|
||||
Target newTarget = chooseNewTarget(targetController, ability, mode, target, forceChange, filterNewTarget, game);
|
||||
// clear the old target and copy all targets from new target
|
||||
|
@ -131,7 +133,7 @@ public abstract class StackObjImpl implements StackObject {
|
|||
}
|
||||
|
||||
}
|
||||
if (newTargetDescription.length() > 0 && !game.isSimulation()) {
|
||||
if (!newTargetDescription.toString().equals(oldTargetDescription.toString()) && !game.isSimulation()) {
|
||||
game.informPlayers(this.getLogName() + " is now " + newTargetDescription.toString());
|
||||
}
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue