mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
CounterPutEffect: make counterType support , seperator
This commit is contained in:
@@ -45,8 +45,9 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
final StringBuilder stringBuilder = new StringBuilder();
|
final StringBuilder stringBuilder = new StringBuilder();
|
||||||
final Card card = spellAbility.getHostCard();
|
final Card card = spellAbility.getHostCard();
|
||||||
|
|
||||||
final int amount = AbilityUtils.calculateAmount(card, spellAbility.getParamOrDefault("CounterNum", "1"), spellAbility);
|
final int amount = AbilityUtils.calculateAmount(card, spellAbility.getParamOrDefault("CounterNum", "1"),
|
||||||
//skip the StringBuilder if no targets are chosen ("up to" scenario)
|
spellAbility);
|
||||||
|
// skip the StringBuilder if no targets are chosen ("up to" scenario)
|
||||||
if (spellAbility.usesTargeting()) {
|
if (spellAbility.usesTargeting()) {
|
||||||
final List<Card> targetCards = SpellAbilityEffect.getTargetCards(spellAbility);
|
final List<Card> targetCards = SpellAbilityEffect.getTargetCards(spellAbility);
|
||||||
if (targetCards.size() == 0) {
|
if (targetCards.size() == 0) {
|
||||||
@@ -60,7 +61,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
boolean divAsChoose = spellAbility.isDividedAsYouChoose();
|
boolean divAsChoose = spellAbility.isDividedAsYouChoose();
|
||||||
if (divAsChoose) {
|
if (divAsChoose) {
|
||||||
stringBuilder.append("Distribute ");
|
stringBuilder.append("Distribute ");
|
||||||
} else if (spellAbility.hasParam("DividedRandomly")){
|
} else if (spellAbility.hasParam("DividedRandomly")) {
|
||||||
stringBuilder.append("Randomly distribute ");
|
stringBuilder.append("Randomly distribute ");
|
||||||
} else {
|
} else {
|
||||||
stringBuilder.append("Put ");
|
stringBuilder.append("Put ");
|
||||||
@@ -70,37 +71,33 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final String typeName = CounterType.getType(spellAbility.getParam("CounterType")).getName().toLowerCase();
|
final String typeName = CounterType.getType(spellAbility.getParam("CounterType")).getName().toLowerCase();
|
||||||
stringBuilder.append(Lang.nounWithNumeralExceptOne(amount,
|
stringBuilder.append(Lang.nounWithNumeralExceptOne(amount, typeName + " counter"));
|
||||||
typeName + " counter"));
|
stringBuilder.append(divAsChoose || spellAbility.hasParam("DividedRandomly") ? " among " : " on ");
|
||||||
stringBuilder.append(divAsChoose || spellAbility.hasParam("DividedRandomly")
|
|
||||||
? " among " : " on ");
|
|
||||||
|
|
||||||
// special handling for multiple Defined
|
// special handling for multiple Defined
|
||||||
if (spellAbility.hasParam("Defined") && spellAbility.getParam("Defined").contains(" & ")) {
|
if (spellAbility.hasParam("Defined") && spellAbility.getParam("Defined").contains(" & ")) {
|
||||||
String[] def = spellAbility.getParam("Defined").split(" & ");
|
String[] def = spellAbility.getParam("Defined").split(" & ");
|
||||||
for (int i = 0; i < def.length; i++) {
|
for (int i = 0; i < def.length; i++) {
|
||||||
stringBuilder.append(AbilityUtils.getDefinedEntities(card, def[i],
|
stringBuilder.append(AbilityUtils.getDefinedEntities(card, def[i], spellAbility).toString()
|
||||||
spellAbility).toString().replaceAll("[\\[\\]]",""));
|
.replaceAll("[\\[\\]]", ""));
|
||||||
if (i + 1 < def.length) {
|
if (i + 1 < def.length) {
|
||||||
stringBuilder.append(" and ");
|
stringBuilder.append(" and ");
|
||||||
stringBuilder.append(Lang.nounWithNumeralExceptOne(amount,
|
stringBuilder.append(Lang.nounWithNumeralExceptOne(amount, typeName + " counter")).append(" on ");
|
||||||
typeName + " counter")).append(" on ");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if use targeting we show all targets and corresponding counters
|
// if use targeting we show all targets and corresponding counters
|
||||||
} else if (spellAbility.usesTargeting()) {
|
} else if (spellAbility.usesTargeting()) {
|
||||||
final List<Card> targetCards = SpellAbilityEffect.getTargetCards(spellAbility);
|
final List<Card> targetCards = SpellAbilityEffect.getTargetCards(spellAbility);
|
||||||
for(int i = 0; i < targetCards.size(); i++) {
|
for (int i = 0; i < targetCards.size(); i++) {
|
||||||
Card targetCard = targetCards.get(i);
|
Card targetCard = targetCards.get(i);
|
||||||
stringBuilder.append(targetCard);
|
stringBuilder.append(targetCard);
|
||||||
Integer v = spellAbility.getDividedValue(targetCard);
|
Integer v = spellAbility.getDividedValue(targetCard);
|
||||||
if (v != null) // fix null counter stack description
|
if (v != null) // fix null counter stack description
|
||||||
stringBuilder.append(" (").append(v).append(v == 1 ? " counter)" : " counters)");
|
stringBuilder.append(" (").append(v).append(v == 1 ? " counter)" : " counters)");
|
||||||
|
|
||||||
if(i == targetCards.size() - 2) {
|
if (i == targetCards.size() - 2) {
|
||||||
stringBuilder.append(" and ");
|
stringBuilder.append(" and ");
|
||||||
}
|
} else if (i + 1 < targetCards.size()) {
|
||||||
else if(i + 1 < targetCards.size()) {
|
|
||||||
stringBuilder.append(", ");
|
stringBuilder.append(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,7 +121,8 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
return stringBuilder.toString();
|
return stringBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void resolvePerType(SpellAbility sa, final Player placer, CounterType counterType, int counterAmount, GameEntityCounterTable table) {
|
protected void resolvePerType(SpellAbility sa, final Player placer, CounterType counterType, int counterAmount,
|
||||||
|
GameEntityCounterTable table) {
|
||||||
final Card card = sa.getHostCard();
|
final Card card = sa.getHostCard();
|
||||||
final Game game = card.getGame();
|
final Game game = card.getGame();
|
||||||
final Player activator = sa.getActivatingPlayer();
|
final Player activator = sa.getActivatingPlayer();
|
||||||
@@ -139,12 +137,14 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
int divrem = 0;
|
int divrem = 0;
|
||||||
if (sa.hasParam("Bolster")) {
|
if (sa.hasParam("Bolster")) {
|
||||||
CardCollection creatsYouCtrl = activator.getCreaturesInPlay();
|
CardCollection creatsYouCtrl = activator.getCreaturesInPlay();
|
||||||
CardCollection leastToughness = new CardCollection(Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetDefense));
|
CardCollection leastToughness = new CardCollection(
|
||||||
|
Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetDefense));
|
||||||
|
|
||||||
Map<String, Object> params = Maps.newHashMap();
|
Map<String, Object> params = Maps.newHashMap();
|
||||||
params.put("CounterType", counterType);
|
params.put("CounterType", counterType);
|
||||||
|
|
||||||
Iterables.addAll(tgtObjects, activator.getController().chooseCardsForEffect(leastToughness, sa, Localizer.getInstance().getMessage("lblChooseACreatureWithLeastToughness"), 1, 1, false, params));
|
Iterables.addAll(tgtObjects, activator.getController().chooseCardsForEffect(leastToughness, sa,
|
||||||
|
Localizer.getInstance().getMessage("lblChooseACreatureWithLeastToughness"), 1, 1, false, params));
|
||||||
} else if (sa.hasParam("Choices")) {
|
} else if (sa.hasParam("Choices")) {
|
||||||
ZoneType choiceZone = ZoneType.Battlefield;
|
ZoneType choiceZone = ZoneType.Battlefield;
|
||||||
if (sa.hasParam("ChoiceZone")) {
|
if (sa.hasParam("ChoiceZone")) {
|
||||||
@@ -159,17 +159,17 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
chooser = choosers.get(0);
|
chooser = choosers.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = AbilityUtils.calculateAmount(card, sa.getParamOrDefault("ChoiceAmount",
|
int n = AbilityUtils.calculateAmount(card, sa.getParamOrDefault("ChoiceAmount", "1"), sa);
|
||||||
"1"), sa);
|
int m = AbilityUtils.calculateAmount(card,
|
||||||
int m = AbilityUtils.calculateAmount(card, sa.getParamOrDefault("MinChoiceAmount",
|
sa.getParamOrDefault("MinChoiceAmount", sa.getParamOrDefault("ChoiceAmount", "1")), sa);
|
||||||
sa.getParamOrDefault("ChoiceAmount", "1")), sa);
|
|
||||||
|
|
||||||
// no choices allowed
|
// no choices allowed
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CardCollection choices = CardLists.getValidCards(game.getCardsIn(choiceZone), sa.getParam("Choices"), activator, card, sa);
|
CardCollection choices = CardLists.getValidCards(game.getCardsIn(choiceZone), sa.getParam("Choices"),
|
||||||
|
activator, card, sa);
|
||||||
|
|
||||||
String title = Localizer.getInstance().getMessage("lblChooseaCard") + " ";
|
String title = Localizer.getInstance().getMessage("lblChooseaCard") + " ";
|
||||||
if (sa.hasParam("ChoiceTitle")) {
|
if (sa.hasParam("ChoiceTitle")) {
|
||||||
@@ -198,8 +198,8 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("Optional") && !pc.confirmAction
|
if (sa.hasParam("Optional")
|
||||||
(sa, null, Localizer.getInstance().getMessage("lblDoYouWantPutCounter"))) {
|
&& !pc.confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantPutCounter"))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,58 +223,83 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Map<Object, Integer> randomMap = Maps.newHashMap();
|
Map<Object, Integer> randomMap = Maps.newHashMap();
|
||||||
for (int i=0; i<counterRemain; i++) {
|
for (int i = 0; i < counterRemain; i++) {
|
||||||
Card found = Aggregates.random(targets);
|
Card found = Aggregates.random(targets);
|
||||||
found.addCounter(counterType, 1, placer, table);
|
found.addCounter(counterType, 1, placer, table);
|
||||||
if (randomMap.containsKey(found)) {
|
if (randomMap.containsKey(found)) {
|
||||||
int oN = randomMap.get(found);
|
int oN = randomMap.get(found);
|
||||||
int nN = oN+1;
|
int nN = oN + 1;
|
||||||
randomMap.replace(found, oN, nN);
|
randomMap.replace(found, oN, nN);
|
||||||
} else {
|
} else {
|
||||||
randomMap.put(found, 1);
|
randomMap.put(found, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
game.fireEvent(new GameEventRandomLog(logOutput(randomMap, card)));
|
game.fireEvent(new GameEventRandomLog(logOutput(randomMap, card)));
|
||||||
} else for (final GameEntity obj : tgtObjects) {
|
} else {
|
||||||
// check if the object is still in game or if it was moved
|
for (final GameEntity obj : tgtObjects) {
|
||||||
Card gameCard = null;
|
// check if the object is still in game or if it was moved
|
||||||
if (obj instanceof Card) {
|
Card gameCard = null;
|
||||||
Card tgtCard = (Card) obj;
|
if (obj instanceof Card) {
|
||||||
gameCard = game.getCardState(tgtCard, null);
|
Card tgtCard = (Card) obj;
|
||||||
// gameCard is LKI in that case, the card is not in game anymore
|
gameCard = game.getCardState(tgtCard, null);
|
||||||
// or the timestamp did change
|
// gameCard is LKI in that case, the card is not in game anymore
|
||||||
// this should check Self too
|
// or the timestamp did change
|
||||||
if (gameCard == null || !tgtCard.equalsWithTimestamp(gameCard)) {
|
// this should check Self too
|
||||||
continue;
|
if (gameCard == null || !tgtCard.equalsWithTimestamp(gameCard)) {
|
||||||
}
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (existingCounter) {
|
|
||||||
final List<CounterType> choices = Lists.newArrayList();
|
|
||||||
// get types of counters
|
|
||||||
for (CounterType ct : obj.getCounters().keySet()) {
|
|
||||||
if (obj.canReceiveCounters(ct)) {
|
|
||||||
choices.add(ct);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eachExistingCounter) {
|
if (existingCounter) {
|
||||||
for (CounterType ct : choices) {
|
final List<CounterType> choices = Lists.newArrayList();
|
||||||
if (obj instanceof Player) {
|
// get types of counters
|
||||||
((Player) obj).addCounter(ct, counterAmount, placer, table);
|
for (CounterType ct : obj.getCounters().keySet()) {
|
||||||
|
if (obj.canReceiveCounters(ct)) {
|
||||||
|
choices.add(ct);
|
||||||
}
|
}
|
||||||
if (obj instanceof Card) {
|
}
|
||||||
gameCard.addCounter(ct, counterAmount, placer, table);
|
|
||||||
|
if (eachExistingCounter) {
|
||||||
|
for (CounterType ct : choices) {
|
||||||
|
if (obj instanceof Player) {
|
||||||
|
((Player) obj).addCounter(ct, counterAmount, placer, table);
|
||||||
|
}
|
||||||
|
if (obj instanceof Card) {
|
||||||
|
gameCard.addCounter(ct, counterAmount, placer, table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (choices.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
} else if (choices.size() == 1) {
|
||||||
|
counterType = choices.get(0);
|
||||||
|
} else {
|
||||||
|
Map<String, Object> params = Maps.newHashMap();
|
||||||
|
params.put("Target", obj);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(Localizer.getInstance().getMessage("lblSelectCounterTypeAddTo") + " ");
|
||||||
|
sb.append(obj);
|
||||||
|
counterType = pc.chooseCounterType(choices, sa, sb.toString(), params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sa.hasParam("EachFromSource")) {
|
||||||
|
for (Card c : AbilityUtils.getDefinedCards(card, sa.getParam("EachFromSource"), sa)) {
|
||||||
|
for (Entry<CounterType, Integer> cti : c.getCounters().entrySet()) {
|
||||||
|
if (gameCard != null && gameCard.canReceiveCounters(cti.getKey())) {
|
||||||
|
gameCard.addCounter(cti.getKey(), cti.getValue(), placer, table);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (sa.hasParam("CounterTypePerDefined")) {
|
||||||
if (choices.isEmpty()) {
|
List<CounterType> choices = Lists.newArrayList();
|
||||||
continue;
|
for (String s : sa.getParam("CounterType").split(",")) {
|
||||||
} else if (choices.size() == 1) {
|
choices.add(CounterType.getType(s));
|
||||||
counterType = choices.get(0);
|
}
|
||||||
} else {
|
|
||||||
Map<String, Object> params = Maps.newHashMap();
|
Map<String, Object> params = Maps.newHashMap();
|
||||||
params.put("Target", obj);
|
params.put("Target", obj);
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
@@ -282,126 +307,128 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
sb.append(obj);
|
sb.append(obj);
|
||||||
counterType = pc.chooseCounterType(choices, sa, sb.toString(), params);
|
counterType = pc.chooseCounterType(choices, sa, sb.toString(), params);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (sa.hasParam("EachFromSource")) {
|
if (obj instanceof Card) {
|
||||||
for (Card c : AbilityUtils.getDefinedCards(card, sa.getParam("EachFromSource"), sa)) {
|
counterAmount = sa.usesTargeting() && sa.isDividedAsYouChoose() ? sa.getDividedValue(gameCard)
|
||||||
for (Entry<CounterType, Integer> cti : c.getCounters().entrySet()) {
|
: counterAmount;
|
||||||
if (gameCard != null && gameCard.canReceiveCounters(cti.getKey())) {
|
if (!sa.usesTargeting() || gameCard.canBeTargetedBy(sa)) {
|
||||||
gameCard.addCounter(cti.getKey(), cti.getValue(), placer, table);
|
if (max != -1) {
|
||||||
|
counterAmount = Math.max(Math.min(max - gameCard.getCounters(counterType), counterAmount),
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
}
|
if (sa.hasParam("UpTo")) {
|
||||||
}
|
Map<String, Object> params = Maps.newHashMap();
|
||||||
continue;
|
params.put("Target", obj);
|
||||||
}
|
params.put("CounterType", counterType);
|
||||||
|
counterAmount = pc.chooseNumber(sa,
|
||||||
if (obj instanceof Card) {
|
Localizer.getInstance().getMessage("lblHowManyCounters"), 0, counterAmount, params);
|
||||||
counterAmount = sa.usesTargeting() && sa.isDividedAsYouChoose() ? sa.getDividedValue(gameCard) : counterAmount;
|
|
||||||
if (!sa.usesTargeting() || gameCard.canBeTargetedBy(sa)) {
|
|
||||||
if (max != -1) {
|
|
||||||
counterAmount = Math.max(Math.min(max - gameCard.getCounters(counterType), counterAmount), 0);
|
|
||||||
}
|
|
||||||
if (sa.hasParam("UpTo")) {
|
|
||||||
Map<String, Object> params = Maps.newHashMap();
|
|
||||||
params.put("Target", obj);
|
|
||||||
params.put("CounterType", counterType);
|
|
||||||
counterAmount = pc.chooseNumber(sa, Localizer.getInstance().getMessage("lblHowManyCounters"), 0, counterAmount, params);
|
|
||||||
}
|
|
||||||
if (sa.isDividedAsYouChoose() && !sa.usesTargeting()) {
|
|
||||||
Map<String, Object> params = Maps.newHashMap();
|
|
||||||
params.put("Target", obj);
|
|
||||||
params.put("CounterType", counterType);
|
|
||||||
divrem++;
|
|
||||||
if (divrem == tgtObjects.size() || counterRemain == 1) { counterAmount = counterRemain; }
|
|
||||||
else {
|
|
||||||
counterAmount = pc.chooseNumber(sa, Localizer.getInstance().getMessage
|
|
||||||
("lblHowManyCountersThis", CardTranslation.getTranslatedName(gameCard.getName())),
|
|
||||||
1, counterRemain, params);
|
|
||||||
}
|
}
|
||||||
}
|
if (sa.isDividedAsYouChoose() && !sa.usesTargeting()) {
|
||||||
|
Map<String, Object> params = Maps.newHashMap();
|
||||||
// Adapt need extra logic
|
params.put("Target", obj);
|
||||||
if (sa.hasParam("Adapt")) {
|
params.put("CounterType", counterType);
|
||||||
if (!(gameCard.getCounters(CounterEnumType.P1P1) == 0 || StaticAbilityAdapt.anyWithAdapt(sa, gameCard))) {
|
divrem++;
|
||||||
continue;
|
if (divrem == tgtObjects.size() || counterRemain == 1) {
|
||||||
}
|
counterAmount = counterRemain;
|
||||||
}
|
} else {
|
||||||
|
counterAmount = pc.chooseNumber(sa,
|
||||||
if (sa.hasParam("Tribute")) {
|
Localizer.getInstance().getMessage("lblHowManyCountersThis",
|
||||||
// make a copy to check if it would be on the battlefield
|
CardTranslation.getTranslatedName(gameCard.getName())),
|
||||||
Card noTributeLKI = CardUtil.getLKICopy(gameCard);
|
1, counterRemain, params);
|
||||||
// this check needs to check if this card would be on the battlefield
|
}
|
||||||
noTributeLKI.setLastKnownZone(activator.getZone(ZoneType.Battlefield));
|
|
||||||
|
|
||||||
// double freeze tracker, so it doesn't update view
|
|
||||||
game.getTracker().freeze();
|
|
||||||
|
|
||||||
CardCollection preList = new CardCollection(noTributeLKI);
|
|
||||||
game.getAction().checkStaticAbilities(false, Sets.newHashSet(noTributeLKI), preList);
|
|
||||||
|
|
||||||
boolean abort = !noTributeLKI.canReceiveCounters(counterType);
|
|
||||||
|
|
||||||
game.getAction().checkStaticAbilities(false);
|
|
||||||
// clear delayed changes, this check should not have updated the view
|
|
||||||
game.getTracker().clearDelayed();
|
|
||||||
// need to unfreeze tracker
|
|
||||||
game.getTracker().unfreeze();
|
|
||||||
|
|
||||||
// check if it can recive the Tribute
|
|
||||||
if (abort) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Object> params = Maps.newHashMap();
|
// Adapt need extra logic
|
||||||
params.put("CounterType", counterType);
|
if (sa.hasParam("Adapt")) {
|
||||||
params.put("Amount", counterAmount);
|
if (!(gameCard.getCounters(CounterEnumType.P1P1) == 0
|
||||||
params.put("Target", gameCard);
|
|| StaticAbilityAdapt.anyWithAdapt(sa, gameCard))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String message = Localizer.getInstance().getMessage("lblDoYouWantPutTargetP1P1CountersOnCard", String.valueOf(counterAmount), CardTranslation.getTranslatedName(gameCard.getName()));
|
if (sa.hasParam("Tribute")) {
|
||||||
Player chooser = pc.chooseSingleEntityForEffect(activator.getOpponents(), sa, Localizer.getInstance().getMessage("lblChooseAnOpponent"), params);
|
// make a copy to check if it would be on the battlefield
|
||||||
|
Card noTributeLKI = CardUtil.getLKICopy(gameCard);
|
||||||
|
// this check needs to check if this card would be on the battlefield
|
||||||
|
noTributeLKI.setLastKnownZone(activator.getZone(ZoneType.Battlefield));
|
||||||
|
|
||||||
if (chooser.getController().confirmAction(sa, PlayerActionConfirmMode.Tribute, message)) {
|
// double freeze tracker, so it doesn't update view
|
||||||
gameCard.setTributed(true);
|
game.getTracker().freeze();
|
||||||
|
|
||||||
|
CardCollection preList = new CardCollection(noTributeLKI);
|
||||||
|
game.getAction().checkStaticAbilities(false, Sets.newHashSet(noTributeLKI), preList);
|
||||||
|
|
||||||
|
boolean abort = !noTributeLKI.canReceiveCounters(counterType);
|
||||||
|
|
||||||
|
game.getAction().checkStaticAbilities(false);
|
||||||
|
// clear delayed changes, this check should not have updated the view
|
||||||
|
game.getTracker().clearDelayed();
|
||||||
|
// need to unfreeze tracker
|
||||||
|
game.getTracker().unfreeze();
|
||||||
|
|
||||||
|
// check if it can recive the Tribute
|
||||||
|
if (abort) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> params = Maps.newHashMap();
|
||||||
|
params.put("CounterType", counterType);
|
||||||
|
params.put("Amount", counterAmount);
|
||||||
|
params.put("Target", gameCard);
|
||||||
|
|
||||||
|
String message = Localizer.getInstance().getMessage(
|
||||||
|
"lblDoYouWantPutTargetP1P1CountersOnCard", String.valueOf(counterAmount),
|
||||||
|
CardTranslation.getTranslatedName(gameCard.getName()));
|
||||||
|
Player chooser = pc.chooseSingleEntityForEffect(activator.getOpponents(), sa,
|
||||||
|
Localizer.getInstance().getMessage("lblChooseAnOpponent"), params);
|
||||||
|
|
||||||
|
if (chooser.getController().confirmAction(sa, PlayerActionConfirmMode.Tribute, message)) {
|
||||||
|
gameCard.setTributed(true);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (etbcounter) {
|
||||||
|
gameCard.addEtbCounter(counterType, counterAmount, placer);
|
||||||
} else {
|
} else {
|
||||||
continue;
|
gameCard.addCounter(counterType, counterAmount, placer, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sa.hasParam("Evolve")) {
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.Evolved, AbilityKey.mapFromCard(gameCard),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
if (sa.hasParam("Monstrosity")) {
|
||||||
|
gameCard.setMonstrous(true);
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(gameCard);
|
||||||
|
runParams.put(AbilityKey.MonstrosityAmount, counterAmount);
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.BecomeMonstrous, runParams, false);
|
||||||
|
}
|
||||||
|
if (sa.hasParam("Renown")) {
|
||||||
|
gameCard.setRenowned(true);
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.BecomeRenowned,
|
||||||
|
AbilityKey.mapFromCard(gameCard), false);
|
||||||
|
}
|
||||||
|
if (sa.hasParam("Adapt")) {
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.Adapt, AbilityKey.mapFromCard(gameCard),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
if (sa.hasParam("Training")) {
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.Trains, AbilityKey.mapFromCard(gameCard),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
game.updateLastStateForCard(gameCard);
|
||||||
|
if (sa.isDividedAsYouChoose() && !sa.usesTargeting()) {
|
||||||
|
counterRemain = counterRemain - counterAmount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (obj instanceof Player) {
|
||||||
if (etbcounter) {
|
// Add Counters to players!
|
||||||
gameCard.addEtbCounter(counterType, counterAmount, placer);
|
Player pl = (Player) obj;
|
||||||
} else {
|
pl.addCounter(counterType, counterAmount, placer, table);
|
||||||
gameCard.addCounter(counterType, counterAmount, placer, table);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sa.hasParam("Evolve")) {
|
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.Evolved, AbilityKey.mapFromCard(gameCard), false);
|
|
||||||
}
|
|
||||||
if (sa.hasParam("Monstrosity")) {
|
|
||||||
gameCard.setMonstrous(true);
|
|
||||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(gameCard);
|
|
||||||
runParams.put(AbilityKey.MonstrosityAmount, counterAmount);
|
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.BecomeMonstrous, runParams, false);
|
|
||||||
}
|
|
||||||
if (sa.hasParam("Renown")) {
|
|
||||||
gameCard.setRenowned(true);
|
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.BecomeRenowned, AbilityKey.mapFromCard(gameCard), false);
|
|
||||||
}
|
|
||||||
if (sa.hasParam("Adapt")) {
|
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.Adapt, AbilityKey.mapFromCard(gameCard), false);
|
|
||||||
}
|
|
||||||
if (sa.hasParam("Training")) {
|
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.Trains, AbilityKey.mapFromCard(gameCard), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
game.updateLastStateForCard(gameCard);
|
|
||||||
if (sa.isDividedAsYouChoose() && !sa.usesTargeting()) {
|
|
||||||
counterRemain = counterRemain - counterAmount;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (obj instanceof Player) {
|
|
||||||
// Add Counters to players!
|
|
||||||
Player pl = (Player) obj;
|
|
||||||
pl.addCounter(counterType, counterAmount, placer, table);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -427,23 +454,33 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
if (sa.hasParam("TriggeredCounterMap")) {
|
if (sa.hasParam("TriggeredCounterMap")) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Map<CounterType, Integer> counterMap = (Map<CounterType, Integer>) sa.getTriggeringObject(AbilityKey.CounterMap);
|
Map<CounterType, Integer> counterMap = (Map<CounterType, Integer>) sa
|
||||||
|
.getTriggeringObject(AbilityKey.CounterMap);
|
||||||
for (Map.Entry<CounterType, Integer> e : counterMap.entrySet()) {
|
for (Map.Entry<CounterType, Integer> e : counterMap.entrySet()) {
|
||||||
resolvePerType(sa, placer, e.getKey(), e.getValue(), table);
|
resolvePerType(sa, placer, e.getKey(), e.getValue(), table);
|
||||||
}
|
}
|
||||||
} else if (sa.hasParam("SharedKeywords")) {
|
} else if (sa.hasParam("SharedKeywords")) {
|
||||||
List<String> keywords = Arrays.asList(sa.getParam("SharedKeywords").split(" & "));
|
List<String> keywords = Arrays.asList(sa.getParam("SharedKeywords").split(" & "));
|
||||||
List<ZoneType> zones = ZoneType.listValueOf(sa.getParam("SharedKeywordsZone"));
|
List<ZoneType> zones = ZoneType.listValueOf(sa.getParam("SharedKeywordsZone"));
|
||||||
String[] restrictions = sa.hasParam("SharedRestrictions") ? sa.getParam("SharedRestrictions").split(",") : new String[]{"Card"};
|
String[] restrictions = sa.hasParam("SharedRestrictions") ? sa.getParam("SharedRestrictions").split(",")
|
||||||
|
: new String[] { "Card" };
|
||||||
keywords = CardFactoryUtil.sharedKeywords(keywords, restrictions, zones, card, sa);
|
keywords = CardFactoryUtil.sharedKeywords(keywords, restrictions, zones, card, sa);
|
||||||
for (String k : keywords) {
|
for (String k : keywords) {
|
||||||
resolvePerType(sa, placer, CounterType.getType(k), counterAmount, table);
|
resolvePerType(sa, placer, CounterType.getType(k), counterAmount, table);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CounterType counterType = null;
|
CounterType counterType = null;
|
||||||
if (!sa.hasParam("EachExistingCounter") && !sa.hasParam("EachFromSource")) {
|
if (!sa.hasParam("EachExistingCounter") && !sa.hasParam("EachFromSource")
|
||||||
|
&& !sa.hasParam("CounterTypePerDefined")) {
|
||||||
try {
|
try {
|
||||||
counterType = CounterType.getType(sa.getParam("CounterType"));
|
List<CounterType> choices = Lists.newArrayList();
|
||||||
|
for (String s : sa.getParam("CounterType").split(",")) {
|
||||||
|
choices.add(CounterType.getType(s));
|
||||||
|
}
|
||||||
|
Map<String, Object> params = Maps.newHashMap();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(Localizer.getInstance().getMessage("lblSelectCounterTypeAddTo"));
|
||||||
|
counterType = placer.getController().chooseCounterType(choices, sa, sb.toString(), params);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("Counter type doesn't match, nor does an SVar exist with the type name.");
|
System.out.println("Counter type doesn't match, nor does an SVar exist with the type name.");
|
||||||
return;
|
return;
|
||||||
@@ -473,19 +510,24 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addRemovePhaseTrigger(final Card host, final SpellAbility sa, String phase, GameEntity tgt, CounterType ct, int added) {
|
protected void addRemovePhaseTrigger(final Card host, final SpellAbility sa, String phase, GameEntity tgt,
|
||||||
|
CounterType ct, int added) {
|
||||||
boolean intrinsic = sa.isIntrinsic();
|
boolean intrinsic = sa.isIntrinsic();
|
||||||
|
|
||||||
StringBuilder delTrig = new StringBuilder("Mode$ Phase | Phase$ ");
|
StringBuilder delTrig = new StringBuilder("Mode$ Phase | Phase$ ");
|
||||||
delTrig.append(phase);
|
delTrig.append(phase);
|
||||||
delTrig.append(" | TriggerDescription$ For each ").append(ct.getName()).append(" counter you put on a creature this way, remove a ").append(ct.getName()).append(" counter from that creature at the beginning of the next");
|
delTrig.append(" | TriggerDescription$ For each ").append(ct.getName())
|
||||||
|
.append(" counter you put on a creature this way, remove a ").append(ct.getName())
|
||||||
|
.append(" counter from that creature at the beginning of the next");
|
||||||
if ("Cleanup".equals(phase)) {
|
if ("Cleanup".equals(phase)) {
|
||||||
delTrig.append("cleanup step");
|
delTrig.append("cleanup step");
|
||||||
} else if ("End of Turn".equals(phase)) {
|
} else if ("End of Turn".equals(phase)) {
|
||||||
delTrig.append("next end step");
|
delTrig.append("next end step");
|
||||||
}
|
}
|
||||||
|
|
||||||
String trigSA = new StringBuilder("DB$ RemoveCounter | Defined$ DelayTriggerRemembered | CounterNum$ 1 | CounterType$ ").append(ct).toString();
|
String trigSA = new StringBuilder(
|
||||||
|
"DB$ RemoveCounter | Defined$ DelayTriggerRemembered | CounterNum$ 1 | CounterType$ ").append(ct)
|
||||||
|
.toString();
|
||||||
|
|
||||||
// these trigger are one per counter
|
// these trigger are one per counter
|
||||||
for (int i = 0; i < added; i++) {
|
for (int i = 0; i < added; i++) {
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
Name:Dismantle
|
Name:Dismantle
|
||||||
ManaCost:2 R
|
ManaCost:2 R
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Destroy | Cost$ 2 R | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SubAbility$ DBChoice | SpellDescription$ Destroy target artifact. If that artifact had counters on it, put that many +1/+1 counters or charge counters on an artifact you control.
|
A:SP$ Destroy | Cost$ 2 R | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SubAbility$ DBPutCounter | SpellDescription$ Destroy target artifact. If that artifact had counters on it, put that many +1/+1 counters or charge counters on an artifact you control.
|
||||||
SVar:DBChoice:DB$ GenericChoice | Choices$ DBPutP1P1,DBPutCharge | ConditionDefined$ Targeted | ConditionPresent$ Card.HasCounters | ConditionCompare$ GE1 | StackDescription$ put that many +1/+1 counters or charge counters on an artifact you control.
|
SVar:DBPutCounter:DB$ PutCounter | Choices$ Artifact.YouCtrl | CounterType$ P1P1,CHARGE | CounterNum$ X | CounterTypePerDefined$ True | ConditionDefined$ Targeted | ConditionPresent$ Card.HasCounters | ConditionCompare$ GE1 | StackDescription$ put that many +1/+1 counters or charge counters on an artifact you control.
|
||||||
SVar:DBPutP1P1:DB$ PutCounter | Choices$ Artifact.YouCtrl | CounterType$ P1P1 | CounterNum$ X | SpellDescription$ +1/+1
|
|
||||||
SVar:DBPutCharge:DB$ PutCounter | Choices$ Artifact.YouCtrl | CounterType$ CHARGE | CounterNum$ X | SpellDescription$ Charge
|
|
||||||
SVar:X:TargetedLKI$CardCounters.ALL
|
SVar:X:TargetedLKI$CardCounters.ALL
|
||||||
Oracle:Destroy target artifact. If that artifact had counters on it, put that many +1/+1 counters or charge counters on an artifact you control.
|
Oracle:Destroy target artifact. If that artifact had counters on it, put that many +1/+1 counters or charge counters on an artifact you control.
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
Name:Invoke the Ancients
|
Name:Invoke the Ancients
|
||||||
ManaCost:1 G G G G
|
ManaCost:1 G G G G
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Token | TokenAmount$ 2 | TokenScript$ g_4_5_spirit | RememberTokens$ True | SubAbility$ DBRepeatEach | SpellDescription$ Create two 4/5 green Spirit creature tokens.
|
A:SP$ Token | TokenAmount$ 2 | TokenScript$ g_4_5_spirit | RememberTokens$ True | SubAbility$ DBCounter | SpellDescription$ Create two 4/5 green Spirit creature tokens.
|
||||||
SVar:DBRepeatEach:DB$ RepeatEach | UseImprinted$ True | RepeatCards$ Card.IsRemembered | RepeatSubAbility$ CounterChoice | SubAbility$ DBCleanup | SpellDescription$ For each of them, put your choice of a vigilance counter, a reach counter, or a trample counter on it.
|
SVar:DBCounter:DB$ PutCounter | Defined$ Remembered | CounterType$ Vigilance,Reach,Trample | CounterNum$ 1 | CounterTypePerDefined$ True | SubAbility$ DBCleanup | SpellDescription$ For each of them, put your choice of a vigilance counter, a reach counter, or a trample counter on it.
|
||||||
SVar:CounterChoice:DB$ GenericChoice | Defined$ You | Choices$ Vigilance,Reach,Trample
|
|
||||||
SVar:Vigilance:DB$ PutCounter | Defined$ Imprinted | CounterType$ Vigilance | CounterNum$ 1 | SpellDescription$ Vigilance
|
|
||||||
SVar:Reach:DB$ PutCounter | Defined$ Imprinted | CounterType$ Reach | CounterNum$ 1 | SpellDescription$ Reach
|
|
||||||
SVar:Trample:DB$ PutCounter | Defined$ Imprinted | CounterType$ Trample | CounterNum$ 1 | SpellDescription$ Trample
|
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
DeckHas:Ability$Token|Counters & Type$Spirit & Keyword$Vigilance|Reach|Trample
|
DeckHas:Ability$Token|Counters & Type$Spirit & Keyword$Vigilance|Reach|Trample
|
||||||
Oracle:Create two 4/5 green Spirit creature tokens. For each of them, put your choice of a vigilance counter, a reach counter, or a trample counter on it.
|
Oracle:Create two 4/5 green Spirit creature tokens. For each of them, put your choice of a vigilance counter, a reach counter, or a trample counter on it.
|
||||||
|
|||||||
@@ -5,11 +5,8 @@ Loyalty:3
|
|||||||
S:Mode$ Continuous | Affected$ Card.TopLibrary+YouCtrl | AffectedZone$ Library | MayLookAt$ You | Description$ You may look at the top card of your library any time.
|
S:Mode$ Continuous | Affected$ Card.TopLibrary+YouCtrl | AffectedZone$ Library | MayLookAt$ You | Description$ You may look at the top card of your library any time.
|
||||||
S:Mode$ Continuous | Affected$ Creature.TopLibrary+YouCtrl | MayPlay$ True | AffectedZone$ Library | Description$ You may cast creature spells from the top of your library.
|
S:Mode$ Continuous | Affected$ Creature.TopLibrary+YouCtrl | MayPlay$ True | AffectedZone$ Library | Description$ You may cast creature spells from the top of your library.
|
||||||
SVar:NonStackingEffect:True
|
SVar:NonStackingEffect:True
|
||||||
A:AB$ Token | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | TokenAmount$ 1 | TokenScript$ g_3_3_beast | TokenOwner$ You | LegacyImage$ g 3 3 beast iko | RememberTokens$ True | SubAbility$ DBGenericChoice | SpellDescription$ Create a 3/3 green Beast creature token. Put your choice of a vigilance counter, a reach counter, or a trample counter on it.
|
A:AB$ Token | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | TokenAmount$ 1 | TokenScript$ g_3_3_beast | TokenOwner$ You | RememberTokens$ True | SubAbility$ DBCounter | SpellDescription$ Create a 3/3 green Beast creature token. Put your choice of a vigilance counter, a reach counter, or a trample counter on it.
|
||||||
SVar:DBGenericChoice:DB$ GenericChoice | Defined$ You | Choices$ Vigilance,Reach,Trample | AILogic$ Always
|
SVar:DBCounter:DB$ PutCounter | Defined$ Remembered | CounterType$ Vigilance,Reach,Trample | CounterNum$ 1 | SubAbility$ DBCleanup
|
||||||
SVar:Reach:DB$ PutCounter | Defined$ Remembered | CounterType$ Reach | CounterNum$ 1 | SubAbility$ DBCleanup | SpellDescription$ Reach
|
|
||||||
SVar:Trample:DB$ PutCounter | Defined$ Remembered | CounterType$ Trample | CounterNum$ 1 | SubAbility$ DBCleanup | SpellDescription$ Trample
|
|
||||||
SVar:Vigilance:DB$ PutCounter | Defined$ Remembered | CounterType$ Vigilance | CounterNum$ 1 | SubAbility$ DBCleanup | SpellDescription$ Vigilance
|
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
A:AB$ Effect | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | Ultimate$ True | Triggers$ TrigSearch | AILogic$ WillCastCreature | SpellDescription$ When you cast your next creature spell this turn, search your library for a creature card with lesser mana value, put it onto the battlefield, then shuffle.
|
A:AB$ Effect | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | Ultimate$ True | Triggers$ TrigSearch | AILogic$ WillCastCreature | SpellDescription$ When you cast your next creature spell this turn, search your library for a creature card with lesser mana value, put it onto the battlefield, then shuffle.
|
||||||
SVar:TrigSearch:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | OneOff$ True | TriggerZones$ Command | Execute$ DBSearch | TriggerDescription$ When you cast your next creature spell this turn, search your library for a creature card with lesser mana value, put it onto the battlefield, then shuffle.
|
SVar:TrigSearch:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | OneOff$ True | TriggerZones$ Command | Execute$ DBSearch | TriggerDescription$ When you cast your next creature spell this turn, search your library for a creature card with lesser mana value, put it onto the battlefield, then shuffle.
|
||||||
|
|||||||
Reference in New Issue
Block a user