diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java index 79b0098859b..3f3ea7f2ef6 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Random; import com.google.common.base.Predicate; @@ -1294,7 +1295,7 @@ public class AbilityFactoryCounters { @Override public boolean canPlayAI() { - return AbilityFactoryCounters.proliferateShouldPlayAI(this); + return AbilityFactoryCounters.proliferateShouldPlayAI(getActivatingPlayer(), this); } @Override @@ -1332,7 +1333,7 @@ public class AbilityFactoryCounters { @Override public boolean canPlayAI() { - return AbilityFactoryCounters.proliferateShouldPlayAI(this); + return AbilityFactoryCounters.proliferateShouldPlayAI(getActivatingPlayer(), this); } @Override @@ -1376,7 +1377,7 @@ public class AbilityFactoryCounters { @Override public boolean canPlayAI() { - return AbilityFactoryCounters.proliferateShouldPlayAI(this); + return AbilityFactoryCounters.proliferateShouldPlayAI(getActivatingPlayer(), this); } @Override @@ -1391,7 +1392,7 @@ public class AbilityFactoryCounters { @Override public boolean chkAIDrawback() { - return AbilityFactoryCounters.proliferateShouldPlayAI(this); + return AbilityFactoryCounters.proliferateShouldPlayAI(getActivatingPlayer(), this); } @Override @@ -1441,14 +1442,16 @@ public class AbilityFactoryCounters { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean proliferateShouldPlayAI(final SpellAbility sa) { + private static boolean proliferateShouldPlayAI(final Player ai, final SpellAbility sa) { boolean chance = true; final AbilitySub subAb = sa.getSubAbility(); if (subAb != null && !subAb.chkAIDrawback()) { return false; } - List hperms = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); - List cperms = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + + + + List cperms = ai.getCardsIn(ZoneType.Battlefield); cperms = CardLists.filter(cperms, new Predicate() { @Override public boolean apply(final Card crd) { @@ -1461,6 +1464,7 @@ public class AbilityFactoryCounters { } }); + List hperms = ai.getOpponent().getCardsIn(ZoneType.Battlefield); hperms = CardLists.filter(hperms, new Predicate() { @Override public boolean apply(final Card crd) { @@ -1473,7 +1477,7 @@ public class AbilityFactoryCounters { } }); - if ((cperms.size() == 0) && (hperms.size() == 0) && (AllZone.getHumanPlayer().getPoisonCounters() == 0)) { + if ((cperms.size() == 0) && (hperms.size() == 0) && (ai.getOpponent().getPoisonCounters() == 0)) { return false; } return chance; @@ -1512,154 +1516,139 @@ public class AbilityFactoryCounters { * @param sa * a {@link forge.card.spellability.SpellAbility} object. */ + private static void proliferateResolve(final AbilityFactory af, final SpellAbility sa) { - List hperms = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); - List cperms = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + Player controller = sa.getSourceCard().getController(); + if (controller.isHuman()) + proliferateResolveHuman(af, sa); + else + proliferateResolveAI(controller, af, sa); + } + + private static void proliferateResolveHuman(final AbilityFactory af, final SpellAbility sa) { + final List unchosen = AllZoneUtil.getCardsIn(ZoneType.Battlefield); + AllZone.getInputControl().setInput(new Input() { + private static final long serialVersionUID = -1779224307654698954L; - if (sa.getSourceCard().getController().isHuman()) { - cperms.addAll(hperms); - final List unchosen = cperms; - AllZone.getInputControl().setInput(new Input() { - private static final long serialVersionUID = -1779224307654698954L; + @Override + public void showMessage() { + ButtonUtil.enableOnlyCancel(); + CMatchUI.SINGLETON_INSTANCE.showMessage("Proliferate: Choose permanents and/or players"); + } - @Override - public void showMessage() { - ButtonUtil.enableOnlyCancel(); - CMatchUI.SINGLETON_INSTANCE.showMessage("Proliferate: Choose permanents and/or players"); - } + @Override + public void selectButtonCancel() { + // Hacky intermittent solution to triggers that look for + // counters being put on. They used + // to wait for another priority passing after proliferate + // finished. + AllZone.getStack().chooseOrderOfSimultaneousStackEntryAll(); + this.stop(); + } - @Override - public void selectButtonCancel() { - // Hacky intermittent solution to triggers that look for - // counters being put on. They used - // to wait for another priority passing after proliferate - // finished. - AllZone.getStack().chooseOrderOfSimultaneousStackEntryAll(); - this.stop(); + @Override + public void selectCard(final Card card, final PlayerZone zone) { + if (!unchosen.contains(card)) { + return; } - - @Override - public void selectCard(final Card card, final PlayerZone zone) { - if (!unchosen.contains(card)) { - return; - } - unchosen.remove(card); - final ArrayList choices = new ArrayList(); - for (final Counters c1 : Counters.values()) { - if (card.getCounters(c1) != 0) { - choices.add(c1.getName()); - } - } - if (choices.size() > 0) { - card.addCounter( - Counters.getType((choices.size() == 1 ? choices.get(0) : GuiChoose.one( - "Select counter type", choices).toString())), 1); - } - } - - private boolean selComputer = false; - private boolean selHuman = false; - - @Override - public void selectPlayer(final Player player) { - if (player.isHuman() && (!this.selHuman)) { - this.selHuman = true; - if (AllZone.getHumanPlayer().getPoisonCounters() > 0) { - AllZone.getHumanPlayer().addPoisonCounters(1, sa.getSourceCard()); - } - } - if (player.isComputer() && (!this.selComputer)) { - this.selComputer = true; - if (AllZone.getComputerPlayer().getPoisonCounters() > 0) { - AllZone.getComputerPlayer().addPoisonCounters(1, sa.getSourceCard()); - } - } - } - }); - } else { // Compy - cperms = CardLists.filter(cperms, new Predicate() { - @Override - public boolean apply(final Card crd) { - for (final Counters c1 : Counters.values()) { - if (crd.getCounters(c1) != 0) { - if (!CardFactoryUtil.isNegativeCounter(c1)) { - return true; - } - } - } - return false; - } - }); - - hperms = CardLists.filter(hperms, new Predicate() { - @Override - public boolean apply(final Card crd) { - for (final Counters c1 : Counters.values()) { - if (crd.getCounters(c1) != 0) { - if (CardFactoryUtil.isNegativeCounter(c1)) { - return true; - } - } - } - return false; - } - }); - - final StringBuilder sb = new StringBuilder(); - sb.append("Proliferate:
Computer selects "); - if ((cperms.size() == 0) && (hperms.size() == 0) && (AllZone.getHumanPlayer().getPoisonCounters() == 0)) { - sb.append("nothing."); - } else { - if (cperms.size() > 0) { - sb.append("
From Computer's permanents:
"); - for (final Card c : cperms) { - sb.append(c); - sb.append(" "); - } - sb.append("
"); - } - if (hperms.size() > 0) { - sb.append("
From Human's permanents:
"); - for (final Card c : cperms) { - sb.append(c); - sb.append(" "); - } - sb.append("
"); - } - if (AllZone.getHumanPlayer().getPoisonCounters() > 0) { - sb.append("Human Player."); - } - } // else - sb.append(""); - - // add a counter of one counter type, if it would benefit the - // computer - for (final Card c : cperms) { + unchosen.remove(card); + final ArrayList choices = new ArrayList(); for (final Counters c1 : Counters.values()) { - if (c.getCounters(c1) != 0 && !CardFactoryUtil.isNegativeCounter(c1)) { - c.addCounter(c1, 1); - break; + if (card.getCounters(c1) != 0) { + choices.add(c1.getName()); } } + if (choices.size() > 0) { + card.addCounter( + Counters.getType((choices.size() == 1 ? choices.get(0) : GuiChoose.one( + "Select counter type", choices).toString())), 1); + } } - // add a counter of one counter type, if it would screw over the - // player - for (final Card c : hperms) { - for (final Counters c1 : Counters.values()) { - if (c.getCounters(c1) != 0 && CardFactoryUtil.isNegativeCounter(c1)) { - c.addCounter(c1, 1); - break; + List players = AllZone.getPlayersInGame(); + + @Override + public void selectPlayer(final Player player) { + if (players.indexOf(player) >= 0) + { + players.remove(player); // no second selection + if (player.getPoisonCounters() > 0) { + player.addPoisonCounters(1, sa.getSourceCard()); } } } - - // give human a poison counter, if he has one - if (AllZone.getHumanPlayer().getPoisonCounters() > 0) { - AllZone.getHumanPlayer().addPoisonCounters(1, sa.getSourceCard()); + }); + } + + + + private static void proliferateResolveAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { + final List allies = ai.getAllies(); + allies.add(ai); + final List enemies = ai.getOpponents(); + final Predicate predProliferate = new Predicate() { + @Override + public boolean apply(Card crd) { + for (final Entry c1 : crd.getCounters().entrySet()) { + if ( CardFactoryUtil.isNegativeCounter(c1.getKey()) && enemies.contains(crd.getController())) + return true; + if ( !CardFactoryUtil.isNegativeCounter(c1.getKey()) && allies.contains(crd.getController())) + return true; + } + return false; } + }; - } // comp + List cardsToProliferate = CardLists.filter(AllZoneUtil.getCardsIn(ZoneType.Battlefield), predProliferate); + List playersToPoison = new ArrayList(); + for( Player e : enemies ) { + if ( e.getPoisonCounters() > 0 ) + playersToPoison.add(e); + } + + final StringBuilder sb = new StringBuilder(); + sb.append("Proliferate. Computer selects:
"); + if (cardsToProliferate.isEmpty() && playersToPoison.isEmpty()) { + sb.append("nothing."); + } else { + for( Card c : cardsToProliferate ) { + sb.append(c.getController().getName()); + sb.append("'s "); + sb.append(c.getName()); + sb.append("
"); + } + + if( !playersToPoison.isEmpty() ) { + sb.append("
The following players:
"); + } + for( Player p : playersToPoison ) { + sb.append(""); + sb.append(p.getName()); + sb.append("
"); + } + } // else + sb.append(""); + + // add a counter of one counter type, if it would benefit the + // computer + for (final Card c : cardsToProliferate) { + for (final Entry c1 : c.getCounters().entrySet()) { + if ( CardFactoryUtil.isNegativeCounter(c1.getKey()) && enemies.contains(c.getController())) + { + c.addCounter(c1.getKey(), 1); + break; + } + if ( !CardFactoryUtil.isNegativeCounter(c1.getKey()) && allies.contains(c.getController())) + { + c.addCounter(c1.getKey(), 1); + break; + } + } + } + + for(final Player p : playersToPoison ) { + p.addPoisonCounters(1, sa.getSourceCard()); + } } // ******************************************* diff --git a/src/main/java/forge/game/player/AIPlayer.java b/src/main/java/forge/game/player/AIPlayer.java index 8d04d55574b..f2eaf0c3602 100644 --- a/src/main/java/forge/game/player/AIPlayer.java +++ b/src/main/java/forge/game/player/AIPlayer.java @@ -21,8 +21,6 @@ import java.util.List; import java.util.Random; import com.google.common.collect.Iterables; - -import forge.AllZone; import forge.Card; import forge.CardLists; @@ -72,24 +70,12 @@ public class AIPlayer extends Player { super(myName, myLife, myPoisonCounters); } - /** - *

- * getOpponent. - *

- * - * @return a {@link forge.game.player.Player} object. - */ - @Override - public final Player getOpponent() { - return AllZone.getHumanPlayer(); - } - + // ////////////// // / // / Methods to ease transition to Abstract Player class // / // ///////////// - /** *

* isHuman. diff --git a/src/main/java/forge/game/player/HumanPlayer.java b/src/main/java/forge/game/player/HumanPlayer.java index 8274053ef4c..f549ccfebd6 100644 --- a/src/main/java/forge/game/player/HumanPlayer.java +++ b/src/main/java/forge/game/player/HumanPlayer.java @@ -68,18 +68,6 @@ public class HumanPlayer extends Player { super(myName, myLife, myPoisonCounters); } - /** - *

- * getOpponent. - *

- * - * @return a {@link forge.game.player.Player} object. - */ - @Override - public final Player getOpponent() { - return AllZone.getComputerPlayer(); - } - // ////////////// // / // / Methods to ease transition to Abstract Player class diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index 829299eba4c..9122f775770 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -29,6 +29,7 @@ import java.util.Random; import javax.swing.JOptionPane; import com.google.common.base.Function; +import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -244,12 +245,38 @@ public abstract class Player extends GameEntity implements Comparable { /** *

- * getOpponent. + * getOpponent. WILL BE DEPRECATED *

* * @return a {@link forge.game.player.Player} object. */ - public abstract Player getOpponent(); + public final Player getOpponent() { + Predicate enemy = com.google.common.base.Predicates.not(Player.Predicates.isType(this.getType())); + return Iterables.find(Singletons.getModel().getGameState().getPlayers(), enemy); + } + + /** + * + * returns all opponents + * Should keep player relations somewhere in the match structure + * @return + */ + public final List getOpponents() { + Predicate enemy = com.google.common.base.Predicates.not(Player.Predicates.isType(this.getType())); + return Lists.newArrayList(Iterables.filter(Singletons.getModel().getGameState().getPlayers(), enemy)); + } + + /** + * returns allied players + * Should keep player relations somewhere in the match structure + * @return + */ + public final List getAllies() { + Predicate enemy = Player.Predicates.isType(this.getType()); + return Lists.newArrayList(Iterables.filter(Singletons.getModel().getGameState().getPlayers(), enemy)); + } + + // //////////////////////// // @@ -2698,6 +2725,18 @@ public abstract class Player extends GameEntity implements Comparable { this.deck = deck; } + public static class Predicates { + + public static Predicate isType(final PlayerType type) { + return new Predicate() { + @Override + public boolean apply(Player input){ + return input.getType() == type; + } + }; + } + } + public static class Accessors { public static Function FN_GET_LIFE = new Function(){ @Override