mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
Support exiling and retrieving multiple for Planar Conquest
This commit is contained in:
@@ -532,6 +532,16 @@ public abstract class ItemManager<T extends InventoryItem> extends FContainer im
|
||||
updateView(false, items);
|
||||
}
|
||||
|
||||
public void addItemsFlat(Iterable<T> itemsToAdd) {
|
||||
pool.addAllFlat(itemsToAdd);
|
||||
if (isUnfiltered()) {
|
||||
for (T item : itemsToAdd) {
|
||||
model.addItem(item, 1);
|
||||
}
|
||||
}
|
||||
updateView(false, itemsToAdd);
|
||||
}
|
||||
|
||||
public void setItems(Iterable<Entry<T, Integer>> items) {
|
||||
pool.clear();
|
||||
model.clear();
|
||||
@@ -560,6 +570,18 @@ public abstract class ItemManager<T extends InventoryItem> extends FContainer im
|
||||
updateView(false, itemsToSelect);
|
||||
}
|
||||
|
||||
public void removeItemsFlat(Iterable<T> itemsToRemove) {
|
||||
final Iterable<T> itemsToSelect = currentView == listView ? getSelectedItems() : null;
|
||||
|
||||
pool.removeAllFlat(itemsToRemove);
|
||||
if (isUnfiltered()) {
|
||||
for (T item : itemsToRemove) {
|
||||
model.removeItem(item, 1);
|
||||
}
|
||||
}
|
||||
updateView(false, itemsToSelect);
|
||||
}
|
||||
|
||||
public void removeAllItems() {
|
||||
pool.clear();
|
||||
model.clear();
|
||||
|
||||
@@ -120,17 +120,21 @@ public abstract class ItemView<T extends InventoryItem> {
|
||||
protected abstract void onRefresh();
|
||||
protected void fixSelection(final Iterable<T> itemsToSelect, final int backupIndexToSelect, final float scrollValueToRestore) {
|
||||
if (itemsToSelect == null) {
|
||||
if (maxSelections <= 1 || minSelections > 0) {
|
||||
setSelectedIndex(0, false); //select first item if no items to select
|
||||
}
|
||||
else { //if in multi-select mode, clear selection instead
|
||||
if (itemManager.getMultiSelectMode()) { //if in multi-select mode, clear selection
|
||||
setSelectedIndex(-1, false);
|
||||
}
|
||||
else { //otherwise select first item if no items to select
|
||||
setSelectedIndex(0, false);
|
||||
}
|
||||
setScrollValue(0); //ensure scrolled to top
|
||||
}
|
||||
else {
|
||||
if (!setSelectedItems(itemsToSelect)) {
|
||||
setSelectedIndex(backupIndexToSelect);
|
||||
|
||||
if (itemManager.getMultiSelectMode()) { //in multi-select mode, clear selection after scrolling into view
|
||||
setSelectedIndex(-1, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,8 +249,7 @@ public abstract class ItemView<T extends InventoryItem> {
|
||||
}
|
||||
|
||||
protected void onSelectionChange() {
|
||||
final int index = getSelectedIndex();
|
||||
if (index != -1) {
|
||||
if (getSelectedIndex() != -1 || itemManager.getMultiSelectMode()) {
|
||||
if (itemManager.getSelectionChangedHandler() != null) {
|
||||
itemManager.getSelectionChangedHandler().handleEvent(new FEvent(itemManager, FEventType.CHANGE));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package forge.screens.planarconquest;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.assets.FImage;
|
||||
@@ -34,12 +36,62 @@ import forge.toolbox.FEvent.FEventHandler;
|
||||
public class ConquestCollectionScreen extends TabPageScreen<ConquestCollectionScreen> {
|
||||
private final FLabel lblShards = add(new FLabel.Builder().font(ConquestAEtherScreen.LABEL_FONT).parseSymbols().build());
|
||||
private final FLabel lblInfo = add(new FLabel.Builder().font(FSkinFont.get(11)).build());
|
||||
private final FLabel btnExileMultiple = add(new FLabel.ButtonBuilder().font(ConquestAEtherScreen.LABEL_FONT).parseSymbols().build());
|
||||
|
||||
public ConquestCollectionScreen() {
|
||||
super("", ConquestMenu.getMenu(), new CollectionTab[] {
|
||||
new CollectionTab("Collection", FSkinImage.SPELLBOOK),
|
||||
new CollectionTab("Exile", FSkinImage.EXILE)
|
||||
});
|
||||
btnExileMultiple.setVisible(false); //hide unless in multi-select mode
|
||||
btnExileMultiple.setCommand(new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
final ConquestData model = FModel.getConquest().getModel();
|
||||
|
||||
FThreads.invokeInBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (getSelectedPage() == tabPages[0]) {
|
||||
int value = 0;
|
||||
final Collection<PaperCard> cards = getCollectionTab().list.getSelectedItems();
|
||||
for (PaperCard card : cards) {
|
||||
value += ConquestUtil.getShardValue(card, CQPref.AETHER_BASE_EXILE_VALUE);
|
||||
}
|
||||
if (model.exileCards(cards, value)) {
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateShards();
|
||||
getCollectionTab().list.removeItemsFlat(cards);
|
||||
getExileTab().list.addItemsFlat(cards);
|
||||
updateTabCaptions();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
int cost = 0;
|
||||
final Collection<PaperCard> cards = getExileTab().list.getSelectedItems();
|
||||
for (PaperCard card : cards) {
|
||||
cost += ConquestUtil.getShardValue(card, CQPref.AETHER_BASE_RETRIEVE_COST);
|
||||
}
|
||||
if (model.retrieveCardsFromExile(cards, cost)) {
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateShards();
|
||||
getCollectionTab().list.addItemsFlat(cards);
|
||||
getExileTab().list.removeItemsFlat(cards);
|
||||
updateTabCaptions();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,6 +135,38 @@ public class ConquestCollectionScreen extends TabPageScreen<ConquestCollectionSc
|
||||
getExileTab().updateCaption();
|
||||
}
|
||||
|
||||
private void updateExileButtonCaption() {
|
||||
String action;
|
||||
CQPref baseValuePref;
|
||||
Collection<PaperCard> cards;
|
||||
if (getSelectedPage() == tabPages[0]) {
|
||||
action = "Exile";
|
||||
baseValuePref = CQPref.AETHER_BASE_EXILE_VALUE;
|
||||
cards = getCollectionTab().list.getSelectedItems();
|
||||
}
|
||||
else {
|
||||
action = "Retrieve";
|
||||
baseValuePref = CQPref.AETHER_BASE_RETRIEVE_COST;
|
||||
cards = getExileTab().list.getSelectedItems();
|
||||
}
|
||||
|
||||
int count = cards.size();
|
||||
String caption = action;
|
||||
if (count > 0) {
|
||||
if (count > 1) {
|
||||
caption += " " + count + " cards";
|
||||
}
|
||||
int total = 0;
|
||||
for (PaperCard card : cards) {
|
||||
total += ConquestUtil.getShardValue(card, baseValuePref);
|
||||
}
|
||||
caption += " for {AE}" + total;
|
||||
}
|
||||
|
||||
btnExileMultiple.setText(caption);
|
||||
btnExileMultiple.setEnabled(count > 0);
|
||||
}
|
||||
|
||||
private CollectionTab getCollectionTab() {
|
||||
return (CollectionTab)tabPages[0];
|
||||
}
|
||||
@@ -104,6 +188,9 @@ public class ConquestCollectionScreen extends TabPageScreen<ConquestCollectionSc
|
||||
lblInfo.setBounds(x + labelWidth, y, w - labelWidth, labelHeight);
|
||||
y += labelHeight;
|
||||
super.doLayout(y, width, height);
|
||||
|
||||
float buttonHeight = tabHeader.getHeight() - 2 * ItemFilter.PADDING;
|
||||
btnExileMultiple.setBounds(x, height - buttonHeight - ItemFilter.PADDING, w, buttonHeight);
|
||||
}
|
||||
|
||||
private static class CollectionTab extends TabPage<ConquestCollectionScreen> {
|
||||
@@ -125,7 +212,15 @@ public class ConquestCollectionScreen extends TabPageScreen<ConquestCollectionSc
|
||||
protected void doLayout(float width, float height) {
|
||||
list.setBounds(0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean fling(float velocityX, float velocityY) {
|
||||
if (list.getMultiSelectMode()) {
|
||||
return false; //prevent changing tabs while in multi-select mode
|
||||
}
|
||||
return super.fling(velocityX, velocityY);
|
||||
}
|
||||
|
||||
private class CollectionManager extends CardManager {
|
||||
public CollectionManager(String caption0) {
|
||||
super(false);
|
||||
@@ -143,7 +238,7 @@ public class ConquestCollectionScreen extends TabPageScreen<ConquestCollectionSc
|
||||
FThreads.invokeInBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (model.retrieveCardFromExile(card, cost)) {
|
||||
if (model.retrieveCardsFromExile(ImmutableList.of(card), cost)) {
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -167,7 +262,7 @@ public class ConquestCollectionScreen extends TabPageScreen<ConquestCollectionSc
|
||||
FThreads.invokeInBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (model.exileCard(card, value)) {
|
||||
if (model.exileCards(ImmutableList.of(card), value)) {
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -187,6 +282,14 @@ public class ConquestCollectionScreen extends TabPageScreen<ConquestCollectionSc
|
||||
menu.addItem(item);
|
||||
}
|
||||
});
|
||||
setSelectionChangedHandler(new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
if (getMultiSelectMode()) {
|
||||
parentScreen.updateExileButtonCaption();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -199,8 +302,14 @@ public class ConquestCollectionScreen extends TabPageScreen<ConquestCollectionSc
|
||||
@Override
|
||||
protected void onCardLongPress(int index, Entry<PaperCard, Integer> value, float x, float y) {
|
||||
toggleMultiSelectMode(index);
|
||||
|
||||
//hide tabs and show Exile/Retrieve button while in multi-select mode
|
||||
boolean multiSelectMode = getMultiSelectMode();
|
||||
|
||||
if (multiSelectMode) {
|
||||
parentScreen.updateExileButtonCaption();
|
||||
}
|
||||
parentScreen.btnExileMultiple.setVisible(multiSelectMode);
|
||||
parentScreen.tabHeader.setVisible(!multiSelectMode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import forge.util.gui.SOptionPane;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -256,34 +257,51 @@ public final class ConquestData {
|
||||
return exiledCards;
|
||||
}
|
||||
|
||||
public boolean exileCard(PaperCard card, int value) {
|
||||
final String title = "Exile Card";
|
||||
if (planeswalker == card) {
|
||||
SOptionPane.showMessageDialog("Current planeswalker cannot be exiled.", title, SOptionPane.INFORMATION_ICON);
|
||||
return false;
|
||||
}
|
||||
String commandersUsingCard = "";
|
||||
ConquestCommander commanderBeingExiled = null;
|
||||
for (ConquestCommander commander : commanders) {
|
||||
if (commander.getCard() == card) {
|
||||
if (!commander.getDeck().getMain().isEmpty()) {
|
||||
SOptionPane.showMessageDialog("Cannot exile a commander with a defined deck.", title, SOptionPane.INFORMATION_ICON);
|
||||
return false;
|
||||
public boolean exileCards(Collection<PaperCard> cards, int value) {
|
||||
int count = cards.size();
|
||||
if (count == 0) { return false; }
|
||||
|
||||
String title = count == 1 ? "Exile Card" : "Exile " + count + " Cards";
|
||||
String cardStr = (count == 1 ? "card" : "cards");
|
||||
|
||||
List<ConquestCommander> commandersBeingExiled = null;
|
||||
|
||||
String message = "Exile the following " + cardStr + " to receive {AE}" + value + "?\n";
|
||||
for (PaperCard card : cards) {
|
||||
if (planeswalker == card) {
|
||||
SOptionPane.showMessageDialog("Current planeswalker cannot be exiled.", title, SOptionPane.INFORMATION_ICON);
|
||||
return false;
|
||||
}
|
||||
|
||||
String commandersUsingCard = "";
|
||||
for (ConquestCommander commander : commanders) {
|
||||
if (commander.getCard() == card) {
|
||||
if (!commander.getDeck().getMain().isEmpty()) {
|
||||
SOptionPane.showMessageDialog("Cannot exile a commander with a defined deck.", title, SOptionPane.INFORMATION_ICON);
|
||||
return false;
|
||||
}
|
||||
if (commandersBeingExiled == null) {
|
||||
commandersBeingExiled = new ArrayList<ConquestCommander>();
|
||||
}
|
||||
commandersBeingExiled.add(commander); //cache commander to make it easier to remove later
|
||||
}
|
||||
if (commander.getDeck().getMain().contains(card)) {
|
||||
commandersUsingCard += "\n" + commander.getName();
|
||||
}
|
||||
commanderBeingExiled = commander; //cache commander to make it easier to remove later
|
||||
}
|
||||
if (commander.getDeck().getMain().contains(card)) {
|
||||
commandersUsingCard += "\n" + commander.getName();
|
||||
|
||||
if (!commandersUsingCard.isEmpty()) {
|
||||
SOptionPane.showMessageDialog(card.getName() + " is in use by the following commanders and cannot be exiled:\n" + commandersUsingCard, title, SOptionPane.INFORMATION_ICON);
|
||||
return false;
|
||||
}
|
||||
|
||||
message += "\n" + card.getName();
|
||||
}
|
||||
if (!commandersUsingCard.isEmpty()) {
|
||||
SOptionPane.showMessageDialog("Card is in use by the following commanders and cannot be exiled:\n" + commandersUsingCard, title, SOptionPane.INFORMATION_ICON);
|
||||
return false;
|
||||
}
|
||||
if (SOptionPane.showConfirmDialog("Exile the following card to receive {AE}" + value + "?\n\n" + card.getName(), title, "OK", "Cancel")) {
|
||||
if (exiledCards.add(card)) {
|
||||
if (commanderBeingExiled != null) {
|
||||
commanders.remove(commanderBeingExiled);
|
||||
|
||||
if (SOptionPane.showConfirmDialog(message, title, "OK", "Cancel")) {
|
||||
if (exiledCards.addAll(cards)) {
|
||||
if (commandersBeingExiled != null) {
|
||||
commanders.removeAll(commandersBeingExiled);
|
||||
}
|
||||
rewardAEtherShards(value);
|
||||
saveData();
|
||||
@@ -293,16 +311,27 @@ public final class ConquestData {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean retrieveCardFromExile(PaperCard card, int cost) {
|
||||
final String title = "Retrieve Card";
|
||||
public boolean retrieveCardsFromExile(Collection<PaperCard> cards, int cost) {
|
||||
int count = cards.size();
|
||||
if (count == 0) { return false; }
|
||||
|
||||
String title = count == 1 ? "Retrieve Card" : "Retrieve " + count + " Cards";
|
||||
String cardStr = (count == 1 ? "card" : "cards");
|
||||
if (aetherShards < cost) {
|
||||
SOptionPane.showMessageDialog("Not enough shards to retrieve card.", title, SOptionPane.INFORMATION_ICON);
|
||||
SOptionPane.showMessageDialog("Not enough shards to retrieve " + cardStr + ".", title, SOptionPane.INFORMATION_ICON);
|
||||
return false;
|
||||
}
|
||||
if (SOptionPane.showConfirmDialog("Spend {AE}" + cost + " to retrieve the following card from exile?\n\n" + card.getName(), title, "OK", "Cancel")) {
|
||||
if (exiledCards.remove(card)) {
|
||||
if (card.getRules().canBeCommander()) { //add back commander for card if needed
|
||||
commanders.add(new ConquestCommander(card));
|
||||
|
||||
String message = "Spend {AE}" + cost + " to retrieve the following " + cardStr + " from exile?\n";
|
||||
for (PaperCard card : cards) {
|
||||
message += "\n" + card.getName();
|
||||
}
|
||||
if (SOptionPane.showConfirmDialog(message, title, "OK", "Cancel")) {
|
||||
if (exiledCards.removeAll(cards)) {
|
||||
for (PaperCard card : cards) {
|
||||
if (card.getRules().canBeCommander()) { //add back commander for card if needed
|
||||
commanders.add(new ConquestCommander(card));
|
||||
}
|
||||
}
|
||||
spendAEtherShards(cost);
|
||||
saveData();
|
||||
|
||||
Reference in New Issue
Block a user