package magic.model.choice; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; import magic.exception.GameException; import magic.exception.UndoClickedException; import magic.model.IUIGameController; import magic.model.MagicCostManaType; import magic.model.MagicGame; import magic.model.MagicManaCost; import magic.model.MagicPermanent; import magic.model.MagicPlayer; import magic.model.MagicRandom; import magic.model.MagicSource; import magic.model.event.MagicEvent; /** X must be at least one in a mana cost. */ public class MagicPayManaCostChoice extends MagicChoice { private final MagicManaCost cost; public MagicPayManaCostChoice(final MagicManaCost cost) { super("Choose how to pay the mana cost."); this.cost=cost; } @Override public int getManaChoiceResultIndex() { return 0; } @Override public boolean hasOptions(final MagicGame game,final MagicPlayer player,final MagicSource source,final boolean hints) { final MagicBuilderManaCost builderCost=new MagicBuilderManaCost(player.getBuilderCost()); cost.addTo(builderCost); return new MagicPayManaCostResultBuilder(game,player,builderCost).hasResults(); } private Collection<Object> genOptions(final MagicGame game, final MagicPlayer player) { return game.getFastMana() ? buildDelayedPayManaCostResults(game,player) : new MagicPayManaCostResultBuilder(game,player,cost.getBuilderCost()).getResults(); } private Collection<Object> buildDelayedPayManaCostResults(final MagicGame game,final MagicPlayer player) { if (cost.hasX()) { final int maxX=player.getMaximumX(game,cost); if (maxX <= 0) { throw new GameException("Unable to pay for {X} in " + cost + " as maxX = " + maxX, game); } else if (maxX == 1) { return Collections.<Object>singletonList(new MagicDelayedPayManaCostResult(cost,1)); } else { final List<Object> choices=new ArrayList<Object>(); for (int x=1;x<=maxX;x++) { choices.add(new MagicDelayedPayManaCostResult(cost,x)); } return choices; } } else { return Collections.<Object>singletonList(new MagicDelayedPayManaCostResult(cost,0)); } } @Override Collection<Object> getArtificialOptions(final MagicGame game, final MagicEvent event) { final MagicPlayer player = event.getPlayer(); final MagicSource source = event.getSource(); final Collection<Object> options = genOptions(game, player); assert !options.isEmpty() : "No options to pay mana cost\n" + "fastMana = " + game.getFastMana() + "\n" + "source = " + source + "\n" + "player = " + player + "\n" + "event = " + event + "\n"; return options; } @Override public Object[] getSimulationChoiceResult(final MagicGame game, final MagicEvent event) { final MagicPlayer player = event.getPlayer(); //in simulation use delayed pay mana cost final List<Object> choices = (List<Object>)buildDelayedPayManaCostResults(game,player); return new Object[]{choices.get(MagicRandom.nextRNGInt(choices.size()))}; } @Override public Object[] getPlayerChoiceResults(final IUIGameController controller, final MagicGame game, final MagicEvent event) throws UndoClickedException { final MagicPlayer player = event.getPlayer(); final MagicSource source = event.getSource(); controller.disableActionButton(false); final int x; if (cost.hasX()) { final int maximumX = player.getMaximumX(game, cost); x = controller.getPayManaCostXChoice(source, maximumX); } else { x = 0; } final List<MagicCostManaType> costManaTypes=cost.getCostManaTypes(x); final MagicBuilderManaCost builderCost=new MagicBuilderManaCost(); builderCost.addTypes(costManaTypes); final MagicPayManaCostResultBuilder builder=new MagicPayManaCostResultBuilder(game,player,builderCost); final boolean canSkip = MagicGame.canSkipSingleManaChoice(); final int costMinAmount = builderCost.getMinimumAmount(); // if number of mana permanents equal to min amount && // number of mana abilities equal to min amount // then the only way to pay is to use each mana ability boolean useAll = false; if (builder.getActivationsSize() == costMinAmount) { int totalManaActivations = 0; for (final MagicPermanent perm : player.getPermanents()) { totalManaActivations += perm.countManaActivations(); } if (totalManaActivations == costMinAmount) { useAll = true; } } for (final MagicCostManaType costManaType : costManaTypes) { if (canSkip&&builder.useAllManaSources(costManaType)) { controller.updateGameView(); break; } final Set<MagicPermanent> validSources=builder.getManaSources(costManaType,!canSkip); MagicPermanent sourcePermanent = MagicPermanent.NONE; if (canSkip && (validSources.size() == 1 || useAll)) { // only one valid choice or must use all sourcePermanent = validSources.iterator().next(); } else { controller.setValidChoices(validSources,false); controller.showMessage(source,"Choose a mana source to pay "+costManaType.getText()+"."); controller.waitForInput(); controller.clearValidChoices(); sourcePermanent = controller.getChoiceClicked(); } builder.useManaSource(sourcePermanent,costManaType); controller.updateGameView(); } return new Object[]{new MagicPlayerPayManaCostResult(x,costManaTypes.size())}; } }