Create new booster structure so cards that aren't new are converted to an appropriate number of credits

This commit is contained in:
drdev
2015-12-08 04:15:09 +00:00
parent 64bc5e0484
commit 53eb31cfba
4 changed files with 85 additions and 345 deletions

View File

@@ -52,10 +52,6 @@ public class ConquestPrefsScreen extends FScreen {
scroller.add(new PrefsOption("Commons", CQPref.BOOSTER_COMMONS, PrefsGroup.BOOSTER)); scroller.add(new PrefsOption("Commons", CQPref.BOOSTER_COMMONS, PrefsGroup.BOOSTER));
scroller.add(new PrefsOption("Uncommons", CQPref.BOOSTER_UNCOMMONS, PrefsGroup.BOOSTER)); scroller.add(new PrefsOption("Uncommons", CQPref.BOOSTER_UNCOMMONS, PrefsGroup.BOOSTER));
scroller.add(new PrefsOption("Rares", CQPref.BOOSTER_RARES, PrefsGroup.BOOSTER)); scroller.add(new PrefsOption("Rares", CQPref.BOOSTER_RARES, PrefsGroup.BOOSTER));
scroller.add(new PrefsOption("Common Reroll Duplicate (%)", CQPref.BOOSTER_COMMON_REROLL, PrefsGroup.BOOSTER));
scroller.add(new PrefsOption("Uncommon Reroll Duplicate (%)", CQPref.BOOSTER_UNCOMMON_REROLL, PrefsGroup.BOOSTER));
scroller.add(new PrefsOption("Rare Reroll Duplicate (%)", CQPref.BOOSTER_RARE_REROLL, PrefsGroup.BOOSTER));
scroller.add(new PrefsOption("Mythic Reroll Duplicate (%)", CQPref.BOOSTER_MYTHIC_REROLL, PrefsGroup.BOOSTER));
} }
@Override @Override

View File

@@ -20,17 +20,12 @@ package forge.planarconquest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import forge.FThreads; import forge.FThreads;
import forge.GuiBase; import forge.GuiBase;
import forge.LobbyPlayer; import forge.LobbyPlayer;
import forge.card.CardRarity; import forge.assets.FSkinProp;
import forge.card.CardRules;
import forge.card.CardType; import forge.card.CardType;
import forge.deck.Deck; import forge.deck.Deck;
import forge.game.GameRules; import forge.game.GameRules;
@@ -48,9 +43,6 @@ import forge.player.LobbyPlayerHuman;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.quest.BoosterUtils; import forge.quest.BoosterUtils;
import forge.util.Aggregates; import forge.util.Aggregates;
import forge.util.Lang;
import forge.util.gui.SGuiChoose;
import forge.util.gui.SOptionPane;
import forge.util.storage.IStorage; import forge.util.storage.IStorage;
public class ConquestController { public class ConquestController {
@@ -218,20 +210,6 @@ public class ConquestController {
} }
} }
/*private boolean recruit(ConquestCommander commander) {
boolean bonusCard = Aggregates.randomInt(1, 100) <= FModel.getConquestPreferences().getPrefInt(CQPref.RECRUIT_BONUS_CARD_ODDS);
return awardNewCards(model.getCurrentPlane().getCardPool().getAllCards(),
commander.getName() + " recruited", "new creature", null, null,
CardRulesPredicates.Presets.IS_CREATURE, bonusCard ? 2 : 1);
}
private boolean study(ConquestCommander commander) {
boolean bonusCard = Aggregates.randomInt(1, 100) <= FModel.getConquestPreferences().getPrefInt(CQPref.STUDY_BONUS_CARD_ODDS);
return awardNewCards(model.getCurrentPlane().getCardPool().getAllCards(),
commander.getName() + " unlocked", "new spell", null, null,
CardRulesPredicates.Presets.IS_NON_CREATURE_SPELL, bonusCard ? 2 : 1);
}*/
public void showGameRewards(final GameView game, final IWinLoseView<? extends IButton> view) { public void showGameRewards(final GameView game, final IWinLoseView<? extends IButton> view) {
if (game.isMatchWonBy(humanPlayer)) { if (game.isMatchWonBy(humanPlayer)) {
view.getBtnQuit().setText("Great!"); view.getBtnQuit().setText("Great!");
@@ -240,19 +218,7 @@ public class ConquestController {
view.showRewards(new Runnable() { view.showRewards(new Runnable() {
@Override @Override
public void run() { public void run() {
final List<String> options = ImmutableList.of("Booster", "Card"); awardBooster(view);
if (SOptionPane.showOptionDialog("Choose one \u2014\n\n" +
"\u2022 Open a random booster pack\n" +
"\u2022 Choose a card from your opponent's deck",
"Spoils of Victory", null, options) == 0) {
awardBooster(view);
}
else {
if (!awardOpponentsCard(view)) {
SOptionPane.showMessageDialog("Opponent had no new cards, so you can open a random booster pack instead.");
awardBooster(view);
}
}
} }
}); });
} }
@@ -275,193 +241,15 @@ public class ConquestController {
gameRunner.finish(); gameRunner.finish();
} }
private boolean awardNewCards(Iterable<PaperCard> cardPool, String messagePrefix, String messageSuffix, CardRarity rarity, final IWinLoseView<? extends IButton> view, Predicate<CardRules> pred, int count) {
List<PaperCard> commons = new ArrayList<PaperCard>();
List<PaperCard> uncommons = new ArrayList<PaperCard>();
List<PaperCard> rares = new ArrayList<PaperCard>();
List<PaperCard> mythics = new ArrayList<PaperCard>();
int newCardCount = 0;
for (PaperCard c : cardPool) {
if ((pred == null || pred.apply(c.getRules())) && !model.hasUnlockedCard(c)) {
switch (c.getRarity()) {
case Common:
commons.add(c);
break;
case Uncommon:
uncommons.add(c);
break;
case Rare:
rares.add(c);
break;
case MythicRare:
mythics.add(c);
break;
default:
break;
}
}
}
newCardCount = commons.size() + uncommons.size() + rares.size() + mythics.size();
if (newCardCount == 0) {
return false;
}
List<PaperCard> rewardPool = null;
if (rarity != null) {
switch (rarity) {
case Common:
rewardPool = commons;
if (rewardPool.isEmpty()) {
rewardPool = uncommons;
messageSuffix = messageSuffix.replace("common", "uncommon");
if (rewardPool.isEmpty()) {
rewardPool = rares;
messageSuffix = messageSuffix.replace("uncommon", "rare");
if (rewardPool.isEmpty()) {
rewardPool = mythics;
messageSuffix = messageSuffix.replace("rare", "mythic rare");
}
}
}
break;
case Uncommon:
rewardPool = uncommons;
if (rewardPool.isEmpty()) {
rewardPool = commons;
messageSuffix = messageSuffix.replace("uncommon", "common");
if (rewardPool.isEmpty()) {
rewardPool = rares;
messageSuffix = messageSuffix.replace("common", "rare");
if (rewardPool.isEmpty()) {
rewardPool = mythics;
messageSuffix = messageSuffix.replace("rare", "mythic rare");
}
}
}
break;
case Rare:
rewardPool = rares;
if (rewardPool.isEmpty()) {
rewardPool = uncommons;
messageSuffix = messageSuffix.replace("rare", "uncommon");
if (rewardPool.isEmpty()) {
rewardPool = commons;
messageSuffix = messageSuffix.replace("uncommon", "common");
if (rewardPool.isEmpty()) {
rewardPool = mythics;
messageSuffix = messageSuffix.replace("common", "mythic rare");
}
}
}
break;
case MythicRare:
rewardPool = mythics;
if (rewardPool.isEmpty()) {
rewardPool = rares;
messageSuffix = messageSuffix.replace("mythic rare", "rare");
if (rewardPool.isEmpty()) {
rewardPool = uncommons;
messageSuffix = messageSuffix.replace("rare", "uncommon");
if (rewardPool.isEmpty()) {
rewardPool = commons;
messageSuffix = messageSuffix.replace("uncommon", "common");
}
}
}
break;
default:
return false;
}
newCardCount = rewardPool.size();
}
List<PaperCard> rewards = new ArrayList<PaperCard>();
for (int i = 0; i < count; i++) {
//determine which rarity card to get based on pack ratios if no rarity passed in
if (rarity == null) {
int value = Aggregates.randomInt(1, 15);
if (value <= 8) { //reward common about 50% of the time
rewardPool = commons;
if (rewardPool.isEmpty()) {
rewardPool = uncommons;
if (rewardPool.isEmpty()) {
rewardPool = rares;
if (rewardPool.isEmpty()) {
rewardPool = mythics;
}
}
}
}
else if (value <= 12) { //reward uncommon about 25% of the time
rewardPool = uncommons;
if (rewardPool.isEmpty()) {
rewardPool = commons;
if (rewardPool.isEmpty()) {
rewardPool = rares;
if (rewardPool.isEmpty()) {
rewardPool = mythics;
}
}
}
}
else if (value <= 14) { //reward rare about 12.5% of the time
rewardPool = rares;
if (rewardPool.isEmpty()) {
rewardPool = uncommons;
if (rewardPool.isEmpty()) {
rewardPool = commons;
if (rewardPool.isEmpty()) {
rewardPool = mythics;
}
}
}
}
else { //reward mythic about 6.75% of the time
rewardPool = mythics;
if (rewardPool.isEmpty()) {
rewardPool = rares;
if (rewardPool.isEmpty()) {
rewardPool = uncommons;
if (rewardPool.isEmpty()) {
rewardPool = commons;
}
}
}
}
}
int index = Aggregates.randomInt(0, rewardPool.size() - 1);
rewards.add(rewardPool.remove(index));
if (--newCardCount == 0) {
break; //break out if no new cards remain
}
}
model.unlockCards(rewards);
String message = messagePrefix;
if (messageSuffix != null) {
message += " " + Lang.nounWithAmount(rewards.size(), messageSuffix);
}
if (view == null) {
SGuiChoose.reveal(message, rewards);
}
else {
view.showCards(message, rewards);
}
return true;
}
private void awardBooster(final IWinLoseView<? extends IButton> view) { private void awardBooster(final IWinLoseView<? extends IButton> view) {
Iterable<PaperCard> cardPool = model.getCurrentPlane().getCardPool().getAllCards(); Iterable<PaperCard> cardPool = model.getCurrentPlane().getCardPool().getAllCards();
ConquestPreferences prefs = FModel.getConquestPreferences(); ConquestPreferences prefs = FModel.getConquestPreferences();
BoosterPool commons = new BoosterPool(prefs.getPrefInt(CQPref.BOOSTER_COMMON_REROLL)); BoosterPool commons = new BoosterPool();
BoosterPool uncommons = new BoosterPool(prefs.getPrefInt(CQPref.BOOSTER_UNCOMMON_REROLL)); BoosterPool uncommons = new BoosterPool();
BoosterPool rares = new BoosterPool(prefs.getPrefInt(CQPref.BOOSTER_RARE_REROLL)); BoosterPool rares = new BoosterPool();
BoosterPool mythics = new BoosterPool(prefs.getPrefInt(CQPref.BOOSTER_MYTHIC_REROLL)); BoosterPool mythics = new BoosterPool();
for (PaperCard c : cardPool) { for (PaperCard c : cardPool) {
switch (c.getRarity()) { switch (c.getRarity()) {
@@ -472,6 +260,7 @@ public class ConquestController {
uncommons.add(c); uncommons.add(c);
break; break;
case Rare: case Rare:
case Special: //lump special cards in with rares for simplicity
rares.add(c); rares.add(c);
break; break;
case MythicRare: case MythicRare:
@@ -484,8 +273,8 @@ public class ConquestController {
List<PaperCard> rewards = new ArrayList<PaperCard>(); List<PaperCard> rewards = new ArrayList<PaperCard>();
int boostersPerMythic = prefs.getPrefInt(CQPref.BOOSTERS_PER_MYTHIC); int boostersPerMythic = prefs.getPrefInt(CQPref.BOOSTERS_PER_MYTHIC);
int count = prefs.getPrefInt(CQPref.BOOSTER_RARES); int raresPerBooster = prefs.getPrefInt(CQPref.BOOSTER_RARES);
for (int i = 0; i < count; i++) { for (int i = 0; i < raresPerBooster; i++) {
if (mythics.isEmpty() || Aggregates.randomInt(1, boostersPerMythic) > 1) { if (mythics.isEmpty() || Aggregates.randomInt(1, boostersPerMythic) > 1) {
rares.rewardCard(rewards); rares.rewardCard(rewards);
} }
@@ -494,86 +283,97 @@ public class ConquestController {
} }
} }
count = prefs.getPrefInt(CQPref.BOOSTER_UNCOMMONS); int uncommonsPerBooster = prefs.getPrefInt(CQPref.BOOSTER_UNCOMMONS);
for (int i = 0; i < count; i++) { for (int i = 0; i < uncommonsPerBooster; i++) {
uncommons.rewardCard(rewards); uncommons.rewardCard(rewards);
} }
count = prefs.getPrefInt(CQPref.BOOSTER_COMMONS); int commonsPerBooster = prefs.getPrefInt(CQPref.BOOSTER_COMMONS);
for (int i = 0; i < count; i++) { for (int i = 0; i < commonsPerBooster; i++) {
commons.rewardCard(rewards); commons.rewardCard(rewards);
} }
count = rewards.size(); //calculate odds of each rarity
if (count == 0) { float commonOdds = commons.getOdds(commonsPerBooster);
//if no new cards in booster, pretend it contained a random card float uncommonOdds = uncommons.getOdds(uncommonsPerBooster);
awardNewCards(cardPool, "Booster contained ", "new card", null, view, null, 1); float rareOdds = rares.getOdds(raresPerBooster);
return; float mythicOdds = mythics.getOdds(raresPerBooster / boostersPerMythic);
}
BoosterUtils.sort(rewards); //determine value of each rarity based on the base value of a common
model.unlockCards(rewards); int commonValue = prefs.getPrefInt(CQPref.CARD_BASE_VALUE);
view.showCards("Booster contained " + count + " new card" + (count != 1 ? "s" : ""), rewards); int uncommonValue = Math.round(commonValue / (uncommonOdds / commonOdds));
} int rareValue = Math.round(commonValue / (rareOdds / commonOdds));
int mythicValue = mythics.isEmpty() ? 0 : Math.round(commonValue / (mythicOdds / commonOdds));
private boolean awardOpponentsCard(IWinLoseView<? extends IButton> view) { //remove any already unlocked cards from booster, calculating credit to reward instead
List<PaperCard> cards = new ArrayList<PaperCard>(); int credits = 0;
for (Entry<PaperCard, Integer> entry : gameRunner.event.getOpponentDeck().getMain()) { int count = rewards.size();
PaperCard c = entry.getKey(); for (int i = 0; i < count; i++) {
if (!c.getRules().getType().isBasicLand() && !getModel().hasUnlockedCard(c)) { PaperCard card = rewards.get(i);
cards.add(c); if (model.hasUnlockedCard(card)) {
rewards.remove(i);
i--;
count--;
switch (card.getRarity()) {
case Common:
credits += commonValue;
break;
case Uncommon:
credits += uncommonValue;
break;
case Rare:
case Special:
credits += rareValue;
break;
case MythicRare:
credits += mythicValue;
break;
default:
break;
}
} }
} }
if (cards.isEmpty()) { return false; } if (count > 0) {
BoosterUtils.sort(rewards);
BoosterUtils.sort(cards); view.showCards("Booster contained " + count + " new card" + (count != 1 ? "s" : ""), rewards);
PaperCard card = SGuiChoose.one("Choose a card from your opponent's deck", cards); if (credits > 0) {
model.unlockCard(card); view.showMessage("Remaining cards exchanged for " + credits + " credits.", "Received Credits", FSkinProp.ICO_QUEST_COIN);
return true; model.rewardCredits(credits);
}
model.unlockCards(rewards);
}
else {
view.showMessage("Booster contained no cards, so it has been exchanged for " + credits + " credits.", "Received Credits", FSkinProp.ICO_QUEST_COIN);
model.rewardCredits(credits);
}
} }
private class BoosterPool { private class BoosterPool {
private final int rerollChance;
private int newCount = 0;
private final List<PaperCard> cards = new ArrayList<PaperCard>(); private final List<PaperCard> cards = new ArrayList<PaperCard>();
private BoosterPool(int rerollChance0) { private BoosterPool() {
rerollChance = rerollChance0;
} }
private boolean isEmpty() { private boolean isEmpty() {
return cards.isEmpty(); return cards.isEmpty();
} }
public float getOdds(float perBoosterCount) {
int count = cards.size();
if (count == 0) { return 0; }
return (float)perBoosterCount / (float)count;
}
private void add(PaperCard c) { private void add(PaperCard c) {
if (!model.hasUnlockedCard(c)) {
newCount++;
}
cards.add(c); cards.add(c);
} }
private void rewardCard(List<PaperCard> rewards) { private void rewardCard(List<PaperCard> rewards) {
if (newCount == 0) { int index = Aggregates.randomInt(0, cards.size() - 1);
return; PaperCard c = cards.get(index);
} cards.remove(index);
rewards.add(c);
PaperCard c;
while (true) {
int index = Aggregates.randomInt(0, cards.size() - 1);
c = cards.get(index);
if (!model.hasUnlockedCard(c)) {
newCount--;
cards.remove(c);
rewards.add(c);
return; //return if new
}
if (Aggregates.randomInt(1, 100) > rerollChance) {
return; //return if reroll chance fails
}
}
} }
} }
} }

View File

@@ -179,6 +179,16 @@ public final class ConquestData {
public int getCredits() { public int getCredits() {
return credits; return credits;
} }
public void rewardCredits(int credits0) {
credits += credits0;
}
public boolean deductCredits(int credits0) {
if (credits >= credits0) {
credits -= credits0;
return true;
}
return false;
}
public String getProgress() { public String getProgress() {
int conquered = 0; int conquered = 0;

View File

@@ -33,10 +33,8 @@ public class ConquestPreferences extends PreferencesStore<ConquestPreferences.CQ
BOOSTER_UNCOMMONS("3"), BOOSTER_UNCOMMONS("3"),
BOOSTER_RARES("1"), BOOSTER_RARES("1"),
BOOSTERS_PER_MYTHIC("8"), BOOSTERS_PER_MYTHIC("8"),
BOOSTER_COMMON_REROLL("10"),
BOOSTER_UNCOMMON_REROLL("25"), CARD_BASE_VALUE("100");
BOOSTER_RARE_REROLL("50"),
BOOSTER_MYTHIC_REROLL("100");
private final String strDefaultVal; private final String strDefaultVal;
@@ -49,9 +47,6 @@ public class ConquestPreferences extends PreferencesStore<ConquestPreferences.CQ
} }
} }
public static enum DifficultyPrefs {
}
public ConquestPreferences() { public ConquestPreferences() {
super(ForgeConstants.CONQUEST_PREFS_FILE, CQPref.class); super(ForgeConstants.CONQUEST_PREFS_FILE, CQPref.class);
} }
@@ -73,59 +68,6 @@ public class ConquestPreferences extends PreferencesStore<ConquestPreferences.CQ
return key.getDefault(); return key.getDefault();
} }
public String getPref(DifficultyPrefs pref, int difficultyIndex) {
String newCQPref = pref.toString();
switch (difficultyIndex) {
case 0:
newCQPref += "_EASY";
break;
case 1:
newCQPref += "_MEDIUM";
break;
case 2:
newCQPref += "_HARD";
break;
case 3:
newCQPref += "_EXPERT";
break;
default:
try {
throw new Exception();
} catch (final Exception e1) {
System.err.println("Difficulty index out of bounds: " + difficultyIndex);
e1.printStackTrace();
}
}
return getPref(CQPref.valueOf(newCQPref));
}
public int getPrefInt(DifficultyPrefs pref, int difficultyIndex) {
return Integer.parseInt(this.getPref(pref, difficultyIndex));
}
public static String getDifficulty(int difficultyIndex) {
String s;
switch (difficultyIndex) {
case 1:
s = "EASY";
break;
case 2:
s = "MEDIUM";
break;
case 3:
s = "HARD";
break;
case 4:
s = "EXPERT";
break;
default:
s = "UNKNOWN";
}
return s;
}
public String validatePreference(CQPref qpref, int val) { public String validatePreference(CQPref qpref, int val) {
switch (qpref) { switch (qpref) {
case BOOSTER_COMMONS: case BOOSTER_COMMONS:
@@ -148,14 +90,6 @@ public class ConquestPreferences extends PreferencesStore<ConquestPreferences.CQ
return "Booster packs must have maximum 15 cards."; return "Booster packs must have maximum 15 cards.";
} }
break; break;
case BOOSTER_COMMON_REROLL:
case BOOSTER_UNCOMMON_REROLL:
case BOOSTER_RARE_REROLL:
case BOOSTER_MYTHIC_REROLL:
if (val > 100) {
return "Booster reroll chance must be between 0% and 100%.";
}
break;
default: default:
break; break;
} }