Refactor some spell shop logic to make it more reusable from mobile game

This commit is contained in:
drdev
2014-07-15 04:13:46 +00:00
parent 34dfbf1098
commit 6afe46792c
10 changed files with 502 additions and 389 deletions

View File

@@ -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);

View File

@@ -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;

View 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;
}
}