mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Refactor some spell shop logic to make it more reusable from mobile game
This commit is contained in:
@@ -53,6 +53,7 @@ public interface IGuiBase {
|
||||
String showFileDialog(String title, String defaultDir);
|
||||
File getSaveFile(File defaultFile);
|
||||
void showCardList(final String title, final String message, final List<PaperCard> list);
|
||||
boolean showBoxedProduct(final String title, final String message, final List<PaperCard> list);
|
||||
void fireEvent(UiEvent e);
|
||||
void setCard(Card card);
|
||||
void showCombat(Combat combat);
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
347
forge-gui/src/main/java/forge/quest/QuestSpellShop.java
Normal file
347
forge-gui/src/main/java/forge/quest/QuestSpellShop.java
Normal file
@@ -0,0 +1,347 @@
|
||||
package forge.quest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.item.BoosterBox;
|
||||
import forge.item.BoosterPack;
|
||||
import forge.item.BoxedProduct;
|
||||
import forge.item.FatPack;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.PreconDeck;
|
||||
import forge.item.SealedProduct;
|
||||
import forge.item.TournamentPack;
|
||||
import forge.itemmanager.IItemManager;
|
||||
import forge.itemmanager.SItemManagerUtil;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.quest.io.ReadPriceList;
|
||||
import forge.util.ItemPool;
|
||||
import forge.util.gui.SOptionPane;
|
||||
|
||||
public class QuestSpellShop {
|
||||
private static final ReadPriceList r = new ReadPriceList();
|
||||
private static final Map<String, Integer> mapPrices = r.getPriceList();
|
||||
private static double multiplier;
|
||||
private static ItemPool<InventoryItem> decksUsingMyCards;
|
||||
|
||||
public static Integer getCardValue(final InventoryItem card) {
|
||||
String ns = null;
|
||||
int value = 1337; // previously this was the returned default
|
||||
boolean foil = false;
|
||||
int foilMultiplier = 1;
|
||||
|
||||
if (card instanceof PaperCard) {
|
||||
ns = card.getName() + "|" + ((PaperCard) card).getEdition();
|
||||
foil = ((PaperCard) card).isFoil();
|
||||
} else {
|
||||
ns = card.getName();
|
||||
}
|
||||
|
||||
if (mapPrices.containsKey(ns)) {
|
||||
value = mapPrices.get(ns);
|
||||
} else if (card instanceof PaperCard) {
|
||||
switch (((IPaperCard) card).getRarity()) {
|
||||
case BasicLand:
|
||||
value = 4;
|
||||
break;
|
||||
case Common:
|
||||
value = 6;
|
||||
break;
|
||||
case Uncommon:
|
||||
value = 40;
|
||||
break;
|
||||
case Rare:
|
||||
value = 120;
|
||||
break;
|
||||
case MythicRare:
|
||||
value = 600;
|
||||
break;
|
||||
default:
|
||||
value = 15;
|
||||
break;
|
||||
}
|
||||
} else if (card instanceof BoosterPack) {
|
||||
value = 395;
|
||||
} else if (card instanceof TournamentPack) {
|
||||
value = 995;
|
||||
} else if (card instanceof FatPack) {
|
||||
value = 2365;
|
||||
} else if (card instanceof BoosterBox) {
|
||||
value = 8750;
|
||||
} else if (card instanceof PreconDeck) {
|
||||
value = QuestController.getPreconDeals((PreconDeck) card).getCost();
|
||||
}
|
||||
|
||||
// TODO: make this changeable via a user-definable property?
|
||||
if (foil) {
|
||||
switch (((IPaperCard) card).getRarity()) {
|
||||
case BasicLand:
|
||||
foilMultiplier = 2;
|
||||
break;
|
||||
case Common:
|
||||
foilMultiplier = 2;
|
||||
break;
|
||||
case Uncommon:
|
||||
foilMultiplier = 2;
|
||||
break;
|
||||
case Rare:
|
||||
foilMultiplier = 3;
|
||||
break;
|
||||
case MythicRare:
|
||||
foilMultiplier = 3;
|
||||
break;
|
||||
default:
|
||||
foilMultiplier = 2;
|
||||
break;
|
||||
}
|
||||
value *= foilMultiplier;
|
||||
}
|
||||
|
||||
return Integer.valueOf(value);
|
||||
}
|
||||
|
||||
public static final Function<Entry<InventoryItem, Integer>, Comparable<?>> fnPriceCompare = new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
|
||||
@Override
|
||||
public Comparable<?> apply(final Entry<InventoryItem, Integer> from) {
|
||||
return getCardValue(from.getKey());
|
||||
}
|
||||
};
|
||||
public static final Function<Entry<? extends InventoryItem, Integer>, Object> fnPriceGet = new Function<Entry<? extends InventoryItem, Integer>, Object>() {
|
||||
@Override
|
||||
public Object apply(final Entry<? extends InventoryItem, Integer> from) {
|
||||
return getCardValue(from.getKey());
|
||||
}
|
||||
};
|
||||
public static final Function<Entry<? extends InventoryItem, Integer>, Object> fnPriceSellGet = new Function<Entry<? extends InventoryItem, Integer>, Object>() {
|
||||
@Override
|
||||
public Object apply(final Entry<? extends InventoryItem, Integer> from) {
|
||||
return (int) (multiplier * getCardValue(from.getKey()));
|
||||
}
|
||||
};
|
||||
public static final Function<Entry<InventoryItem, Integer>, Comparable<?>> fnDeckCompare = new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
|
||||
@Override
|
||||
public Comparable<?> apply(final Entry<InventoryItem, Integer> from) {
|
||||
final Integer iValue = decksUsingMyCards.count(from.getKey());
|
||||
return iValue == null ? Integer.valueOf(0) : iValue;
|
||||
}
|
||||
};
|
||||
public static final Function<Entry<? extends InventoryItem, Integer>, Object> fnDeckGet = new Function<Entry<? extends InventoryItem, Integer>, Object>() {
|
||||
@Override
|
||||
public Object apply(final Entry<? extends InventoryItem, Integer> from) {
|
||||
final Integer iValue = decksUsingMyCards.count(from.getKey());
|
||||
return iValue == null ? "" : iValue.toString();
|
||||
}
|
||||
};
|
||||
|
||||
public static void buy(Iterable<Entry<InventoryItem, Integer>> items, IItemManager<InventoryItem> shopManager, IItemManager<InventoryItem> inventoryManager, boolean confirmPurchase) {
|
||||
long totalCost = 0;
|
||||
ItemPool<InventoryItem> itemsToBuy = new ItemPool<InventoryItem>(InventoryItem.class);
|
||||
for (Entry<InventoryItem, Integer> itemEntry : items) {
|
||||
final InventoryItem item = itemEntry.getKey();
|
||||
if (item instanceof PaperCard || item instanceof SealedProduct || item instanceof PreconDeck) {
|
||||
final int qty = itemEntry.getValue();
|
||||
itemsToBuy.add(item, qty);
|
||||
totalCost += qty * QuestSpellShop.getCardValue(item);
|
||||
}
|
||||
}
|
||||
if (itemsToBuy.isEmpty()) { return; }
|
||||
|
||||
List<InventoryItem> itemFlatList = itemsToBuy.toFlatList();
|
||||
String suffix = SItemManagerUtil.getItemDisplayString(itemFlatList, 1, true);
|
||||
String displayList = SItemManagerUtil.buildDisplayList(itemsToBuy);
|
||||
String title = "Buy " + suffix;
|
||||
|
||||
long creditsShort = totalCost - FModel.getQuest().getAssets().getCredits();
|
||||
if (creditsShort > 0) {
|
||||
SOptionPane.showMessageDialog("You need " + creditsShort + " more credits to purchase the following " + suffix.toLowerCase() + ".\n" + displayList, title);
|
||||
return;
|
||||
}
|
||||
|
||||
if (confirmPurchase && !SOptionPane.showConfirmDialog("Pay " + totalCost + " credits to purchase the following " +
|
||||
suffix.toLowerCase() + "?\n" + displayList, title, "Buy", "Cancel")) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemPool<InventoryItem> itemsToAdd = new ItemPool<InventoryItem>(InventoryItem.class);
|
||||
|
||||
for (Entry<InventoryItem, Integer> itemEntry : itemsToBuy) {
|
||||
final InventoryItem item = itemEntry.getKey();
|
||||
|
||||
final int qty = itemEntry.getValue();
|
||||
final int value = QuestSpellShop.getCardValue(item);
|
||||
|
||||
if (item instanceof PaperCard) {
|
||||
FModel.getQuest().getCards().buyCard((PaperCard) item, qty, value);
|
||||
itemsToAdd.add(item, qty);
|
||||
}
|
||||
else if (item instanceof SealedProduct) {
|
||||
for (int i = 0; i < qty; i++) {
|
||||
SealedProduct booster = null;
|
||||
if (item instanceof BoosterPack) {
|
||||
booster = (BoosterPack) ((BoosterPack) item).clone();
|
||||
}
|
||||
else if (item instanceof TournamentPack) {
|
||||
booster = (TournamentPack) ((TournamentPack) item).clone();
|
||||
}
|
||||
else if (item instanceof FatPack) {
|
||||
booster = (FatPack) ((FatPack) item).clone();
|
||||
}
|
||||
else if (item instanceof BoosterBox) {
|
||||
booster = (BoosterBox) ((BoosterBox) item).clone();
|
||||
}
|
||||
FModel.getQuest().getCards().buyPack(booster, value);
|
||||
final List<PaperCard> newCards = booster.getCards();
|
||||
|
||||
itemsToAdd.addAllFlat(newCards);
|
||||
|
||||
if (booster instanceof BoxedProduct && FModel.getPreferences().getPrefBoolean(FPref.UI_OPEN_PACKS_INDIV)) {
|
||||
|
||||
int totalPacks = ((BoxedProduct) booster).boosterPacksRemaining();
|
||||
boolean skipTheRest = false;
|
||||
final List<PaperCard> remainingCards = new ArrayList<>();
|
||||
|
||||
while (((BoxedProduct) booster).boosterPacksRemaining() > 0 && !skipTheRest) {
|
||||
skipTheRest = GuiBase.getInterface().showBoxedProduct(booster.getName(), "You have found the following cards inside (Booster Pack " + (totalPacks - ((BoxedProduct) booster).boosterPacksRemaining() + 1) + " of " + totalPacks + "):", ((BoxedProduct) booster).getNextBoosterPack());
|
||||
}
|
||||
|
||||
if (skipTheRest) {
|
||||
while (((BoxedProduct) booster).boosterPacksRemaining() > 0) {
|
||||
remainingCards.addAll(((BoxedProduct) booster).getNextBoosterPack());
|
||||
}
|
||||
}
|
||||
|
||||
remainingCards.addAll(((BoxedProduct) booster).getExtraCards());
|
||||
|
||||
if (remainingCards.size() > 0) {
|
||||
GuiBase.getInterface().showCardList(booster.getName(), "You have found the following cards inside:", remainingCards);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
GuiBase.getInterface().showCardList(booster.getName(), "You have found the following cards inside:", newCards);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (item instanceof PreconDeck) {
|
||||
final PreconDeck deck = (PreconDeck) item;
|
||||
for (int i = 0; i < qty; i++) {
|
||||
FModel.getQuest().getCards().buyPreconDeck(deck, value);
|
||||
|
||||
itemsToAdd.addAll(deck.getDeck().getMain());
|
||||
}
|
||||
|
||||
boolean one = (qty == 1);
|
||||
SOptionPane.showMessageDialog(String.format(
|
||||
"%s '%s' %s added to your decklist.%n%n%s cards were also added to your pool.",
|
||||
one ? "Deck" : String.format("%d copies of deck", qty),
|
||||
deck.getName(), one ? "was" : "were", one ? "Its" : "Their"),
|
||||
"Thanks for purchasing!", SOptionPane.INFORMATION_ICON);
|
||||
}
|
||||
}
|
||||
|
||||
inventoryManager.addItems(itemsToAdd);
|
||||
shopManager.removeItems(itemsToBuy);
|
||||
}
|
||||
|
||||
public static void sell(Iterable<Entry<InventoryItem, Integer>> items, IItemManager<InventoryItem> shopManager, IItemManager<InventoryItem> inventoryManager, boolean confirmSale) {
|
||||
long totalReceived = 0;
|
||||
ItemPool<InventoryItem> itemsToSell = new ItemPool<InventoryItem>(InventoryItem.class);
|
||||
for (Entry<InventoryItem, Integer> itemEntry : items) {
|
||||
final InventoryItem item = itemEntry.getKey();
|
||||
if (item instanceof PaperCard) {
|
||||
final int qty = itemEntry.getValue();
|
||||
itemsToSell.add(item, qty);
|
||||
totalReceived += qty * Math.min((int) (multiplier * getCardValue(item)), FModel.getQuest().getCards().getSellPriceLimit());
|
||||
}
|
||||
}
|
||||
if (itemsToSell.isEmpty()) { return; }
|
||||
|
||||
if (confirmSale) {
|
||||
List<InventoryItem> itemFlatList = itemsToSell.toFlatList();
|
||||
String suffix = SItemManagerUtil.getItemDisplayString(itemFlatList, 1, true);
|
||||
String displayList = SItemManagerUtil.buildDisplayList(itemsToSell);
|
||||
String title = "Sell " + suffix;
|
||||
|
||||
if (!SOptionPane.showConfirmDialog("Sell the following " + suffix.toLowerCase() + " for " + totalReceived +
|
||||
" credit" + (totalReceived != 1 ? "s" : "") + "?\n" + displayList, title, "Sell", "Cancel")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<InventoryItem, Integer> itemEntry : itemsToSell) {
|
||||
final PaperCard card = (PaperCard) itemEntry.getKey();
|
||||
final int qty = itemEntry.getValue();
|
||||
final int price = Math.min((int) (multiplier * getCardValue(card)), FModel.getQuest().getCards().getSellPriceLimit());
|
||||
|
||||
FModel.getQuest().getCards().sellCard(card, qty, price);
|
||||
}
|
||||
|
||||
shopManager.addItems(itemsToSell);
|
||||
inventoryManager.removeItems(itemsToSell);
|
||||
}
|
||||
|
||||
public static void sellExtras(IItemManager<InventoryItem> shopManager, IItemManager<InventoryItem> inventoryManager) {
|
||||
List<Entry<InventoryItem, Integer>> cardsToRemove = new LinkedList<Map.Entry<InventoryItem,Integer>>();
|
||||
for (Entry<InventoryItem, Integer> item : inventoryManager.getPool()) {
|
||||
PaperCard card = (PaperCard)item.getKey();
|
||||
int numToKeep = card.getRules().getType().isBasic() ? 50 : 4;
|
||||
if ("Relentless Rats".equals(card.getName())) {
|
||||
numToKeep = Integer.MAX_VALUE;
|
||||
}
|
||||
if (numToKeep < item.getValue()) {
|
||||
cardsToRemove.add(Pair.of(item.getKey(), item.getValue() - numToKeep));
|
||||
}
|
||||
}
|
||||
|
||||
shopManager.addItems(cardsToRemove);
|
||||
inventoryManager.removeItems(cardsToRemove);
|
||||
|
||||
for (Entry<InventoryItem, Integer> item : cardsToRemove) {
|
||||
if (!(item.getKey() instanceof PaperCard)) {
|
||||
continue;
|
||||
}
|
||||
PaperCard card = (PaperCard)item.getKey();
|
||||
final int price = Math.min((int) (multiplier * getCardValue(card)),
|
||||
FModel.getQuest().getCards().getSellPriceLimit());
|
||||
FModel.getQuest().getCards().sellCard(card, item.getValue(), price);
|
||||
}
|
||||
}
|
||||
|
||||
// fills number of decks using each card
|
||||
public static void updateDecksForEachCard() {
|
||||
decksUsingMyCards = new ItemPool<InventoryItem>(InventoryItem.class);
|
||||
for (final Deck deck : FModel.getQuest().getMyDecks()) {
|
||||
CardPool main = deck.getMain();
|
||||
for (final Entry<PaperCard, Integer> e : main) {
|
||||
decksUsingMyCards.add(e.getKey());
|
||||
}
|
||||
if (deck.has(DeckSection.Sideboard)) {
|
||||
for (final Entry<PaperCard, Integer> e : deck.get(DeckSection.Sideboard)) {
|
||||
// only add card if we haven't already encountered it in main
|
||||
if (!main.contains(e.getKey())) {
|
||||
decksUsingMyCards.add(e.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static double updateMultiplier() {
|
||||
multiplier = FModel.getQuest().getCards().getSellMultiplier();
|
||||
return multiplier;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user