@Override public void update() { activeItem = null; activeStackInstance = null; // reset before updating stack restoreOldZones(); final FCollectionView<StackItemView> stack = MatchController.instance.getGameView().getStack(); if (stackSize != stack.size()) { int oldStackSize = stackSize; stackSize = stack.size(); getMenuTab().setText("Stack (" + stackSize + ")"); if (stackSize > 0) { if (!isVisible()) { if (stackSize > oldStackSize) { // don't re-show stack if user hid it and then resolved an item on // the stack show(); } return; // don't call super.update() either way since show handles this } } else { hide(); return; // super.update() isn't needed if hidden } } super.update(); }
/* (non-Javadoc) * @see forge.card.ability.SpellAbilityEffect#resolve(forge.card.spellability.SpellAbility) */ @Override public void resolve(SpellAbility sa) { Player activator = sa.getActivatingPlayer(); Card source = sa.getHostCard(); Game game = activator.getGame(); String valid = sa.hasParam("Valid") ? sa.getParam("Valid") : "Card"; ZoneType zone = sa.hasParam("Zone") ? ZoneType.smartValueOf(sa.getParam("Zone")) : ZoneType.Battlefield; int min = Integer.MAX_VALUE; final FCollectionView<Player> players = game.getPlayersInTurnOrder(); final List<CardCollection> validCards = new ArrayList<CardCollection>(players.size()); for (int i = 0; i < players.size(); i++) { // Find the minimum of each Valid per player validCards.add( CardLists.getValidCards(players.get(i).getCardsIn(zone), valid, activator, source)); min = Math.min(min, validCards.get(i).size()); } for (int i = 0; i < players.size(); i++) { Player p = players.get(i); int numToBalance = validCards.get(i).size() - min; if (numToBalance == 0) { continue; } if (zone.equals(ZoneType.Hand)) { for (Card card : p.getController() .chooseCardsToDiscardFrom(p, sa, validCards.get(i), numToBalance, numToBalance)) { if (null == card) continue; p.discard(card, sa); } } else { // Battlefield // TODO: "can'e be sacrificed" for (Card card : p.getController() .choosePermanentsToSacrifice( sa, numToBalance, numToBalance, validCards.get(i), valid)) { if (null == card) continue; game.getAction().sacrifice(card, sa); } } } }
@Override protected ScrollBounds updateAndGetPaneSize(float maxWidth, float maxVisibleHeight) { clear(); float x = MARGINS; float y = MARGINS; float totalWidth; if (Forge.isLandscapeMode()) { totalWidth = Forge.getScreenWidth() * 0.35f; } else { totalWidth = maxWidth - MatchController.getView() .getTopPlayerPanel() .getTabs() .iterator() .next() .getRight(); // keep avatar, life total, and hand tab visible to left of stack } float width = totalWidth - 2 * MARGINS; final FCollectionView<StackItemView> stack = MatchController.instance.getGameView().getStack(); if (stack.isEmpty()) { // show label if stack empty FLabel label = add(new FLabel.Builder().text("[Empty]").font(FONT).align(HAlignment.CENTER).build()); float height = Math.round(label.getAutoSizeBounds().height) + 2 * PADDING; label.setBounds(x, y, width, height); return new ScrollBounds(totalWidth, y + height + MARGINS); } else { // iterate stack in reverse so most recent items appear on bottom StackItemView stackInstance = null; StackInstanceDisplay display = null; float overlap = Math.round(CARD_HEIGHT / 2 + PADDING + BORDER_THICKNESS); for (int i = stack.size() - 1; i >= 0; i--) { stackInstance = stack.get(i); display = new StackInstanceDisplay(stackInstance, width); if (activeStackInstance == stackInstance) { activeItem = display; } else { // only add non-active items here add(display); } // use full preferred height of display for topmost item on stack, overlap amount for other // items display.setBounds(x, y, width, i > 0 ? overlap : display.preferredHeight); y += display.getHeight(); } if (activeStackInstance == null) { activeStackInstance = stackInstance; // use topmost item on stack as default active item activeItem = display; } else { activeItem.setHeight( display.preferredHeight); // increase active item height to preferred height if needed if (activeItem.getBottom() > y) { y = activeItem.getBottom(); // ensure stack height increases if needed } add(activeItem); } scrollIntoView(activeItem); // scroll active display into view revealTargetZones(); } return new ScrollBounds(totalWidth, y + MARGINS); }