War: Proliferate: rework effect now put each counter type on it

This commit is contained in:
Hans Mackowiak
2019-04-10 10:23:00 +00:00
committed by swordshine
parent 5c95216d9d
commit 2617795e37
23 changed files with 116 additions and 259 deletions

View File

@@ -18,12 +18,10 @@
package forge.ai; package forge.ai;
import com.esotericsoftware.minlog.Log; import com.esotericsoftware.minlog.Log;
import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import forge.ai.ability.ChangeZoneAi; import forge.ai.ability.ChangeZoneAi;
import forge.ai.ability.ExploreAi; import forge.ai.ability.ExploreAi;
import forge.ai.simulation.SpellAbilityPicker; import forge.ai.simulation.SpellAbilityPicker;
@@ -1784,75 +1782,6 @@ public class AiController {
throw new UnsupportedOperationException("AI is not supposed to reach this code at the moment"); throw new UnsupportedOperationException("AI is not supposed to reach this code at the moment");
} }
public Map<GameEntity, CounterType> chooseProliferation(final SpellAbility sa) {
final Map<GameEntity, CounterType> result = Maps.newHashMap();
final List<Player> allies = player.getAllies();
allies.add(player);
final List<Player> enemies = player.getOpponents();
final Function<Card, CounterType> predProliferate = new Function<Card, CounterType>() {
@Override
public CounterType apply(Card crd) {
//fast way out, no need to check other stuff
if (!crd.hasCounters()) {
return null;
}
// cards controlled by ai or ally with Vanishing or Fading
// and exaclty one counter of the specifice type gets high priority to keep the card
if (allies.contains(crd.getController())) {
// except if its a Chronozoa, because it WANTS to be removed to make more
if (crd.hasKeyword(Keyword.VANISHING) && !"Chronozoa".equals(crd.getName())) {
if (crd.getCounters(CounterType.TIME) == 1) {
return CounterType.TIME;
}
} else if (crd.hasKeyword(Keyword.FADING)) {
if (crd.getCounters(CounterType.FADE) == 1) {
return CounterType.FADE;
}
}
}
for (final Entry<CounterType, Integer> c1 : crd.getCounters().entrySet()) {
// if card can not recive the given counter, try another one
if (!crd.canReceiveCounters(c1.getKey())) {
continue;
}
if (ComputerUtil.isNegativeCounter(c1.getKey(), crd) && enemies.contains(crd.getController())) {
return c1.getKey();
}
if (!ComputerUtil.isNegativeCounter(c1.getKey(), crd) && allies.contains(crd.getController())) {
return c1.getKey();
}
}
return null;
}
};
for (Card c : game.getCardsIn(ZoneType.Battlefield)) {
CounterType ct = predProliferate.apply(c);
if (ct != null)
result.put(c, ct);
}
for (Player e : enemies) {
// TODO In the future check of enemies can get poison counters and give them some other bad counter type
if (e.getCounters(CounterType.POISON) > 0) {
result.put(e, CounterType.POISON);
}
}
for (Player pl : allies) {
if (pl.getCounters(CounterType.EXPERIENCE) > 0) {
result.put(pl, CounterType.EXPERIENCE);
} else if (pl.getCounters(CounterType.ENERGY) > 0) {
result.put(pl, CounterType.ENERGY);
}
}
return result;
}
public CardCollection chooseCardsForEffect(CardCollectionView pool, SpellAbility sa, int min, int max, boolean isOptional) { public CardCollection chooseCardsForEffect(CardCollectionView pool, SpellAbility sa, int min, int max, boolean isOptional) {
if (sa == null || sa.getApi() == null) { if (sa == null || sa.getApi() == null) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();

View File

@@ -953,11 +953,6 @@ public class PlayerControllerAi extends PlayerController {
return true; return true;
} }
@Override
public Map<GameEntity, CounterType> chooseProliferation(SpellAbility sa) {
return brains.chooseProliferation(sa);
}
@Override @Override
public boolean chooseTargetsFor(SpellAbility currentAbility) { public boolean chooseTargetsFor(SpellAbility currentAbility) {
return brains.doTrigger(currentAbility, true); return brains.doTrigger(currentAbility, true);

View File

@@ -1,15 +1,20 @@
package forge.ai.ability; package forge.ai.ability;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import forge.ai.ComputerUtil; import forge.ai.ComputerUtil;
import forge.ai.ComputerUtilCard;
import forge.ai.SpellAbilityAi; import forge.ai.SpellAbilityAi;
import forge.game.GameEntity;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardLists; import forge.game.card.CardLists;
import forge.game.card.CardUtil;
import forge.game.card.CounterType; import forge.game.card.CounterType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
@@ -33,10 +38,14 @@ public class CountersProliferateAi extends SpellAbilityAi {
cperms.addAll(CardLists.filter(p.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() { cperms.addAll(CardLists.filter(p.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() {
@Override @Override
public boolean apply(final Card crd) { public boolean apply(final Card crd) {
if (crd.hasCounters()) { if (!crd.hasCounters()) {
return false; return false;
} }
if (crd.isPlaneswalker()) {
return true;
}
// iterate only over existing counters // iterate only over existing counters
for (final Map.Entry<CounterType, Integer> e : crd.getCounters().entrySet()) { for (final Map.Entry<CounterType, Integer> e : crd.getCounters().entrySet()) {
if (e.getValue() >= 1 && !ComputerUtil.isNegativeCounter(e.getKey(), crd)) { if (e.getValue() >= 1 && !ComputerUtil.isNegativeCounter(e.getKey(), crd)) {
@@ -56,7 +65,11 @@ public class CountersProliferateAi extends SpellAbilityAi {
hperms.addAll(CardLists.filter(o.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() { hperms.addAll(CardLists.filter(o.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() {
@Override @Override
public boolean apply(final Card crd) { public boolean apply(final Card crd) {
if (crd.hasCounters()) { if (!crd.hasCounters()) {
return false;
}
if (crd.isPlaneswalker()) {
return false; return false;
} }
@@ -95,4 +108,61 @@ public class CountersProliferateAi extends SpellAbilityAi {
return canPlayAI(ai, sa); return canPlayAI(ai, sa);
} }
/*
* (non-Javadoc)
* @see forge.ai.SpellAbilityAi#chooseSingleEntity(forge.game.player.Player, forge.game.spellability.SpellAbility, java.util.Collection, boolean, forge.game.player.Player)
*/
@SuppressWarnings("unchecked")
@Override
public <T extends GameEntity> T chooseSingleEntity(Player ai, SpellAbility sa, Collection<T> options, boolean isOptional, Player targetedPlayer) {
// Proliferate is always optional for all, no need to select best
// because countertype can't be chosen anymore, only look for posion counters
for (final Player p : Iterables.filter(options, Player.class)) {
if (p.isOpponentOf(ai)) {
if (p.getCounters(CounterType.POISON) > 0 && p.canReceiveCounters(CounterType.POISON)) {
return (T)p;
}
} else {
if (p.getCounters(CounterType.POISON) <= 5 || p.canReceiveCounters(CounterType.POISON)) {
return (T)p;
}
}
}
for (final Card c : Iterables.filter(options, Card.class)) {
// AI planeswalker always, opponent planeswalkers never
if (c.isPlaneswalker()) {
if (c.getController().isOpponentOf(ai)) {
continue;
} else {
return (T)c;
}
}
final Card lki = CardUtil.getLKICopy(c);
// update all the counters there
boolean hasNegative = false;
for (final CounterType ct : c.getCounters().keySet()) {
hasNegative = hasNegative || ComputerUtil.isNegativeCounter(ct, c);
lki.setCounters(ct, lki.getCounters(ct) + 1);
}
// TODO need more logic there?
// it tries to evaluate the creatures
if (c.isCreature()) {
if (c.getController().isOpponentOf(ai) ==
(ComputerUtilCard.evaluateCreature(lki, true, false)
< ComputerUtilCard.evaluateCreature(c, true, false))) {
return (T)c;
}
} else {
if (!c.getController().isOpponentOf(ai) && !hasNegative) {
return (T)c;
}
}
}
return null;
}
} }

View File

@@ -4,20 +4,25 @@ import forge.game.Game;
import forge.game.GameEntity; import forge.game.GameEntity;
import forge.game.ability.SpellAbilityEffect; import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardLists;
import forge.game.card.CardPredicates;
import forge.game.card.CounterType; import forge.game.card.CounterType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerController;
import forge.game.player.PlayerPredicates;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.collect.FCollection;
import java.util.Map; import java.util.List;
import java.util.Map.Entry;
public class CountersProliferateEffect extends SpellAbilityEffect { public class CountersProliferateEffect extends SpellAbilityEffect {
@Override @Override
protected String getStackDescription(SpellAbility sa) { protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("Proliferate."); sb.append("Proliferate.");
sb.append(" (You choose any number of permanents and/or players with "); sb.append(" (Choose any number of permanents and/or players,");
sb.append("counters on them, then give each another counter of a kind already there.)"); sb.append(" then give each another counter of each kind already there.)");
return sb.toString(); return sb.toString();
} }
@@ -27,16 +32,23 @@ public class CountersProliferateEffect extends SpellAbilityEffect {
final Player p = sa.getActivatingPlayer(); final Player p = sa.getActivatingPlayer();
final Card host = sa.getHostCard(); final Card host = sa.getHostCard();
final Game game = host.getGame(); final Game game = host.getGame();
Player controller = host.getController();
Map<GameEntity, CounterType> proliferateChoice = controller.getController().chooseProliferation(sa); PlayerController pc = p.getController();
if (proliferateChoice == null )
return; FCollection<GameEntity> list = new FCollection<>();
for(Entry<GameEntity, CounterType> ge: proliferateChoice.entrySet()) {
if( ge.getKey() instanceof Player ) list.addAll(game.getPlayers().filter(PlayerPredicates.hasCounters()));
((Player) ge.getKey()).addCounter(ge.getValue(), 1, p, true); list.addAll(CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.hasCounters()));
else if( ge.getKey() instanceof Card) {
Card c = (Card) ge.getKey(); List<GameEntity> result = pc.chooseEntitiesForEffect(list, 0, list.size(), null, sa,
c.addCounter(ge.getValue(), 1, p, true); "Choose any number of permanents and/or players for proliferate", p);
for (final GameEntity ge : result) {
for (final CounterType ct : ge.getCounters().keySet()) {
ge.addCounter(ct, 1, p, true, true);
}
if (ge instanceof Card) {
Card c = (Card) ge;
game.updateLastStateForCard(c); game.updateLastStateForCard(c);
} }
} }

View File

@@ -213,7 +213,6 @@ public abstract class PlayerController {
public abstract void playTrigger(Card host, WrappedAbility wrapperAbility, boolean isMandatory); public abstract void playTrigger(Card host, WrappedAbility wrapperAbility, boolean isMandatory);
public abstract boolean playSaFromPlayEffect(SpellAbility tgtSA); public abstract boolean playSaFromPlayEffect(SpellAbility tgtSA);
public abstract Map<GameEntity, CounterType> chooseProliferation(SpellAbility sa);
public abstract boolean chooseCardsPile(SpellAbility sa, CardCollectionView pile1, CardCollectionView pile2, String faceUp); public abstract boolean chooseCardsPile(SpellAbility sa, CardCollectionView pile1, CardCollectionView pile2, String faceUp);
public abstract void revealAnte(String message, Multimap<Player, PaperCard> removedAnteCards); public abstract void revealAnte(String message, Multimap<Player, PaperCard> removedAnteCards);

View File

@@ -562,12 +562,6 @@ public class PlayerControllerForTests extends PlayerController {
} }
@Override
public Map<GameEntity, CounterType> chooseProliferation(final SpellAbility sa) {
// TODO Auto-generated method stub
return null;
}
@Override @Override
public boolean chooseTargetsFor(SpellAbility currentAbility) { public boolean chooseTargetsFor(SpellAbility currentAbility) {
// no longer possible to run AI's methods on SpellAbility // no longer possible to run AI's methods on SpellAbility

View File

@@ -6,9 +6,9 @@ K:Flying
K:Vigilance K:Vigilance
K:Deathtouch K:Deathtouch
K:Lifelink K:Lifelink
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigProliferate | TriggerDescription$ At the beginning of your end step, proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigProliferate | TriggerDescription$ At the beginning of your end step, proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)
SVar:TrigProliferate:DB$ Proliferate SVar:TrigProliferate:DB$ Proliferate
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckHints:Ability$Counters DeckHints:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/atraxa_praetors_voice.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/atraxa_praetors_voice.jpg
Oracle:Flying, vigilance, deathtouch, lifelink\nAt the beginning of your end step, proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:Flying, vigilance, deathtouch, lifelink\nAt the beginning of your end step, proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -7,4 +7,4 @@ DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ M1M1 | CounterNum$ 1 | IsCurse$ True SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ M1M1 | CounterNum$ 1 | IsCurse$ True
SVar:Picture:http://www.wizards.com/global/images/magic/general/contagion_clasp.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/contagion_clasp.jpg
Oracle:When Contagion Clasp enters the battlefield, put a -1/-1 counter on target creature.\n{4}, {T}: Proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:When Contagion Clasp enters the battlefield, put a -1/-1 counter on target creature.\n{4}, {T}: Proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -8,4 +8,4 @@ SVar:TrigPutCounterAll:DB$ PutCounterAll | ValidTgts$ Player | TgtPrompt$ Select
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/contagion_engine.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/contagion_engine.jpg
Oracle:When Contagion Engine enters the battlefield, put a -1/-1 counter on each creature target player controls.\n{4}, {T}: Proliferate, then proliferate again. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there. Then do it again.) Oracle:When Contagion Engine enters the battlefield, put a -1/-1 counter on each creature target player controls.\n{4}, {T}: Proliferate, then proliferate again. (Choose any number of permanents and/or players, then give each another counter of each kind already there. Then do it again.)

View File

@@ -8,4 +8,4 @@ SVar:TrigProliferate:DB$ Proliferate
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/core_prowler.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/core_prowler.jpg
Oracle:Infect (This creature deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)\nWhen Core Prowler dies, proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:Infect (This creature deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)\nWhen Core Prowler dies, proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -6,4 +6,4 @@ SVar:DBProliferate:DB$Proliferate
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/fuel_for_the_cause.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/fuel_for_the_cause.jpg
Oracle:Counter target spell, then proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:Counter target spell, then proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -1,9 +1,9 @@
Name:Grim Affliction Name:Grim Affliction
ManaCost:2 B ManaCost:2 B
Types:Instant Types:Instant
A:SP$ PutCounter | Cost$ 2 B | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ M1M1 | CounterNum$ 1 | IsCurse$ True | SubAbility$ DBProliferate | SpellDescription$ Put a -1/-1 counter on target creature, then proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) A:SP$ PutCounter | Cost$ 2 B | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ M1M1 | CounterNum$ 1 | IsCurse$ True | SubAbility$ DBProliferate | SpellDescription$ Put a -1/-1 counter on target creature, then proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)
SVar:DBProliferate:DB$Proliferate SVar:DBProliferate:DB$Proliferate
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/grim_affliction.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/grim_affliction.jpg
Oracle:Put a -1/-1 counter on target creature, then proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:Put a -1/-1 counter on target creature, then proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -7,4 +7,4 @@ SVar:BuffedBy:Card
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/inexorable_tide.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/inexorable_tide.jpg
Oracle:Whenever you cast a spell, proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:Whenever you cast a spell, proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -8,4 +8,4 @@ SVar:AIPreference:SacCost$Creature.token+powerLE3+toughnessLE3,Creature.cmcLE2
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/plaguemaw_beast.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/plaguemaw_beast.jpg
Oracle:{T}, Sacrifice a creature: Proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:{T}, Sacrifice a creature: Proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -6,4 +6,4 @@ SVar:DBProliferate:DB$Proliferate
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/spread_the_sickness.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/spread_the_sickness.jpg
Oracle:Destroy target creature, then proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:Destroy target creature, then proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -6,4 +6,4 @@ SVar:DB:DB$Draw | NumCards$ 1
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/steady_progress.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/steady_progress.jpg
Oracle:Proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.)\nDraw a card. Oracle:Proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)\nDraw a card.

View File

@@ -6,4 +6,4 @@ SVar:DBProlif:DB$Proliferate
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/tezzerets_gambit.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/tezzerets_gambit.jpg
Oracle:({P/U} can be paid with either {U} or 2 life.)\nDraw two cards, then proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:({P/U} can be paid with either {U} or 2 life.)\nDraw two cards, then proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -7,4 +7,4 @@ DeckNeeds:Ability$Counters
SVar:AIPreference:SacCost$Artifact.token,Artifact.cmcLE2 SVar:AIPreference:SacCost$Artifact.token,Artifact.cmcLE2
AI:RemoveDeck:Random AI:RemoveDeck:Random
SVar:Picture:http://www.wizards.com/global/images/magic/general/throne_of_geth.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/throne_of_geth.jpg
Oracle:{T}, Sacrifice an artifact: Proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:{T}, Sacrifice an artifact: Proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -8,4 +8,4 @@ SVar:TrigProliferate:DB$ Proliferate
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckHints:Ability$Counters DeckHints:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/thrummingbird.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/thrummingbird.jpg
Oracle:Flying\nWhenever Thrummingbird deals combat damage to a player, proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:Flying\nWhenever Thrummingbird deals combat damage to a player, proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -8,4 +8,4 @@ A:AB$ Proliferate | Cost$ 3 U | SpellDescription$ Proliferate.
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/viral_drake.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/viral_drake.jpg
Oracle:Flying\nInfect (This creature deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)\n{3}{U}: Proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:Flying\nInfect (This creature deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)\n{3}{U}: Proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -1,9 +1,9 @@
Name:Volt Charge Name:Volt Charge
ManaCost:2 R ManaCost:2 R
Types:Instant Types:Instant
A:SP$ DealDamage | Cost$ 2 R | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 3 | SubAbility$ DBProliferate | SpellDescription$ CARDNAME deals 3 damage to any target. Proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) A:SP$ DealDamage | Cost$ 2 R | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 3 | SubAbility$ DBProliferate | SpellDescription$ CARDNAME deals 3 damage to any target. Proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)
SVar:DBProliferate:DB$Proliferate SVar:DBProliferate:DB$Proliferate
DeckHas:Ability$Proliferate DeckHas:Ability$Proliferate
DeckNeeds:Ability$Counters DeckNeeds:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/volt_charge.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/volt_charge.jpg
Oracle:Volt Charge deals 3 damage to any target. Proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Oracle:Volt Charge deals 3 damage to any target. Proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)

View File

@@ -1,131 +0,0 @@
package forge.match.input;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import forge.model.FModel;
import forge.properties.ForgePreferences;
import forge.game.GameEntity;
import forge.game.card.Card;
import forge.game.card.CounterType;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.player.PlayerControllerHuman;
import forge.util.ITriggerEvent;
public final class InputProliferate extends InputSelectManyBase<GameEntity> {
private static final long serialVersionUID = -1779224307654698954L;
private final Map<GameEntity, CounterType> chosenCounters = new HashMap<GameEntity, CounterType>();
private SpellAbility sa;
public InputProliferate(final PlayerControllerHuman controller, final SpellAbility sa) {
super(controller, 1, Integer.MAX_VALUE);
this.sa = sa;
}
@Override
protected String getMessage() {
final StringBuilder sb = new StringBuilder();
if ( FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_DETAILED_SPELLDESC_IN_PROMPT) &&
sa != null ) {
sb.append(sa.getStackDescription()).append("\n");
}
sb.append("Choose permanents and/or players with counters on them to add one more counter of that type.");
sb.append("\n\nYou've selected so far:\n");
if (chosenCounters.isEmpty()) {
sb.append("(none)");
}
else {
for (final Entry<GameEntity, CounterType> ge : chosenCounters.entrySet()) {
sb.append("* ").append(ge.getKey()).append(" -> ").append(ge.getValue()).append("counter\n");
}
}
return sb.toString();
}
@Override
protected boolean onCardSelected(final Card card, final List<Card> otherCardsToSelect, final ITriggerEvent triggerEvent) {
if (!card.hasCounters()) {
return false;
}
final boolean entityWasSelected = chosenCounters.containsKey(card);
if (entityWasSelected) {
this.chosenCounters.remove(card);
}
else {
final List<CounterType> choices = new ArrayList<CounterType>();
for (final CounterType ct : CounterType.values()) {
if (card.getCounters(ct) > 0) {
choices.add(ct);
}
}
final CounterType toAdd = choices.size() == 1 ? choices.get(0) : getController().getGui().one("Select counter type", choices);
chosenCounters.put(card, toAdd);
}
refresh();
return true;
}
@Override
public String getActivateAction(final Card card) {
if (card.hasCounters() && !chosenCounters.containsKey(card)) {
return "add counter to card";
}
return null;
}
@Override
protected final void onPlayerSelected(final Player player, final ITriggerEvent triggerEvent) {
if (!player.hasCounters()) {
// Can't select a player without counters
return;
}
final boolean entityWasSelected = chosenCounters.containsKey(player);
if (entityWasSelected) {
this.chosenCounters.remove(player);
} else {
final List<CounterType> choices = new ArrayList<CounterType>();
for (final CounterType ct : player.getCounters().keySet()) {
if (player.getCounters(ct) > 0) {
choices.add(ct);
}
}
if (player.hasKeyword("You can't get poison counters")) {
choices.remove(CounterType.POISON);
}
final CounterType toAdd = choices.size() == 1 ? choices.get(0) : getController().getGui().one("Select counter type", choices);
this.chosenCounters.put(player, toAdd);
}
refresh();
}
public Map<GameEntity, CounterType> getProliferationMap() {
return chosenCounters;
}
@Override
protected boolean hasEnoughTargets() { return true; }
@Override
protected boolean hasAllTargets() { return false; }
@Override
public Collection<GameEntity> getSelected() {
// TODO Auto-generated method stub
return chosenCounters.keySet();
}

View File

@@ -1724,17 +1724,6 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
return HumanPlay.playSpellAbility(this, player, tgtSA); return HumanPlay.playSpellAbility(this, player, tgtSA);
} }
@Override
public Map<GameEntity, CounterType> chooseProliferation(final SpellAbility sa) {
final InputProliferate inp = new InputProliferate(this, sa);
inp.setCancelAllowed(true);
inp.showAndWait();
if (inp.hasCancelled()) {
return null;
}
return inp.getProliferationMap();
}
@Override @Override
public boolean chooseTargetsFor(final SpellAbility currentAbility) { public boolean chooseTargetsFor(final SpellAbility currentAbility) {
final TargetSelection select = new TargetSelection(this, currentAbility); final TargetSelection select = new TargetSelection(this, currentAbility);