diff --git a/projects/mtg/Makefile b/projects/mtg/Makefile index 407cf7b79..7238d2389 100644 --- a/projects/mtg/Makefile +++ b/projects/mtg/Makefile @@ -1,4 +1,4 @@ -OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardPrimitive.o objs/CardSelector.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckMetaData.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateAwards.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GameStateStory.o objs/GameStateTransitions.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGPack.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/Pos.o objs/PriceList.o objs/ReplacementEffects.o objs/Rules.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/SimplePad.o objs/StoryFlow.o objs/StyleManager.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/ThisDescriptor.o objs/Token.o objs/Translate.o objs/TranslateKeys.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o objs/WDataSrc.o objs/WGui.o objs/WFilter.o objs/Tasks.o objs/WFont.o +OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardPrimitive.o objs/CardSelector.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckMetaData.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateAwards.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/DeckManager.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GameStateStory.o objs/GameStateTransitions.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGPack.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/Pos.o objs/PriceList.o objs/ReplacementEffects.o objs/Rules.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/SimplePad.o objs/StoryFlow.o objs/StyleManager.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/ThisDescriptor.o objs/Token.o objs/Translate.o objs/TranslateKeys.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o objs/WDataSrc.o objs/WGui.o objs/WFilter.o objs/Tasks.o objs/WFont.o DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS)) RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache) diff --git a/projects/mtg/include/DeckManager.h b/projects/mtg/include/DeckManager.h new file mode 100644 index 000000000..f6db9ad47 --- /dev/null +++ b/projects/mtg/include/DeckManager.h @@ -0,0 +1,27 @@ +#include +#include + +using namespace std; + + +class DeckManager +{ +protected: + static DeckManager * mInstance; + +public: + + + vector playerDeckOrderList; + vector aiDeckOrderList; + + + vector * getPlayerDeckOrderList(); + vector * getAIDeckOrderList(); + + static DeckManager * GetInstance(); + static void EndInstance(); + + DeckManager(); + ~DeckManager(); +}; diff --git a/projects/mtg/include/DeckMetaData.h b/projects/mtg/include/DeckMetaData.h index fb86985a0..97fd6d6da 100644 --- a/projects/mtg/include/DeckMetaData.h +++ b/projects/mtg/include/DeckMetaData.h @@ -2,16 +2,25 @@ #define _DECKMETADATA_H_ #include +#include #include using namespace std; class DeckMetaData { public: + DeckMetaData(); DeckMetaData(string filename); void load(string filename); + bool operator<(DeckMetaData b); + string desc; string name; + int deckid; + + string& trim(string &str); + string& ltrim(string &str); + string& rtrim(string &str); }; class DeckMetaDataList { @@ -20,6 +29,8 @@ public: DeckMetaData * get(string filename); ~DeckMetaDataList(); static DeckMetaDataList * decksMetaData; + + private: mapvalues; }; diff --git a/projects/mtg/include/GameOptions.h b/projects/mtg/include/GameOptions.h index 047a69bf5..181c6bb66 100644 --- a/projects/mtg/include/GameOptions.h +++ b/projects/mtg/include/GameOptions.h @@ -46,6 +46,7 @@ public: REVERSETRIGGERS, DISABLECARDS, MAX_GRADE, + ASPHASES, ECON_DIFFICULTY, TRANSITIONS, GUI_STYLE, @@ -182,7 +183,13 @@ private: OptionMaxGrade(); static OptionMaxGrade mDef; }; - +class OptionASkipPhase: public EnumDefinition { +public: + static EnumDefinition * getInstance() {return &mDef;}; +private: + OptionASkipPhase(); + static OptionASkipPhase mDef; +}; class OptionEconDifficulty: public EnumDefinition { public: static EnumDefinition * getInstance() {return &mDef;}; diff --git a/projects/mtg/include/GameState.h b/projects/mtg/include/GameState.h index 7acd78934..e4f059b0a 100644 --- a/projects/mtg/include/GameState.h +++ b/projects/mtg/include/GameState.h @@ -7,6 +7,8 @@ class JGE; #include #include +#include +#include using namespace std; enum ENUM_GAME_STATE @@ -53,7 +55,13 @@ class GameState virtual void Update(float dt) = 0; virtual void Render() = 0; static int fillDeckMenu(SimpleMenu * _menu, string path, string smallDeckPrefix = "", Player * statsPlayer = NULL); -}; + static int fillDeckMenu( vector * deckIdList, SimpleMenu * _menu, string path, string smallDeckPrefix = "", Player * statsPlayer = NULL); + + string& trim(string &str); + string& ltrim(string &str); + string& rtrim(string &str); + + }; #endif diff --git a/projects/mtg/include/MTGDefinitions.h b/projects/mtg/include/MTGDefinitions.h index 0bec4324d..87c43e15b 100644 --- a/projects/mtg/include/MTGDefinitions.h +++ b/projects/mtg/include/MTGDefinitions.h @@ -175,6 +175,10 @@ class Constants GRADE_CRAPPY = 3, GRADE_UNSUPPORTED = 4, GRADE_DANGEROUS = 5, + + ASKIP_NONE=0, + ASKIP_SAFE=1, + ASKIP_FULL=2, }; static char MTGColorChars[]; diff --git a/projects/mtg/src/CardDisplay.cpp b/projects/mtg/src/CardDisplay.cpp index d147d8548..85993d638 100644 --- a/projects/mtg/src/CardDisplay.cpp +++ b/projects/mtg/src/CardDisplay.cpp @@ -78,7 +78,7 @@ void CardDisplay::Update(float dt){ } bool CardDisplay::CheckUserInput(JButton key){ - if (JGE_BTN_SEC == key) + if (JGE_BTN_SEC == key || JGE_BTN_PRI == key) { if (listener){ listener->ButtonPressed(mId, 0); diff --git a/projects/mtg/src/DeckManager.cpp b/projects/mtg/src/DeckManager.cpp new file mode 100644 index 000000000..733e35a48 --- /dev/null +++ b/projects/mtg/src/DeckManager.cpp @@ -0,0 +1,38 @@ +#include "../include/DeckManager.h" +#include + +DeckManager::DeckManager() +{ +} + +DeckManager::~DeckManager() +{ +} + + +vector * DeckManager::getPlayerDeckOrderList() +{ + return &playerDeckOrderList; +} + +vector * DeckManager::getAIDeckOrderList() +{ + return &aiDeckOrderList; +} + + +DeckManager * DeckManager::mInstance = NULL; + + +DeckManager* DeckManager::GetInstance() +{ + if ( mInstance == NULL ) + mInstance = new DeckManager(); + return mInstance; +} + +void DeckManager::EndInstance() +{ + + SAFE_DELETE(mInstance); +} diff --git a/projects/mtg/src/DeckMetaData.cpp b/projects/mtg/src/DeckMetaData.cpp index 32f95cb16..7d7a7733b 100644 --- a/projects/mtg/src/DeckMetaData.cpp +++ b/projects/mtg/src/DeckMetaData.cpp @@ -8,16 +8,29 @@ DeckMetaDataList * DeckMetaDataList::decksMetaData = NEW DeckMetaDataList(); +DeckMetaData::DeckMetaData(){ + +} + DeckMetaData::DeckMetaData(string filename){ load(filename); } + void DeckMetaData::load(string filename){ MTGDeck * mtgd = NEW MTGDeck(filename.c_str(),NULL,1); - name = mtgd->meta_name; - desc = mtgd->meta_desc; + name = DeckMetaData::trim( mtgd->meta_name ); + desc = DeckMetaData::trim( mtgd->meta_desc ); + deckid = atoi( (filename.substr( filename.find("deck") + 4, filename.find(".txt") )).c_str() ); delete(mtgd); } + +// Must define less than relative to DeckMetaData objects. +bool DeckMetaData::operator<(DeckMetaData b) +{ + return strcmp(name.c_str(), b.name.c_str()) < 0; +} + DeckMetaDataList::~DeckMetaDataList(){ for(map::iterator it = values.begin(); it != values.end(); ++it){ SAFE_DELETE(it->second); @@ -43,3 +56,46 @@ DeckMetaData * DeckMetaDataList::get(string filename){ return values[filename]; //this creates a NULL entry if the file does not exist } + + + +string& DeckMetaData::trim(string &str) +{ + int i,j,start,end; + + //ltrim + for (i=0; (str[i]!=0 && str[i]<=32); ) + i++; + start=i; + + //rtrim + for(i=0,j=0; str[i]!=0; i++) + j = ((str[i]<=32)? j+1 : 0); + end=i-j; + str = str.substr(start,end-start); + return str; +} + + +string& DeckMetaData::ltrim(string &str) +{ + int i,start; + + for (i=0; (str[i]!=0 && str[i]<=32); ) + i++; + start=i; + + str = str.substr(start,str.length()-start); + return str; +} +string& DeckMetaData::rtrim(string &str) +{ + int i,j,end; + + for(i=0,j=0; str[i]!=0; i++) + j = ((str[i]<=32)? j+1 : 0); + end=i-j; + + str = str.substr(0,end); + return str; +} diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index c0b5a577a..3ad19dd60 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -301,6 +301,32 @@ void GameObserver::Update(float dt){ } stateEffects(); oldGamePhase = currentGamePhase; + + //Auto skip Phases + int skipLevel = options[Options::ASPHASES].number; + int nrCreatures = currentPlayer->game->inPlay->countByType("Creature"); + + if (skipLevel == Constants::ASKIP_SAFE || skipLevel == Constants::ASKIP_FULL) { + if ((opponent()->isAI() && !(isInterrupting)) && + ( + currentGamePhase == Constants::MTG_PHASE_UNTAP + || currentGamePhase == Constants::MTG_PHASE_DRAW + || currentGamePhase == Constants::MTG_PHASE_COMBATBEGIN + || ((currentGamePhase == Constants::MTG_PHASE_COMBATATTACKERS) && (nrCreatures == 0)) + || currentGamePhase == Constants::MTG_PHASE_COMBATEND + || currentGamePhase == Constants::MTG_PHASE_ENDOFTURN + || ((currentGamePhase == Constants::MTG_PHASE_CLEANUP) && (currentPlayer->game->hand->nb_cards < 8)) + )) + userRequestNextGamePhase(); + } + if (skipLevel == Constants::ASKIP_FULL) { + if ((opponent()->isAI() && !(isInterrupting)) && + (currentGamePhase == Constants::MTG_PHASE_UPKEEP + || currentGamePhase == Constants::MTG_PHASE_COMBATDAMAGE + )) + userRequestNextGamePhase(); + + } } //applies damage to creatures after updates diff --git a/projects/mtg/src/GameOptions.cpp b/projects/mtg/src/GameOptions.cpp index 5fc51793d..7c70d6411 100644 --- a/projects/mtg/src/GameOptions.cpp +++ b/projects/mtg/src/GameOptions.cpp @@ -30,6 +30,7 @@ const string Options::optionNames[] = { "reverse_triggers", "disable_cards", "maxGrade", + "ASPhases", "economic_difficulty", "transitions", "bgStyle", @@ -378,6 +379,11 @@ GameOption * GameOptions::get(int optionID) { goEnum = NEW GameOptionEnum(); goEnum->def = OptionMaxGrade::getInstance(); go = goEnum; + break; + case Options::ASPHASES: + goEnum = NEW GameOptionEnum(); + goEnum->def = OptionASkipPhase::getInstance(); + go = goEnum; break; case Options::KEY_BINDINGS: go = NEW GameOptionKeyBindings(); @@ -763,6 +769,12 @@ OptionMaxGrade::OptionMaxGrade(){ mDef.values.push_back(EnumDefinition::assoc(Constants::GRADE_DANGEROUS, "-4: Dangerous (risk of crash)")); }; +OptionASkipPhase OptionASkipPhase::mDef; +OptionASkipPhase::OptionASkipPhase(){ + mDef.values.push_back(EnumDefinition::assoc(Constants::ASKIP_NONE, "Off")); + mDef.values.push_back(EnumDefinition::assoc(Constants::ASKIP_SAFE, "Safe")); + mDef.values.push_back(EnumDefinition::assoc(Constants::ASKIP_FULL, "Full")); +}; OptionClosedHand OptionClosedHand::mDef; OptionClosedHand::OptionClosedHand(){ mDef.values.push_back(EnumDefinition::assoc(INVISIBLE, "invisible")); diff --git a/projects/mtg/src/GameState.cpp b/projects/mtg/src/GameState.cpp index 1750208b5..4a1c4b386 100644 --- a/projects/mtg/src/GameState.cpp +++ b/projects/mtg/src/GameState.cpp @@ -51,3 +51,65 @@ int GameState::fillDeckMenu(SimpleMenu * _menu, string path, string smallDeckPre } return nbDecks; } + +int GameState::fillDeckMenu(vector * deckIdList, SimpleMenu * _menu, string path, string smallDeckPrefix, Player * statsPlayer){ + DeckMetaDataList * metas = DeckMetaDataList::decksMetaData; + int found = 1; + int nbDecks = 0; + _menu->autoTranslate = false; + map menu; + list deckNameVector; + while (found){ + found = 0; + char buffer[512]; + char smallDeckName[512]; + char deckDesc[512]; + sprintf(buffer, "%s/deck%i.txt",path.c_str(),nbDecks+1); + if(DeckMetaData * meta = metas->get(buffer)){ + found = 1; + nbDecks++; + sprintf(smallDeckName, "%s_deck%i",smallDeckPrefix.c_str(),nbDecks); + + if (statsPlayer){ + DeckStats * stats = DeckStats::GetInstance(); + stats->load(statsPlayer); + int percentVictories = stats->percentVictories(string(smallDeckName)); + string difficulty; + if (percentVictories < 34){ + difficulty = "(hard)"; + }else if (percentVictories < 67){ + difficulty = ""; + }else{ + difficulty = "(easy)"; + } + sprintf(deckDesc, "%s %s",meta->name.c_str(), _(difficulty).c_str()); + }else{ + sprintf(deckDesc, "%s",meta->name.c_str()); + } + deckDesc[16] = 0; + //translate decks desc + Translator * t = Translator::GetInstance(); + map::iterator it = t->deckValues.find(meta->name); + if (it != t->deckValues.end()) + _menu->Add(nbDecks,deckDesc, it->second); + else + { + menu[deckDesc] = *meta; + deckNameVector.push_back( deckDesc ); + } + } + } + + deckNameVector.sort(); + int deckNumber = 1; + for (list::iterator i = deckNameVector.begin(); i != deckNameVector.end(); i++) + { + string deckName = *i; + DeckMetaData meta = menu[ deckName ]; + string deckDescription = meta.desc; + deckIdList->push_back( meta.deckid ); + _menu->Add( deckNumber++ ,deckName.c_str(), deckDescription.c_str()); + } + return nbDecks; +} + diff --git a/projects/mtg/src/GameStateDeckViewer.cpp b/projects/mtg/src/GameStateDeckViewer.cpp index c8f1756d1..6428a8e9f 100644 --- a/projects/mtg/src/GameStateDeckViewer.cpp +++ b/projects/mtg/src/GameStateDeckViewer.cpp @@ -3,6 +3,7 @@ #include #include "../include/config.h" +#include "../include/DeckManager.h" #include "../include/GameStateDeckViewer.h" #include "../include/Translate.h" #include "../include/ManaCostHybrid.h" @@ -1087,7 +1088,6 @@ void GameStateDeckViewer::updateStats() { } // Lets look for mana producing abilities - int found; vector abilityStrings; string thisstring = current->data->magicText; @@ -1430,6 +1430,9 @@ int GameStateDeckViewer::loadDeck(int deckid){ void GameStateDeckViewer::ButtonPressed(int controllerId, int controlId) { + int deckIdNumber = controlId; + DeckManager *deckManager = DeckManager::GetInstance(); + vector * deckList; switch(controllerId){ case 10: //Deck menu if (controlId == -1){ @@ -1458,7 +1461,16 @@ void GameStateDeckViewer::ButtonPressed(int controllerId, int controlId) mStage = STAGE_WELCOME; break; } - loadDeck(controlId); + loadDeck(deckIdNumber); + mStage = STAGE_WAITING; + deckNum = controlId; + deckList = deckManager->getPlayerDeckOrderList(); + //if (deckList->size() > 0 && controlId < deckList->size()) removed this hopefully with no side effects due to not being able to compile for psp because of sighed and unsigned int comparison. + // deckIdNumber = deckList->at(controlId); + /*else*/ + + deckIdNumber = controlId; + loadDeck(deckIdNumber); mStage = STAGE_WAITING; deckNum = controlId; break; diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index 10474494f..d5142e05a 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -6,6 +6,9 @@ #include "../include/AIMomirPlayer.h" #include "../include/PlayerData.h" #include "../include/DeckStats.h" +#include "../include/DeckManager.h" + +#include "../include/DeckMetaData.h" #include "../include/MTGRules.h" #include "../include/Credits.h" #include "../include/Translate.h" @@ -89,7 +92,8 @@ void GameStateDuel::Start() if (mParent->players[i] == PLAYER_TYPE_HUMAN){ decksneeded = 1; deckmenu = NEW SimpleMenu(DUEL_MENU_CHOOSE_DECK, this, Constants::MENU_FONT, 35, 25, "Choose a Deck"); - int nbDecks = fillDeckMenu(deckmenu,options.profileFile()); + DeckManager *deckManager = DeckManager::GetInstance(); + int nbDecks = fillDeckMenu( deckManager->getPlayerDeckOrderList(), deckmenu, options.profileFile()); if (nbDecks) decksneeded = 0; break; } @@ -219,7 +223,9 @@ void GameStateDuel::ensureOpponentMenu(){ opponentMenu->Add(0,"Random"); if (options[Options::EVILTWIN_MODE_UNLOCKED].number) opponentMenu->Add(-1,"Evil Twin", "Can you play against yourself?"); - fillDeckMenu(opponentMenu,RESPATH"/ai/baka", "ai_baka", mPlayers[0]); + DeckManager * deckManager = DeckManager::GetInstance(); + fillDeckMenu( deckManager->getAIDeckOrderList(), opponentMenu, RESPATH"/ai/baka", "ai_baka", mPlayers[0]); + opponentMenu->Add(-2,"Cancel", "Back to Main Menu"); } } @@ -477,6 +483,8 @@ void GameStateDuel::Render() } void GameStateDuel::ButtonPressed(int controllerId, int controlId) { + int deckNumber = controlId; + DeckManager * deckManager = DeckManager::GetInstance(); switch (controllerId){ case DUEL_MENU_CHOOSE_OPPONENT: { @@ -487,8 +495,20 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId) { mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY; break; default: - loadPlayer(1,controlId,1); - OpponentsDeckid=controlId; + // cancel option. return to main menu + + if (controlId == -2) + { + opponentMenu->Close(); + mParent->SetNextState( DUEL_STATE_BACK_TO_MAIN_MENU ); + mGamePhase = DUEL_MENU_GAME_MENU; + break; + } + else if ( controlId != -1 && deckManager->getAIDeckOrderList()->size() > 0) // evil twin + deckNumber = deckManager->getAIDeckOrderList()->at( controlId - 1 ); + + loadPlayer(1,deckNumber,1); + OpponentsDeckid=deckNumber; opponentMenu->Close(); mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY; break; @@ -502,7 +522,10 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId) { return; } if (mGamePhase == DUEL_STATE_CHOOSE_DECK1){ - loadPlayer(0,controlId); + vector * playerDeck = deckManager->getPlayerDeckOrderList(); + if ( !premadeDeck && controlId > 0 ) + deckNumber = playerDeck->at( controlId - 1 ); + loadPlayer(0,deckNumber); deckmenu->Close(); mGamePhase = DUEL_STATE_CHOOSE_DECK1_TO_2; }else{ diff --git a/projects/mtg/src/GameStateOptions.cpp b/projects/mtg/src/GameStateOptions.cpp index ebdd4c724..95f5a2105 100644 --- a/projects/mtg/src/GameStateOptions.cpp +++ b/projects/mtg/src/GameStateOptions.cpp @@ -76,6 +76,8 @@ void GameStateOptions::Start() optionsList->Add(cLang); WDecoEnum * oGra = NEW WDecoEnum(NEW OptionInteger(Options::MAX_GRADE,"Minimum Card Grade",Constants::GRADE_DANGEROUS,1,Constants::GRADE_BORDERLINE,"",Constants::GRADE_SUPPORTED)); optionsList->Add(oGra); + WDecoEnum * oASPhases = NEW WDecoEnum(NEW OptionInteger(Options::ASPHASES,"Phase Skip Automation",Constants::ASKIP_FULL,1,Constants::ASKIP_NONE,"",Constants::ASKIP_NONE)); + optionsList->Add(oASPhases); optionsTabs->Add(optionsList); optionsList = NEW WGuiKeyBinder("Key Bindings", this);