forked from External/mage
* Kicker - added support of X and mana cost interactions like Rosheen Meanderer + Verdeloth the Ancient combo (#3538);
* Rosheen Meanderer - fixed that mana can be payed for mana cost with X instead any cost with X (#3538);
This commit is contained in:
parent
49fc094546
commit
cc54a92daa
7 changed files with 216 additions and 147 deletions
|
|
@ -1,22 +1,17 @@
|
|||
|
||||
package mage.cards.k;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.KickedCondition;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.dynamicvalue.common.GetKickerXValue;
|
||||
import mage.abilities.effects.common.continuous.BoostAllEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.KickerAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
|
|
@ -24,10 +19,10 @@ import mage.counters.CounterType;
|
|||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
import mage.filter.predicate.permanent.AnotherPredicate;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author emerald000
|
||||
*/
|
||||
public final class KangeeAerieKeeper extends CardImpl {
|
||||
|
|
@ -55,7 +50,7 @@ public final class KangeeAerieKeeper extends CardImpl {
|
|||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// When Kangee, Aerie Keeper enters the battlefield, if it was kicked, put X feather counters on it.
|
||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.FEATHER.createInstance(), new KangeeAerieKeeperGetKickerXValue(), true));
|
||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.FEATHER.createInstance(), GetKickerXValue.instance, true));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, KickedCondition.instance, "When {this} enters the battlefield, if it was kicked, put X feather counters on it."));
|
||||
|
||||
// Other Bird creatures get +1/+1 for each feather counter on Kangee, Aerie Keeper.
|
||||
|
|
@ -71,38 +66,3 @@ public final class KangeeAerieKeeper extends CardImpl {
|
|||
return new KangeeAerieKeeper(this);
|
||||
}
|
||||
}
|
||||
|
||||
class KangeeAerieKeeperGetKickerXValue implements DynamicValue {
|
||||
|
||||
public KangeeAerieKeeperGetKickerXValue() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability source, Effect effect) {
|
||||
int count = 0;
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (card != null) {
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
if (ability instanceof KickerAbility) {
|
||||
count += ((KickerAbility) ability).getXManaValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KangeeAerieKeeperGetKickerXValue copy() {
|
||||
return new KangeeAerieKeeperGetKickerXValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "X";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
|
||||
package mage.cards.r;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.ConditionalMana;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
|
|
@ -12,20 +9,20 @@ import mage.abilities.effects.mana.BasicManaEffect;
|
|||
import mage.abilities.mana.BasicManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class RosheenMeanderer extends CardImpl {
|
||||
|
||||
public RosheenMeanderer(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R/G}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R/G}");
|
||||
addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.GIANT);
|
||||
this.subtype.add(SubType.SHAMAN);
|
||||
|
|
@ -75,15 +72,16 @@ class RosheenMeandererConditionalMana extends ConditionalMana {
|
|||
|
||||
class RosheenMeandererManaCondition implements Condition {
|
||||
|
||||
/*
|
||||
A “cost that contains {X}” may be a spell’s total cost, an activated ability’s cost, a suspend cost, or a cost you’re
|
||||
asked to pay as part of the resolution of a spell or ability (such as Condescend). A spell’s total cost includes either
|
||||
its mana cost (printed in the upper right corner) or its alternative cost (such as flashback), as well as any additional
|
||||
costs (such as kicker). If it’s something you can spend mana on, it’s a cost. If that cost includes the {X} symbol in it,
|
||||
you can spend mana generated by Rosheen on that cost. (2017-11-17)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
if (AbilityType.SPELL == source.getAbilityType()) {
|
||||
MageObject object = game.getObject(source.getSourceId());
|
||||
return object != null
|
||||
&& object.getManaCost().getText().contains("X");
|
||||
|
||||
} else {
|
||||
return source.getManaCosts().getText().contains("X");
|
||||
}
|
||||
return source.getManaCostsToPay().containsX();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,14 @@
|
|||
|
||||
package mage.cards.v;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.KickedCondition;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.dynamicvalue.common.GetKickerXValue;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostAllEffect;
|
||||
import mage.abilities.keyword.KickerAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
|
|
@ -21,17 +16,17 @@ import mage.filter.common.FilterCreaturePermanent;
|
|||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
import mage.filter.predicate.permanent.PermanentIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.token.SaprolingToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class VerdelothTheAncient extends CardImpl {
|
||||
|
||||
public VerdelothTheAncient(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}");
|
||||
addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.TREEFOLK);
|
||||
|
||||
|
|
@ -40,22 +35,22 @@ public final class VerdelothTheAncient extends CardImpl {
|
|||
|
||||
// Kicker {X}
|
||||
this.addAbility(new KickerAbility("{X}"));
|
||||
|
||||
|
||||
// Saproling creatures and other Treefolk creatures get +1/+1.
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("Saproling creatures and other Treefolk creatures");
|
||||
filter.add(Predicates.or(
|
||||
Predicates.and(new SubtypePredicate(SubType.TREEFOLK), Predicates.not(new PermanentIdPredicate(this.getId()))),
|
||||
new SubtypePredicate(SubType.SAPROLING))
|
||||
);
|
||||
);
|
||||
filter.add(Predicates.not(new PermanentIdPredicate(this.getId())));
|
||||
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1,1, Duration.WhileOnBattlefield, filter, false)));
|
||||
|
||||
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, false)));
|
||||
|
||||
// When Verdeloth the Ancient enters the battlefield, if it was kicked, create X 1/1 green Saproling creature tokens.
|
||||
EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new SaprolingToken(), new GetKickerXValue()), false);
|
||||
EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new SaprolingToken(), GetKickerXValue.instance), false);
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, KickedCondition.instance,
|
||||
"When {this} enters the battlefield, if it was kicked, create X 1/1 green Saproling creature tokens."));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public VerdelothTheAncient(final VerdelothTheAncient card) {
|
||||
|
|
@ -66,39 +61,4 @@ public final class VerdelothTheAncient extends CardImpl {
|
|||
public VerdelothTheAncient copy() {
|
||||
return new VerdelothTheAncient(this);
|
||||
}
|
||||
}
|
||||
|
||||
class GetKickerXValue implements DynamicValue {
|
||||
|
||||
public GetKickerXValue() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability source, Effect effect) {
|
||||
int count = 0;
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (card != null) {
|
||||
for (Ability ability: card.getAbilities()) {
|
||||
if (ability instanceof KickerAbility) {
|
||||
count += ((KickerAbility) ability).getXManaValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetKickerXValue copy() {
|
||||
return new GetKickerXValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "X";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
package org.mage.test.cards.mana;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class RosheenMeandererManaXTest extends CardTestPlayerBase {
|
||||
|
||||
// https://github.com/magefree/mage/issues/3538
|
||||
|
||||
// Rosheen Meanderer {3}{R/G}
|
||||
// {T}: Add {C}{C}{C}{C}. Spend this mana only on costs that contain {X}.
|
||||
|
||||
// Verdeloth the Ancient {4}{G}{G}
|
||||
// Kicker {X} (You may pay an additional {X} as you cast this spell.)
|
||||
// Saproling creatures and other Treefolk creatures get +1/+1.
|
||||
// When Verdeloth the Ancient enters the battlefield, if it was kicked, create X 1/1 green Saproling creature tokens.
|
||||
|
||||
@Test
|
||||
public void test_SimpleKicker() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 6 + 2);
|
||||
addCard(Zone.HAND, playerA, "Verdeloth the Ancient");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Verdeloth the Ancient");
|
||||
setChoice(playerA, "Yes"); // use kicker
|
||||
setChoice(playerA, "X=2");
|
||||
|
||||
checkPermanentCount("after", 1, PhaseStep.END_TURN, playerA, "Verdeloth the Ancient", 1);
|
||||
checkPermanentCount("after", 1, PhaseStep.END_TURN, playerA, "Saproling", 2);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
setStrictChooseMode(true);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_KickerWithXMana() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 6 + 2 - 4);
|
||||
addCard(Zone.HAND, playerA, "Verdeloth the Ancient");
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Rosheen Meanderer");
|
||||
|
||||
// make 4 mana for X pay
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {C}");
|
||||
checkManaPool("mana", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "C", 4);
|
||||
|
||||
// cast kicker X and use extra 4 mana
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Verdeloth the Ancient");
|
||||
setChoice(playerA, "Yes"); // use kicker
|
||||
setChoice(playerA, "X=2");
|
||||
|
||||
checkPermanentCount("after", 1, PhaseStep.END_TURN, playerA, "Verdeloth the Ancient", 1);
|
||||
checkPermanentCount("after", 1, PhaseStep.END_TURN, playerA, "Saproling", 2);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
setStrictChooseMode(true);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_KickerWithXZero() {
|
||||
|
||||
// You can spend mana generated by Rosheen on a cost that includes {X} even if you’ve chosen an X of 0,
|
||||
// or if the card specifies that you can spend only colored mana on X. (You’ll have to spend Rosheen’s mana on
|
||||
// a different part of that cost, of course.) (2017-11-17)
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 6 - 4);
|
||||
addCard(Zone.HAND, playerA, "Verdeloth the Ancient");
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Rosheen Meanderer");
|
||||
|
||||
// make 4 mana for X pay
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {C}");
|
||||
checkManaPool("mana", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "C", 4);
|
||||
|
||||
// cast kicker X and use extra 4 mana
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Verdeloth the Ancient");
|
||||
setChoice(playerA, "Yes"); // use kicker
|
||||
setChoice(playerA, "X=0");
|
||||
|
||||
checkPermanentCount("after", 1, PhaseStep.END_TURN, playerA, "Verdeloth the Ancient", 1);
|
||||
checkPermanentCount("after", 1, PhaseStep.END_TURN, playerA, "Saproling", 0);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
setStrictChooseMode(true);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1129,7 +1129,9 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
private void assertManaPoolInner(PlayerAction action, Player player, ManaType manaType, Integer amount) {
|
||||
Integer current = player.getManaPool().get(manaType);
|
||||
Integer normal = player.getManaPool().getMana().get(manaType);
|
||||
Integer conditional = player.getManaPool().getConditionalMana().stream().mapToInt(a -> a.get(manaType)).sum(); // calcs FULL conditional mana, not real conditions
|
||||
Integer current = normal + conditional;
|
||||
Assert.assertEquals(action.getActionName() + " - mana pool must contain [" + amount.toString() + " " + manaType.toString() + "], but found [" + current.toString() + "]", amount, current);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
package mage.abilities.dynamicvalue.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.OptionalAdditionalCost;
|
||||
import mage.abilities.costs.OptionalAdditionalCostImpl;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.keyword.KickerAbility;
|
||||
import mage.game.Game;
|
||||
import mage.game.stack.Spell;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public enum GetKickerXValue implements DynamicValue {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability source, Effect effect) {
|
||||
// calcs only kicker with X values
|
||||
|
||||
// kicker adds additional costs to spell ability
|
||||
// only one X value per card possible
|
||||
// kicker can be calls multiple times (use getKickedCounter)
|
||||
|
||||
int finalValue = 0;
|
||||
Spell spell = game.getSpellOrLKIStack(source.getSourceId());
|
||||
if (spell != null && spell.getSpellAbility() != null) {
|
||||
int xValue = spell.getSpellAbility().getManaCostsToPay().getX();
|
||||
for (Ability ability : spell.getAbilities()) {
|
||||
if (ability instanceof KickerAbility) {
|
||||
|
||||
// search that kicker used X value
|
||||
KickerAbility kickerAbility = (KickerAbility) ability;
|
||||
boolean haveVarCost = false;
|
||||
for (OptionalAdditionalCost cost : kickerAbility.getKickerCosts()) {
|
||||
List<VariableCost> varCosts = ((OptionalAdditionalCostImpl) cost).getVariableCosts();
|
||||
if (!varCosts.isEmpty()) {
|
||||
haveVarCost = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (haveVarCost) {
|
||||
int kickedCount = ((KickerAbility) ability).getKickedCounter(game, source);
|
||||
if (kickedCount > 0) {
|
||||
finalValue += kickedCount * xValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return finalValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetKickerXValue copy() {
|
||||
return GetKickerXValue.instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,10 @@
|
|||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.costs.*;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
|
|
@ -17,6 +12,12 @@ import mage.game.Game;
|
|||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 20121001 702.31. Kicker 702.31a Kicker is a static ability that functions
|
||||
* while the spell with kicker is on the stack. "Kicker [cost]" means "You may
|
||||
|
|
@ -57,7 +58,6 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
protected String keywordText;
|
||||
protected String reminderText;
|
||||
protected List<OptionalAdditionalCost> kickerCosts = new LinkedList<>();
|
||||
private int xManaValue = 0;
|
||||
|
||||
public KickerAbility(String manaString) {
|
||||
this(KICKER_KEYWORD, KICKER_REMINDER_MANA);
|
||||
|
|
@ -79,10 +79,11 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
|
||||
public KickerAbility(final KickerAbility ability) {
|
||||
super(ability);
|
||||
this.kickerCosts.addAll(ability.kickerCosts);
|
||||
for (OptionalAdditionalCost cost : ability.kickerCosts) {
|
||||
this.kickerCosts.add((OptionalAdditionalCost) cost.copy());
|
||||
}
|
||||
this.keywordText = ability.keywordText;
|
||||
this.reminderText = ability.reminderText;
|
||||
this.xManaValue = ability.xManaValue;
|
||||
this.activations.putAll(ability.activations);
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +109,7 @@ 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) {
|
||||
activations.put(key, 0);
|
||||
|
|
@ -116,10 +117,6 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
}
|
||||
}
|
||||
|
||||
public int getXManaValue() {
|
||||
return xManaValue;
|
||||
}
|
||||
|
||||
public int getKickedCounter(Game game, Ability source) {
|
||||
String key = getActivationKey(source, "", game);
|
||||
return activations.getOrDefault(key, 0);
|
||||
|
|
@ -167,7 +164,7 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
if (zcc > 0 && (source.getAbilityType() == AbilityType.TRIGGERED)) {
|
||||
--zcc;
|
||||
}
|
||||
return String.valueOf(zcc) + ((kickerCosts.size() > 1) ? costText : "");
|
||||
return zcc + ((kickerCosts.size() > 1) ? costText : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -182,16 +179,16 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
String times = "";
|
||||
if (kickerCost.isRepeatable()) {
|
||||
int activatedCount = getKickedCounter(game, ability);
|
||||
times = Integer.toString(activatedCount + 1) + (activatedCount == 0 ? " time " : " times ");
|
||||
times = (activatedCount + 1) + (activatedCount == 0 ? " time " : " times ");
|
||||
}
|
||||
if (kickerCost.canPay(ability, sourceId, controllerId, game)
|
||||
&& player.chooseUse(Outcome.Benefit, "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();) {
|
||||
for (@SuppressWarnings("unchecked") Iterator<Cost> itDetails = ((Costs) kickerCostObject).iterator(); itDetails.hasNext(); ) {
|
||||
addKickerCostsToAbility(itDetails.next(), ability, game);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -199,7 +196,7 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
}
|
||||
}
|
||||
} else {
|
||||
addKickerCostsToAbility((Cost) kickerCost, ability, game);
|
||||
addKickerCostsToAbility(kickerCost, ability, game);
|
||||
}
|
||||
again = kickerCost.isRepeatable();
|
||||
} else {
|
||||
|
|
@ -212,26 +209,9 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
|
|||
}
|
||||
|
||||
private void addKickerCostsToAbility(Cost cost, Ability ability, Game game) {
|
||||
// can contains multiple costs from multikicker ability
|
||||
if (cost instanceof ManaCostsImpl) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<VariableManaCost> varCosts = ((ManaCostsImpl) cost).getVariableCosts();
|
||||
if (!varCosts.isEmpty()) {
|
||||
// use only first variable cost
|
||||
xManaValue = game.getPlayer(this.controllerId).announceXMana(varCosts.get(0).getMinX(), Integer.MAX_VALUE, "Announce kicker value for " + varCosts.get(0).getText(), game, this);
|
||||
// kicker variable X costs handled internally as multikicker with {1} cost (no multikicker on card)
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers(game.getPlayer(this.controllerId).getLogName() + " announced a value of " + xManaValue + " for " + " kicker X ");
|
||||
}
|
||||
ability.getManaCostsToPay().add(new GenericManaCost(xManaValue));
|
||||
ManaCostsImpl<ManaCost> kickerManaCosts = (ManaCostsImpl) cost;
|
||||
for (ManaCost manaCost : kickerManaCosts) {
|
||||
if (!(manaCost instanceof VariableManaCost)) {
|
||||
ability.getManaCostsToPay().add(manaCost.copy());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy());
|
||||
}
|
||||
ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy());
|
||||
} else {
|
||||
ability.getCosts().add(cost.copy());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue