mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
War: Proliferate: rework effect now put each counter type on it
This commit is contained in:
committed by
swordshine
parent
5c95216d9d
commit
2617795e37
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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.)
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user