mirror of
https://github.com/correl/mage.git
synced 2024-11-25 11:09:53 +00:00
fixed issues with Conspire, added additional tests
This commit is contained in:
parent
86b20185f5
commit
f32d0b3e6e
3 changed files with 129 additions and 24 deletions
|
@ -35,10 +35,12 @@ public final class WortTheRaidmother extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// When Wort, the Raidmother enters the battlefield, create two 1/1 red and green Goblin Warrior creature tokens.
|
// When Wort, the Raidmother enters the battlefield, create two 1/1 red and green Goblin Warrior creature tokens.
|
||||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GoblinWarriorToken(), 2), false));
|
this.addAbility(new EntersBattlefieldTriggeredAbility(
|
||||||
|
new CreateTokenEffect(new GoblinWarriorToken(), 2)
|
||||||
|
));
|
||||||
|
|
||||||
// Each red or green instant or sorcery spell you cast has conspire.
|
// Each red or green instant or sorcery spell you cast has conspire.
|
||||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WortGainConspireEffect()));
|
this.addAbility(new SimpleStaticAbility(new WortGainConspireEffect()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private WortTheRaidmother(final WortTheRaidmother card) {
|
private WortTheRaidmother(final WortTheRaidmother card) {
|
||||||
|
@ -59,13 +61,17 @@ class WortGainConspireEffect extends ContinuousEffectImpl {
|
||||||
filter.add(Predicates.or(new ColorPredicate(ObjectColor.RED), new ColorPredicate(ObjectColor.GREEN)));
|
filter.add(Predicates.or(new ColorPredicate(ObjectColor.RED), new ColorPredicate(ObjectColor.GREEN)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ConspireAbility conspireAbility;
|
||||||
|
|
||||||
public WortGainConspireEffect() {
|
public WortGainConspireEffect() {
|
||||||
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
||||||
staticText = "Each red or green instant or sorcery spell you cast has conspire. <i>(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.)</i>";
|
staticText = "Each red or green instant or sorcery spell you cast has conspire. <i>(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.)</i>";
|
||||||
|
this.conspireAbility = new ConspireAbility(ConspireAbility.ConspireTargets.MORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WortGainConspireEffect(final WortGainConspireEffect effect) {
|
public WortGainConspireEffect(final WortGainConspireEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
|
this.conspireAbility = effect.conspireAbility;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -77,13 +83,13 @@ class WortGainConspireEffect extends ContinuousEffectImpl {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
for (StackObject stackObject : game.getStack()) {
|
for (StackObject stackObject : game.getStack()) {
|
||||||
// only spells cast, so no copies of spells
|
// only spells cast, so no copies of spells
|
||||||
if ((!(stackObject instanceof Spell)) || stackObject.isCopy()
|
if (!(stackObject instanceof Spell) || stackObject.isCopy()
|
||||||
|| !stackObject.isControlledBy(source.getControllerId())) {
|
|| !stackObject.isControlledBy(source.getControllerId())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Spell spell = (Spell) stackObject;
|
Spell spell = (Spell) stackObject;
|
||||||
if (filter.match(stackObject, game)) {
|
if (filter.match(stackObject, game)) {
|
||||||
game.getState().addOtherAbility(spell.getCard(), new ConspireAbility(ConspireAbility.ConspireTargets.MORE));
|
game.getState().addOtherAbility(spell.getCard(), conspireAbility.setAddedById(source.getSourceId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class ConspireTest extends CardTestPlayerBase {
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertLife(playerB, 14);
|
assertLife(playerB, 20 - 3 - 3);
|
||||||
assertGraveyardCount(playerA, "Burn Trail", 1);
|
assertGraveyardCount(playerA, "Burn Trail", 1);
|
||||||
assertTapped("Goblin Roughrider", true);
|
assertTapped("Goblin Roughrider", true);
|
||||||
assertTapped("Raging Goblin", true);
|
assertTapped("Raging Goblin", true);
|
||||||
|
@ -68,7 +68,7 @@ public class ConspireTest extends CardTestPlayerBase {
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertLife(playerB, 17);
|
assertLife(playerB, 20 - 3);
|
||||||
assertGraveyardCount(playerA, "Burn Trail", 1);
|
assertGraveyardCount(playerA, "Burn Trail", 1);
|
||||||
assertTapped("Goblin Roughrider", false);
|
assertTapped("Goblin Roughrider", false);
|
||||||
assertTapped("Raging Goblin", false);
|
assertTapped("Raging Goblin", false);
|
||||||
|
@ -101,12 +101,35 @@ public class ConspireTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
assertPermanentCount(playerA, "Wort, the Raidmother", 1);
|
assertPermanentCount(playerA, "Wort, the Raidmother", 1);
|
||||||
assertGraveyardCount(playerA, "Lightning Bolt", 1);
|
assertGraveyardCount(playerA, "Lightning Bolt", 1);
|
||||||
assertLife(playerB, 14);
|
assertLife(playerB, 20 - 3 - 3);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWortTheRaidmotherWithConspireSpell() {
|
public void testWortTheRaidmotherWithConspireSpellOnce() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 10);
|
||||||
|
// 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, true); // use Conspire from Burn Trail itself
|
||||||
|
setChoice(playerA, false); // don't use Conspire gained from Wort, the Raidmother
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertPermanentCount(playerA, "Wort, the Raidmother", 1);
|
||||||
|
assertLife(playerB, 20 - 3 - 3);
|
||||||
|
assertLife(playerA, 20);
|
||||||
|
assertGraveyardCount(playerA, "Burn Trail", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWortTheRaidmotherWithConspireSpellTwice() {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 10);
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 10);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin", 2);
|
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.
|
// When Wort, the Raidmother enters the battlefield, put two 1/1 red and green Goblin Warrior creature tokens onto the battlefield.
|
||||||
|
@ -124,12 +147,66 @@ public class ConspireTest extends CardTestPlayerBase {
|
||||||
setStopAt(1, PhaseStep.END_TURN);
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
execute();
|
execute();
|
||||||
assertPermanentCount(playerA, "Wort, the Raidmother", 1);
|
assertPermanentCount(playerA, "Wort, the Raidmother", 1);
|
||||||
assertLife(playerB, 11);
|
assertLife(playerB, 20 - 3 - 3 - 3);
|
||||||
assertLife(playerA, 20);
|
assertLife(playerA, 20);
|
||||||
assertGraveyardCount(playerA, "Burn Trail", 1);
|
assertGraveyardCount(playerA, "Burn Trail", 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWortTheRaidmotherWithSakashimaOnce() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 11);
|
||||||
|
// 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, "Sakashima the Impostor");
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Wort, the Raidmother"); // {4}{R/G}{R/G}
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sakashima the Impostor"); // {2}{U}{U}
|
||||||
|
setChoice(playerA, "Wort, the Raidmother");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||||
|
setChoice(playerA, true); // use Conspire gained from Wort, the Raidmother
|
||||||
|
setChoice(playerA, false); // don't use Conspire gained from Sakashima the Imposter
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertPermanentCount(playerA, "Wort, the Raidmother", 1);
|
||||||
|
assertPermanentCount(playerA, "Sakashima the Impostor", 1);
|
||||||
|
assertLife(playerB, 20 - 3 - 3);
|
||||||
|
assertLife(playerA, 20);
|
||||||
|
assertGraveyardCount(playerA, "Lightning Bolt", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWortTheRaidmotherWithSakashimaTwice() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 11);
|
||||||
|
// 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, "Sakashima the Impostor");
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Wort, the Raidmother"); // {4}{R/G}{R/G}
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sakashima the Impostor"); // {2}{U}{U}
|
||||||
|
setChoice(playerA, "Wort, the Raidmother");
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||||
|
setChoice(playerA, true); // use Conspire gained from Wort, the Raidmother
|
||||||
|
setChoice(playerA, true); // use Conspire gained from Sakashima the Imposter
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertPermanentCount(playerA, "Wort, the Raidmother", 1);
|
||||||
|
assertPermanentCount(playerA, "Sakashima the Impostor", 1);
|
||||||
|
assertLife(playerB, 20 - 3 - 3 - 3);
|
||||||
|
assertLife(playerA, 20);
|
||||||
|
assertGraveyardCount(playerA, "Lightning Bolt", 1);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConspire_User() {
|
public void testConspire_User() {
|
||||||
// Burn Trail deals 3 damage to any target.
|
// Burn Trail deals 3 damage to any target.
|
||||||
|
@ -151,7 +228,7 @@ public class ConspireTest extends CardTestPlayerBase {
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertGraveyardCount(playerA, "Burn Trail", 1);
|
assertGraveyardCount(playerA, "Burn Trail", 1);
|
||||||
assertLife(playerB, 20 - 3 * 2);
|
assertLife(playerB, 20 - 3 - 3);
|
||||||
assertTapped("Goblin Assailant", true);
|
assertTapped("Goblin Assailant", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +253,7 @@ public class ConspireTest extends CardTestPlayerBase {
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertGraveyardCount(playerA, "Burn Trail", 1);
|
assertGraveyardCount(playerA, "Burn Trail", 1);
|
||||||
assertLife(playerB, 20 - 3 * 2);
|
assertLife(playerB, 20 - 3 - 3);
|
||||||
assertTapped("Goblin Assailant", true);
|
assertTapped("Goblin Assailant", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,14 @@ import mage.filter.predicate.mageobject.SharesColorWithSourcePredicate;
|
||||||
import mage.filter.predicate.permanent.TappedPredicate;
|
import mage.filter.predicate.permanent.TappedPredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetControlledPermanent;
|
import mage.target.common.TargetControlledPermanent;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 702.77. Conspire
|
* 702.77. Conspire
|
||||||
|
@ -44,7 +43,6 @@ import java.util.Objects;
|
||||||
public class ConspireAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
|
public class ConspireAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
|
||||||
|
|
||||||
private static final String keywordText = "Conspire";
|
private static final String keywordText = "Conspire";
|
||||||
protected static final String CONSPIRE_ACTIVATION_KEY = "ConspireActivation";
|
|
||||||
private static final FilterControlledPermanent filter
|
private static final FilterControlledPermanent filter
|
||||||
= new FilterControlledPermanent("untapped creatures you control that share a color with it");
|
= new FilterControlledPermanent("untapped creatures you control that share a color with it");
|
||||||
|
|
||||||
|
@ -70,6 +68,8 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final UUID conspireId;
|
||||||
|
private UUID addedById = null;
|
||||||
private final String reminderText;
|
private final String reminderText;
|
||||||
private final OptionalAdditionalCost conspireCost;
|
private final OptionalAdditionalCost conspireCost;
|
||||||
|
|
||||||
|
@ -81,17 +81,20 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
|
||||||
*/
|
*/
|
||||||
public ConspireAbility(ConspireTargets conspireTargets) {
|
public ConspireAbility(ConspireTargets conspireTargets) {
|
||||||
super(Zone.STACK, null);
|
super(Zone.STACK, null);
|
||||||
|
this.conspireId = UUID.randomUUID();
|
||||||
reminderText = conspireTargets.getReminder();
|
reminderText = conspireTargets.getReminder();
|
||||||
this.conspireCost = new OptionalAdditionalCostImpl(
|
this.conspireCost = new OptionalAdditionalCostImpl(
|
||||||
keywordText, " ", reminderText,
|
keywordText, " ", reminderText,
|
||||||
new TapTargetCost(new TargetControlledPermanent(2, filter))
|
new TapTargetCost(new TargetControlledPermanent(2, filter))
|
||||||
);
|
);
|
||||||
this.conspireCost.setCostType(VariableCostType.ADDITIONAL);
|
this.conspireCost.setCostType(VariableCostType.ADDITIONAL);
|
||||||
addSubAbility(new ConspireTriggeredAbility());
|
this.addSubAbility(new ConspireTriggeredAbility(conspireId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConspireAbility(final ConspireAbility ability) {
|
public ConspireAbility(final ConspireAbility ability) {
|
||||||
super(ability);
|
super(ability);
|
||||||
|
this.conspireId = ability.conspireId;
|
||||||
|
this.addedById = ability.addedById;
|
||||||
this.conspireCost = ability.conspireCost.copy();
|
this.conspireCost = ability.conspireCost.copy();
|
||||||
this.reminderText = ability.reminderText;
|
this.reminderText = ability.reminderText;
|
||||||
}
|
}
|
||||||
|
@ -124,9 +127,11 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
|
||||||
}
|
}
|
||||||
// AI supports conspire
|
// AI supports conspire
|
||||||
if (!conspireCost.canPay(ability, this, getControllerId(), game)
|
if (!conspireCost.canPay(ability, this, getControllerId(), game)
|
||||||
|| !player.chooseUse(Outcome.Benefit, "Pay " + conspireCost.getText(false) + " ?", ability, game)) {
|
|| !player.chooseUse(Outcome.Benefit, "Pay "
|
||||||
|
+ conspireCost.getText(false) + " ?", ability, game)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ability.getEffects().setValue("ConspireActivation" + conspireId + addedById, true);
|
||||||
for (Iterator<Cost> it = ((Costs<Cost>) conspireCost).iterator(); it.hasNext(); ) {
|
for (Iterator<Cost> it = ((Costs<Cost>) conspireCost).iterator(); it.hasNext(); ) {
|
||||||
Cost cost = (Cost) it.next();
|
Cost cost = (Cost) it.next();
|
||||||
if (cost instanceof ManaCostsImpl) {
|
if (cost instanceof ManaCostsImpl) {
|
||||||
|
@ -151,17 +156,32 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
|
||||||
public String getCastMessageSuffix() {
|
public String getCastMessageSuffix() {
|
||||||
return conspireCost != null ? conspireCost.getCastSuffixMessage(0) : "";
|
return conspireCost != null ? conspireCost.getCastSuffixMessage(0) : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConspireAbility setAddedById(UUID addedById) {
|
||||||
|
this.addedById = addedById;
|
||||||
|
CardUtil.castStream(
|
||||||
|
this.subAbilities.stream(),
|
||||||
|
ConspireTriggeredAbility.class
|
||||||
|
).forEach(ability -> ability.setAddedById(addedById));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConspireTriggeredAbility extends CastSourceTriggeredAbility {
|
class ConspireTriggeredAbility extends CastSourceTriggeredAbility {
|
||||||
|
|
||||||
public ConspireTriggeredAbility() {
|
private final UUID conspireId;
|
||||||
|
private UUID addedById = null;
|
||||||
|
|
||||||
|
public ConspireTriggeredAbility(UUID conspireId) {
|
||||||
super(new CopySourceSpellEffect(), false);
|
super(new CopySourceSpellEffect(), false);
|
||||||
this.setRuleVisible(false);
|
this.setRuleVisible(false);
|
||||||
|
this.conspireId = conspireId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConspireTriggeredAbility(final ConspireTriggeredAbility ability) {
|
private ConspireTriggeredAbility(final ConspireTriggeredAbility ability) {
|
||||||
super(ability);
|
super(ability);
|
||||||
|
this.conspireId = ability.conspireId;
|
||||||
|
this.addedById = ability.addedById;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -175,19 +195,21 @@ class ConspireTriggeredAbility extends CastSourceTriggeredAbility {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Spell spell = game.getStack().getSpell(event.getSourceId());
|
Spell spell = game.getStack().getSpell(event.getSourceId());
|
||||||
return spell != null && spell
|
return spell != null
|
||||||
|
&& spell
|
||||||
.getSpellAbility()
|
.getSpellAbility()
|
||||||
.getEffects()
|
.getEffects()
|
||||||
.stream()
|
.stream()
|
||||||
.map(effect -> effect.getValue("tappedPermanents"))
|
.map(effect -> effect.getValue("ConspireActivation" + conspireId + addedById))
|
||||||
.filter(Objects::nonNull)
|
.anyMatch(Objects::nonNull);
|
||||||
.map(x -> (List<Permanent>) x)
|
|
||||||
.flatMap(Collection::stream)
|
|
||||||
.count() >= 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "When you pay the conspire costs, copy it and you may choose a new target for the copy.";
|
return "When you pay the conspire costs, copy it and you may choose a new target for the copy.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAddedById(UUID addedById) {
|
||||||
|
this.addedById = addedById;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue