package forge.quest.data; import forge.*; import forge.deck.Deck; import forge.error.ErrorViewer; import forge.properties.ForgeProps; import forge.properties.NewConstants; import forge.quest.data.item.QuestInventory; import forge.quest.data.pet.QuestPetManager; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.google.code.jyield.Generator; import com.google.code.jyield.YieldUtils; //when you create QuestDataOld and AFTER you copy the AI decks over //you have to call one of these two methods below //see Gui_QuestOptions for more details // //static readAIQuestDeckFiles(QuestDataOld data, ArrayList aiDeckNames) //OR non-static readAIQuestDeckFiles() //which reads the files "questDecks-easy", "questDecks-medium","questDecks-hard", /** * <p>QuestData class.</p> * * @author Forge * @version $Id: $ */ public class QuestData { int rankIndex; int win; int lost; int life; //private int maxLife; int questsPlayed; long credits; int diffIndex; String difficulty; String mode = ""; Map<String, Deck> myDecks = new HashMap<String, Deck>(); //holds String card names List<String> cardPool = new ArrayList<String>(); List<String> newCardList = new ArrayList<String>(); List<String> shopList = new ArrayList<String>(); List<Integer> availableQuests = new ArrayList<Integer>(); List<Integer> completedQuests = new ArrayList<Integer>(); private transient QuestBoosterPack boosterPack; //used by shouldAddAdditionalCards() private long randomSeed = 0; private transient String[] rankArray; /** Constant <code>FANTASY="Fantasy"</code> */ public static final String FANTASY = "Fantasy"; /** Constant <code>REALISTIC="Realistic"</code> */ public static final String REALISTIC = "Realistic"; QuestInventory inventory = new QuestInventory(); //This field holds the version of the Quest Data /** Constant <code>CURRENT_VERSION_NUMBER=1</code> */ public static final int CURRENT_VERSION_NUMBER = 1; //This field places the version number into QD instance, //but only when the object is created through the constructor //DO NOT RENAME THIS FIELD int versionNumber = CURRENT_VERSION_NUMBER; QuestPetManager petManager = new QuestPetManager(); /** * <p>Constructor for QuestData.</p> */ public QuestData() { for (int i = 0; i < QuestPreferences.getStartingBasic(); i++) { cardPool.add("Forest"); cardPool.add("Mountain"); cardPool.add("Swamp"); cardPool.add("Island"); cardPool.add("Plains"); } for (int i = 0; i < QuestPreferences.getStartingSnowBasic(); i++) { cardPool.add("Snow-Covered Forest"); cardPool.add("Snow-Covered Mountain"); cardPool.add("Snow-Covered Swamp"); cardPool.add("Snow-Covered Island"); cardPool.add("Snow-Covered Plains"); } initTransients(); randomizeOpponents(); } /** * <p>initTransients.</p> */ private void initTransients() { rankArray = new String[]{ "Level 0 - Confused Wizard", "Level 1 - Mana Mage", "Level 2 - Death by Megrim", "Level 3 - Shattered the Competition", "Level 4 - Black Knighted", "Level 5 - Shockingly Good", "Level 6 - Regressed into Timmy", "Level 7 - Loves Blue Control", "Level 8 - Immobilized by Fear", "Level 9 - Lands = Friends", "Saltblasted for your talent", "Serra Angel is your girlfriend",}; boosterPack = new QuestBoosterPack(); } //adds cards to card pool and sets difficulty /** * <p>newGame.</p> * * @param difficulty a int. * @param m a {@link java.lang.String} object. * @param standardStart a boolean. */ public void newGame(int difficulty, String m, boolean standardStart) { setDifficulty(difficulty); Generator<Card> allCards = YieldUtils.toGenerator(AllZone.getCardFactory()); ArrayList<String> list = new ArrayList<String>(); list.addAll(boosterPack.getQuestStarterDeck(allCards, QuestPreferences.getStartingCommons(difficulty), QuestPreferences.getStartingUncommons(difficulty), QuestPreferences.getStartingRares(difficulty), standardStart)); //because cardPool already has basic land added to it cardPool.addAll(list); credits = QuestPreferences.getStartingCredits(); mode = m; if (mode.equals(FANTASY)) { life = 15; } else { life = 20; } } /** * This method should be called whenever the opponents should change. */ public void randomizeOpponents() { randomSeed = MyRandom.random.nextLong(); } /** * <p>saveData.</p> */ public void saveData() { QuestDataIO.saveData(this); } //returns Strings of the card names /** * <p>getCardpool.</p> * * @return a {@link java.util.List} object. */ public List<String> getCardpool() { //make a copy so the internal ArrrayList cannot be changed externally return new ArrayList<String>(cardPool); } /** * <p>setCardpool.</p> * * @param pool a {@link java.util.ArrayList} object. * @since 1.0.15 */ public void setCardpool(ArrayList<String> pool) { cardPool = pool; } /** * <p>Getter for the field <code>shopList</code>.</p> * * @return a {@link java.util.List} object. */ public List<String> getShopList() { if (shopList != null) { return new ArrayList<String>(shopList); } else { return null; } } /** * <p>Setter for the field <code>shopList</code>.</p> * * @param list a {@link java.util.List} object. */ public void setShopList(List<String> list) { shopList = list; } /** * <p>Getter for the field <code>availableQuests</code>.</p> * * @return a {@link java.util.List} object. */ public List<Integer> getAvailableQuests() { if (availableQuests != null) { return new ArrayList<Integer>(availableQuests); } else { return null; } } /** * <p>Setter for the field <code>availableQuests</code>.</p> * * @param list a {@link java.util.List} object. */ public void setAvailableQuests(List<Integer> list) { availableQuests = list; } /** * <p>clearAvailableQuests.</p> */ public void clearAvailableQuests() { availableQuests.clear(); } /** * <p>Getter for the field <code>completedQuests</code>.</p> * * @return a {@link java.util.List} object. */ public List<Integer> getCompletedQuests() { if (completedQuests != null) { return new ArrayList<Integer>(completedQuests); } else { return null; } } /** * <p>Setter for the field <code>completedQuests</code>.</p> * * @param list a {@link java.util.List} object. */ public void setCompletedQuests(List<Integer> list) { completedQuests = list; } /** * <p>clearShopList.</p> */ public void clearShopList() { shopList.clear(); } /** * <p>removeDeck.</p> * * @param deckName a {@link java.lang.String} object. */ public void removeDeck(String deckName) { myDecks.remove(deckName); } /** * <p>addDeck.</p> * * @param d a {@link forge.deck.Deck} object. */ public void addDeck(Deck d) { myDecks.put(d.getName(), d); } //this Deck object is a Constructed deck //deck.getDeckType() is Constant.GameType.Sealed //sealed since the card pool is the Deck sideboard /** * <p>getDeck.</p> * * @param deckName a {@link java.lang.String} object. * @return a {@link forge.deck.Deck} object. */ public Deck getDeck(String deckName) { //have to always set the card pool aka the Deck sideboard //because new cards may have been added to the card pool by addCards() if (!myDecks.containsKey(deckName)) { ErrorViewer.showError(new Exception(), "QuestData : getDeckFromMap(String deckName) error, deck name not found - %s", deckName); } Deck d = myDecks.get(deckName); //below is probably not needed //remove old cards from card pool for (int i = 0; i < d.countSideboard(); i++) { d.removeSideboard(i); } //add all cards to card pool for (int i = 0; i < cardPool.size(); i++) { d.addSideboard(cardPool.get(i)); } return d; } //returns human player decks //returns ArrayList of String deck names /** * <p>getDeckNames.</p> * * @return a {@link java.util.List} object. */ public List<String> getDeckNames() { return new ArrayList<String>(myDecks.keySet()); } //get new cards that were added to your card pool by addCards() /** * <p>getAddedCards.</p> * * @return a {@link java.util.List} object. */ public List<String> getAddedCards() { return new ArrayList<String>(newCardList); } //adds 11 cards, to the current card pool //(I chose 11 cards instead of 15 in order to make things more challenging) /** * <p>addCards.</p> */ public void addCards() { Generator<Card> cards = YieldUtils.toGenerator(AllZone.getCardFactory()); int nCommon = QuestPreferences.getNumCommon(); int nUncommon = QuestPreferences.getNumUncommon(); int nRare = QuestPreferences.getNumRare(); ArrayList<String> newCards = new ArrayList<String>(); newCards.addAll(boosterPack.generateCards(cards, nCommon, Constant.Rarity.Common, null)); newCards.addAll(boosterPack.generateCards(cards, nUncommon, Constant.Rarity.Uncommon, null)); newCards.addAll(boosterPack.generateCards(cards, nRare, Constant.Rarity.Rare, null)); cardPool.addAll(newCards); //getAddedCards() uses newCardList newCardList = newCards; } /** * <p>addRandomRare.</p> * * @param n a int. * @return a {@link java.util.ArrayList} object. */ public ArrayList<String> addRandomRare(int n) { Generator<Card> allCards = YieldUtils.toGenerator(AllZone.getCardFactory()); ArrayList<String> newCards = new ArrayList<String>(); newCards.addAll(boosterPack.generateCards(allCards, n, Constant.Rarity.Rare, null)); cardPool.addAll(newCards); newCardList.addAll(newCards); return newCards; } /** * <p>addRandomRare.</p> * * @return a {@link java.lang.String} object. */ public String addRandomRare() { return addRandomRare(1).get(0); } /** * <p>addCard.</p> * * @param c a {@link forge.Card} object. */ public void addCard(Card c) { cardPool.add(c.getName()); } /** * <p>addCard.</p> * * @param s a {@link java.lang.String} object. */ public void addCard(String s) { cardPool.add(s); } /** * <p>removeCard.</p> * * @param c a {@link forge.Card} object. */ public void removeCard(Card c) { String s = c.getName(); if (!cardPool.contains(s)) { return; } for (int i = 0; i < cardPool.size(); i++) { String str = cardPool.get(i); if (str.equals(s)) { cardPool.remove(i); break; } } } /** * <p>addCardToShopList.</p> * * @param c a {@link forge.Card} object. */ public void addCardToShopList(Card c) { shopList.add(c.getName()); } /** * <p>removeCardFromShopList.</p> * * @param c a {@link forge.Card} object. */ public void removeCardFromShopList(Card c) { String s = c.getName(); if (!shopList.contains(s)) { return; } for (int i = 0; i < shopList.size(); i++) { String str = shopList.get(i); if (str.equals(s)) { shopList.remove(i); break; } } } /** * <p>getCreditsToAdd.</p> * * @param matchState a {@link forge.quest.data.QuestMatchState} object. * @return a long. */ public long getCreditsToAdd(QuestMatchState matchState) { long creds = (long) (QuestPreferences.getMatchRewardBase() + (QuestPreferences.getMatchRewardTotalWins() * win)); String[] wins = matchState.getWinMethods(); int[] winTurns = matchState.getWinTurns(); boolean[] mulliganedToZero = matchState.getMulliganedToZero(); if (matchState.getLose() == 0) { creds += QuestPreferences.getMatchRewardNoLosses(); } for (String s : wins) { if (s != null) { if (s.equals("Poison Counters")) { creds += QuestPreferences.getMatchRewardPoisonWinBonus(); } else if (s.equals("Milled")) { creds += QuestPreferences.getMatchRewardMilledWinBonus(); } else if (s.equals("Battle of Wits") || s.equals("Felidar Sovereign") || s.equals("Helix Pinnacle") || s.equals("Epic Struggle") || s.equals("Door to Nothingness") || s.equals("Barren Glory") || s.equals("Near-Death Experience") || s.equals("Mortal Combat") || s.equals("Test of Endurance")) { creds += QuestPreferences.getMatchRewardAltWinBonus(); } } } for (int i : winTurns) { if (i == 1) { creds += QuestPreferences.getMatchRewardWinFirst(); } else if (i <= 5) { creds += QuestPreferences.getMatchRewardWinByFifth(); } else if (i <= 10) { creds += QuestPreferences.getMatchRewardWinByTen(); } else if (i <= 15) { creds += QuestPreferences.getMatchRewardWinByFifteen(); } } for (boolean b : mulliganedToZero) { if (b == true) { creds += QuestPreferences.getMatchMullToZero(); } } if (inventory.getItemLevel("Estates") == 1) { creds *= 1.1; } else if (inventory.getItemLevel("Estates") == 2) { creds *= 1.15; } else if (inventory.getItemLevel("Estates") == 3) { creds *= 1.2; } this.addCredits(creds); return creds; } //gets all of the cards that are in the cardpool /** * <p>getCards.</p> * * @return a {@link java.util.List} object. */ public List<String> getCards() { //copy CardList in order to keep private variables private //if we just return cardPool, it could be changed externally return new ArrayList<String>(cardPool); } /** * <p>getTotalNumberOfGames.</p> * * @param difficulty a int. * @return a int. */ public int getTotalNumberOfGames(int difficulty) { //-2 because you start a level 1, and the last level is secret int numberLevels = rankArray.length - 2; int nMatches = QuestPreferences.getWinsForRankIncrease(difficulty); return numberLevels * nMatches; } //this changes getRank() /** * <p>addWin.</p> */ public void addWin() { win++; if (win % QuestPreferences.getWinsForRankIncrease(diffIndex) == 0) { rankIndex++; } } /** * <p>addLost.</p> */ public void addLost() { lost++; } /** * <p>Getter for the field <code>win</code>.</p> * * @return a int. */ public int getWin() { return win; } /** * <p>Getter for the field <code>lost</code>.</p> * * @return a int. */ public int getLost() { return lost; } //********************FANTASY STUFF START*********************** /** * <p>Setter for the field <code>life</code>.</p> * * @param n a int. */ public void setLife(int n) { life = n; } /** * <p>Getter for the field <code>life</code>.</p> * * @return a int. */ public int getLife() { return life; } /** * <p>addLife.</p> * * @param n a int. */ public void addLife(int n) { life += n; } /** * <p>Getter for the field <code>questsPlayed</code>.</p> * * @return a int. */ public int getQuestsPlayed() { return questsPlayed; } /** * <p>addQuestsPlayed.</p> */ public void addQuestsPlayed() { questsPlayed++; } //********************FANTASY STUFF END*********************** /** * <p>addCredits.</p> * * @param c a long. */ public void addCredits(long c) { credits += c; } /** * <p>subtractCredits.</p> * * @param c a long. */ public void subtractCredits(long c) { credits -= c; if (credits < 0) { credits = 0; } } /** * <p>Getter for the field <code>credits</code>.</p> * * @return a long. */ public long getCredits() { return credits; } /** * <p>Getter for the field <code>mode</code>.</p> * * @return a {@link java.lang.String} object. */ public String getMode() { if (mode == null) { return ""; } return mode; } //should be called first, because the difficultly won't change /** * <p>Getter for the field <code>difficulty</code>.</p> * * @return a {@link java.lang.String} object. */ public String getDifficulty() { return difficulty; } /** * <p>getDifficultyIndex.</p> * * @return a int. */ public int getDifficultyIndex() { return diffIndex; } /** * <p>Setter for the field <code>difficulty</code>.</p> * * @param i a int. */ public void setDifficulty(int i) { diffIndex = i; difficulty = QuestPreferences.getDifficulty(i); } /** * <p>setDifficultyIndex.</p> */ public void setDifficultyIndex() { String[] diffStr = QuestPreferences.getDifficulty(); for (int i = 0; i < diffStr.length; i++) { if (difficulty.equals(diffStr[i])) { diffIndex = i; } } } /** * <p>getDifficultyChoices.</p> * * @return an array of {@link java.lang.String} objects. */ public String[] getDifficultyChoices() { return QuestPreferences.getDifficulty(); } /** * <p>getRank.</p> * * @return a {@link java.lang.String} object. */ public String getRank() { //is rankIndex too big? if (rankIndex >= rankArray.length) { rankIndex = rankArray.length - 1; } return rankArray[rankIndex]; } /** * <p>getLevel.</p> * * @return a int. * @since 1.0.15 */ public int getLevel() { return rankIndex; } //add cards after a certain number of wins or losses /** * <p>shouldAddCards.</p> * * @param didWin a boolean. * @return a boolean. */ public boolean shouldAddCards(boolean didWin) { int n = QuestPreferences.getWinsForBooster(diffIndex); if (didWin) { return getWin() % n == 0; } else { return getLost() % n == 0; } } /** * <p>shouldAddAdditionalCards.</p> * * @param didWin a boolean. * @return a boolean. */ public boolean shouldAddAdditionalCards(boolean didWin) { float chance = 0.5f; if (inventory.getItemLevel("Lucky Coin") == 1) { chance = 0.65f; } float r = MyRandom.random.nextFloat(); if (didWin) { return r <= chance; } else { return false; } } /** * <p>hasSaveFile.</p> * * @return a boolean. */ public boolean hasSaveFile() { return ForgeProps.getFile(NewConstants.QUEST.DATA).exists() || ForgeProps.getFile(NewConstants.QUEST.XMLDATA).exists(); } /** * <p>main.</p> * * @param args an array of {@link java.lang.String} objects. */ public static void main(String[] args) { QuestData q = new QuestData(); for (int i = 0; i < 20; i++) { q.addCards(); } for (int i = 0; i < 10; i++) { q.saveData(); q = QuestDataIO.loadData(); } System.exit(1); } /** * <p>Getter for the field <code>petManager</code>.</p> * * @return a {@link forge.quest.data.pet.QuestPetManager} object. */ public QuestPetManager getPetManager() { return petManager; } //get new cards that were added to your card pool by addCards() /** * <p>addToNewList.</p> * * @param added a {@link java.util.ArrayList} object. */ public void addToNewList(ArrayList<String> added) { newCardList.addAll(added); } /** * <p>readResolve.</p> * * @return a {@link java.lang.Object} object. */ public Object readResolve() { initTransients(); return this; } /** * <p>Getter for the field <code>inventory</code>.</p> * * @return a {@link forge.quest.data.item.QuestInventory} object. */ public QuestInventory getInventory() { return inventory; } /** * <p>Getter for the field <code>randomSeed</code>.</p> * * @return a long. */ public long getRandomSeed() { return randomSeed; } }