diff --git a/projects/mtg/include/CardSelector.h b/projects/mtg/include/CardSelector.h index 27eb5aea7..fa8630525 100644 --- a/projects/mtg/include/CardSelector.h +++ b/projects/mtg/include/CardSelector.h @@ -54,7 +54,7 @@ class ObjectSelector : public GuiLayer bool CheckUserInput(u32 key); void Update(float dt); void Render(); - void Limit(LimitorFunctor* limitor); + void Limit(LimitorFunctor* limitor, SelectorZone); void Push(); void Pop(); diff --git a/projects/mtg/include/GameOptions.h b/projects/mtg/include/GameOptions.h index 00abc3cec..dc7031e36 100644 --- a/projects/mtg/include/GameOptions.h +++ b/projects/mtg/include/GameOptions.h @@ -31,7 +31,8 @@ struct Options { static const string ACTIVE_PROFILE; static const string ACTIVE_THEME; static const string ACTIVE_MODE; - static const string HANDMODE; + static const string CLOSEDHAND; + static const string HANDDIRECTION; }; struct Metrics { @@ -78,7 +79,8 @@ public: PIXEL_TYPE asColor(PIXEL_TYPE fallback = ARGB(255,255,255,255)); bool isDefault(); //Returns true when number is 0 abd string is "" or "default" GameOption(int value = 0); - GameOption(string value); + GameOption(string); + GameOption(int, string); }; @@ -116,7 +118,7 @@ public: //These return a filepath accurate to the current mode/profile/theme, and can //optionally fallback to a file within a certain directory. //The sanity=false option returns the adjusted path even if the file doesn't exist. - string profileFile(string filename="", string fallback="", bool sanity=false,bool relative=false); + string profileFile(string filename="", string fallback="", bool sanity=true,bool relative=false); void reloadProfile(bool images = true); //Reloads profile using current options[ACTIVE_PROFILE] void checkProfile(); //Confirms that a profile is loaded and contains a collection. diff --git a/projects/mtg/include/GuiHand.h b/projects/mtg/include/GuiHand.h index cc2c904c7..275f7ffca 100644 --- a/projects/mtg/include/GuiHand.h +++ b/projects/mtg/include/GuiHand.h @@ -28,6 +28,8 @@ class GuiHand : public GuiLayer static const float OpenX; static const float ClosedX; + static const float OpenY; + static const float ClosedY; protected: const MTGHand* hand; diff --git a/projects/mtg/include/OptionItem.h b/projects/mtg/include/OptionItem.h index dce912f55..7a2f3b709 100644 --- a/projects/mtg/include/OptionItem.h +++ b/projects/mtg/include/OptionItem.h @@ -106,7 +106,7 @@ class OptionSelect:public OptionItem{ virtual void addSelection(string s); OptionSelect(string _id, string _displayValue): OptionItem(_id, _displayValue) {value = 0;}; - virtual void Reload() {initSelections();}; + virtual void Reload(){initSelections();}; virtual void Render(); virtual void setData(); virtual void initSelections(); @@ -206,4 +206,29 @@ class OptionsMenu }; +class OptionEnum : public OptionItem { + protected: + typedef pair assoc; + unsigned index; + vector values; + public: + OptionEnum(string id, string displayValue) : OptionItem(id, displayValue), index(0) {}; + virtual void Reload(); + virtual void Render(); + virtual void setData(); + virtual void updateValue(); + virtual ostream& toString(ostream& out) const; +}; + +class OptionClosedHand : public OptionEnum { + public: + enum { INVISIBLE = 0, VISIBLE = 1 }; + OptionClosedHand(string id, string displayValue); +}; +class OptionHandDirection : public OptionEnum { + public: + enum { VERTICAL = 0, HORIZONTAL = 1}; + OptionHandDirection(string id, string displayValue); +}; + #endif diff --git a/projects/mtg/src/CardSelector.cpp b/projects/mtg/src/CardSelector.cpp index afa931a18..f7d96f3d1 100644 --- a/projects/mtg/src/CardSelector.cpp +++ b/projects/mtg/src/CardSelector.cpp @@ -85,6 +85,9 @@ void CardSelector::Pop() { active = fetchMemory(memoryStack.top()); memoryStack.pop(); + SelectorZone oldowner; + if (CardView *q = dynamic_cast(oldactive)) oldowner = q->owner; else oldowner = nullZone; + if (nullZone != oldowner) lasts[oldowner] = SelectorMemory(oldactive); } if (active != oldactive) { @@ -183,13 +186,21 @@ void CardSelector::Render() } template<> -void CardSelector::Limit(LimitorFunctor* limitor) +void CardSelector::Limit(LimitorFunctor* limitor, SelectorZone destzone) { this->limitor = limitor; if (limitor && !limitor->select(active)) { Target* oldactive = active; - active = closest(cards, limitor, active); + SelectorZone oldowner; + if (CardView *q = dynamic_cast(oldactive)) oldowner = q->owner; else oldowner = nullZone; + if (oldowner != destzone) + { + if (nullZone != destzone) + if (PlayGuiObject* old = fetchMemory(lasts[destzone])) + active = old; + lasts[oldowner] = SelectorMemory(oldactive); + } if (limitor && !limitor->select(active)) active = NULL; if (active != oldactive) { diff --git a/projects/mtg/src/GameOptions.cpp b/projects/mtg/src/GameOptions.cpp index 98c09944c..6ac003be6 100644 --- a/projects/mtg/src/GameOptions.cpp +++ b/projects/mtg/src/GameOptions.cpp @@ -42,6 +42,8 @@ const string Options::MOMIR_MODE_UNLOCKED = "_gprx_rimom"; //haha const string Options::EVILTWIN_MODE_UNLOCKED = "_gprx_eviltwin"; const string Options::RANDOMDECK_MODE_UNLOCKED = "_gprx_rnddeck"; const string Options::CACHESIZE = "_gcacheSize"; +const string Options::CLOSEDHAND = "closed_hand"; +const string Options::HANDDIRECTION = "hand_direction"; //Theme metrics const string Metrics::LOADING_TC = "_tLoadingTC"; const string Metrics::STATS_TC = "_tStatsTC"; @@ -76,6 +78,7 @@ const string Metrics::KEYPAD_TC = "_tKeypadTC"; GameOption::GameOption(int value) : number(value){} GameOption::GameOption(string value) : number(0), str(value) {} +GameOption::GameOption(int num, string str) : number(num), str(str) {} bool GameOption::isDefault(){ string test = str; @@ -203,7 +206,6 @@ GameSettings::~GameSettings(){ SAFE_DELETE(globalOptions); SAFE_DELETE(profileOptions); SAFE_DELETE(themeOptions); - SAFE_DELETE(keypad); } GameOption& GameSettings::operator[](string option_name){ @@ -224,11 +226,11 @@ int GameSettings::save(){ if(profileOptions){ //Force our directories to exist. MAKEDIR(RESPATH"/profiles"); - string temp = profileFile(); + string temp = profileFile("","",false,false); MAKEDIR(temp.c_str()); temp+="/stats"; MAKEDIR(temp.c_str()); - temp = profileFile(PLAYER_SETTINGS); + temp = profileFile(PLAYER_SETTINGS,"",false); profileOptions->save(); } @@ -290,7 +292,7 @@ void GameSettings::checkProfile(){ //If it doesn't exist, load current profile. if(!profileOptions) - profileOptions = NEW GameOptions(profileFile(PLAYER_SETTINGS)); + profileOptions = NEW GameOptions(profileFile(PLAYER_SETTINGS,"",false)); //Load theme options if(!themeOptions){ @@ -344,7 +346,7 @@ void GameSettings::createUsersFirstDeck(int setId){ if(theGame == NULL || theGame->collection == NULL) return; - MTGDeck *mCollection = NEW MTGDeck(options.profileFile(PLAYER_COLLECTION).c_str(), theGame->collection); + MTGDeck *mCollection = NEW MTGDeck(options.profileFile(PLAYER_COLLECTION,"",false).c_str(), theGame->collection); //10 lands of each int sets[] = {setId}; if (!mCollection->addRandomCards(10, sets,1, Constants::RARITY_L,"Forest")){ diff --git a/projects/mtg/src/GameStateOptions.cpp b/projects/mtg/src/GameStateOptions.cpp index 06f29669b..69e5bd64e 100644 --- a/projects/mtg/src/GameStateOptions.cpp +++ b/projects/mtg/src/GameStateOptions.cpp @@ -42,6 +42,11 @@ void GameStateOptions::Start() optionsTabs = NEW OptionsMenu(); optionsTabs->Add(optionsList); + optionsList = NEW OptionsList("Game"); + optionsList->Add(NEW OptionClosedHand(Options::CLOSEDHAND, "Closed hand")); + optionsList->Add(NEW OptionHandDirection(Options::HANDDIRECTION, "Hand direction")); + optionsTabs->Add(optionsList); + optionsList = NEW OptionsList("Profiles"); OptionNewProfile * key = NEW OptionNewProfile("","New Profile"); key->bShowValue = false; diff --git a/projects/mtg/src/GuiHand.cpp b/projects/mtg/src/GuiHand.cpp index f88096218..864467d9f 100644 --- a/projects/mtg/src/GuiHand.cpp +++ b/projects/mtg/src/GuiHand.cpp @@ -2,6 +2,7 @@ #include "../include/GameApp.h" #include "../include/Trash.h" #include "../include/GuiHand.h" +#include "../include/OptionItem.h" const float GuiHand::ClosedRowX = 459; const float GuiHand::LeftRowX = 420; @@ -9,6 +10,8 @@ const float GuiHand::RightRowX = 460; const float GuiHand::OpenX = 394; const float GuiHand::ClosedX = 494; +const float GuiHand::OpenY = SCREEN_HEIGHT - 50; +const float GuiHand::ClosedY = SCREEN_HEIGHT; bool HandLimitor::select(Target* t) { @@ -77,6 +80,13 @@ void GuiHandOpponent::Render() GuiHandSelf::GuiHandSelf(CardSelector* cs, MTGHand* hand) : GuiHand(cs, hand), state(Closed), backpos(ClosedX, SCREEN_HEIGHT - 250, 1.0, 0, 255) { limitor = NEW HandLimitor(this); + if (OptionHandDirection::HORIZONTAL == options[Options::HANDDIRECTION].number) + { + backpos.t = M_PI/2; + backpos.y = ClosedY; + backpos.x = SCREEN_WIDTH - 30 * 7 - 14; + backpos.UpdateNow(); + } } GuiHandSelf::~GuiHandSelf(){ @@ -86,7 +96,7 @@ GuiHandSelf::~GuiHandSelf(){ void GuiHandSelf::Repos() { float y = 48.0; - if (Closed == state) + if (Closed == state && OptionClosedHand::VISIBLE == options[Options::CLOSEDHAND].number) for (vector::iterator it = cards.begin(); it != cards.end(); ++it) { (*it)->x = ClosedRowX; (*it)->y = y; @@ -94,13 +104,30 @@ void GuiHandSelf::Repos() } else { - bool flip = false; - for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + bool q = (Closed == state); + if (OptionHandDirection::HORIZONTAL == options[Options::HANDDIRECTION].number) { - (*it)->x = flip ? RightRowX : LeftRowX; - (*it)->y = y; - if (flip) y += 65; - flip = !flip; + y = SCREEN_WIDTH - 30; + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + { + (*it)->x = y; + (*it)->y = SCREEN_HEIGHT - 30; + y -= 30; + (*it)->alpha = (q ? 0 : 255); + } + backpos.x = y + SCREEN_HEIGHT - 14; + } + else + { + bool flip = false; + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + { + (*it)->x = flip ? RightRowX : LeftRowX; + (*it)->y = y; + if (flip) y += 65; + flip = !flip; + (*it)->alpha = (q ? 0 : 255); + } } } } @@ -113,9 +140,25 @@ bool GuiHandSelf::CheckUserInput(u32 key) { state = (Open == state ? Closed : Open); if (Open == state) cs->Push(); - cs->Limit(Open == state ? limitor : NULL); + cs->Limit(Open == state ? limitor : NULL, CardSelector::handZone); if (Closed == state) cs->Pop(); - backpos.x = Open == state ? OpenX : ClosedX; + if (OptionHandDirection::HORIZONTAL == options[Options::HANDDIRECTION].number) + backpos.y = Open == state ? OpenY : ClosedY; + else + backpos.x = Open == state ? OpenX : ClosedX; + if (Open == state && OptionClosedHand::INVISIBLE == options[Options::CLOSEDHAND].number) + { + if (OptionHandDirection::HORIZONTAL == options[Options::HANDDIRECTION].number) + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + { + (*it)->y = SCREEN_HEIGHT + 30; (*it)->UpdateNow(); + } + else + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + { + (*it)->x = SCREEN_WIDTH + 30; (*it)->UpdateNow(); + } + } Repos(); return true; } @@ -131,15 +174,17 @@ void GuiHandSelf::Update(float dt) void GuiHandSelf::Render() { backpos.Render(back); - for (vector::iterator it = cards.begin(); it != cards.end(); ++it) - (*it)->Render(); + if (OptionClosedHand::VISIBLE == options[Options::CLOSEDHAND].number || state == Open) + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + (*it)->Render(); } float GuiHandSelf::LeftBoundary() { float min = SCREEN_WIDTH + 10; - for (vector::iterator it = cards.begin(); it != cards.end(); ++it) - if ((*it)->x - CardGui::Width / 2 < min) min = (*it)->x - CardGui::Width / 2; + if (OptionClosedHand::VISIBLE == options[Options::CLOSEDHAND].number || state == Open) + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + if ((*it)->x - CardGui::Width / 2 < min) min = (*it)->x - CardGui::Width / 2; return min; } @@ -191,7 +236,7 @@ int GuiHandOpponent::receiveEventPlus(WEvent* e) card = NEW CardView(CardSelector::handZone, event->card, *(event->card->view)); else card = NEW CardView(CardSelector::handZone, event->card, ClosedRowX, 0); - card->t = -4*M_PI; card->alpha = 255; + card->alpha = 255; card->t = -4*M_PI; cards.push_back(card); return 1; } diff --git a/projects/mtg/src/OptionItem.cpp b/projects/mtg/src/OptionItem.cpp index 79f4522e8..e9a66f749 100644 --- a/projects/mtg/src/OptionItem.cpp +++ b/projects/mtg/src/OptionItem.cpp @@ -810,6 +810,59 @@ void OptionVolume::updateValue(){ value=0; } -OptionVolume::OptionVolume(string _id, string _displayName, bool _bMusic): OptionInteger(_id, _displayName, 100, 10,0,"Muted") { - bMusic = _bMusic; -} \ No newline at end of file +OptionVolume::OptionVolume(string id, string displayName, bool music): OptionInteger(id, displayName, 100, 10, 0, "Muted") { + bMusic = music; +} + +void OptionEnum::setData() +{ + options[id] = GameOption(values[index].first, values[index].second); +} + +void OptionEnum::updateValue() +{ + ++index; + if (index >= values.size()) index = 0; +} + +void OptionEnum::Render() +{ + JLBFont * mFont = resources.GetJLBFont("f3"); + if (hasFocus) + mFont->SetColor(options[Metrics::OPTION_ITEM_TCH].asColor(ARGB(255,255,255,0))); + else + mFont->SetColor(options[Metrics::OPTION_ITEM_TC].asColor()); + JRenderer * renderer = JRenderer::GetInstance(); + renderer->FillRoundRect(x-5,y-2,width-x-5,height,2,options[Metrics::OPTION_ITEM_FC].asColor(ARGB(150,50,50,50))); + mFont->DrawString(displayValue.c_str(),x,y); + mFont->DrawString(values[index].second.c_str(), width -10, y, JGETEXT_RIGHT); +} + +void OptionEnum::Reload() +{ + for (vector::iterator it = values.begin(); it != values.end(); ++it) + if (it->second == options[id].str) + { + index = it - values.begin(); + return; + } + index = 0; +} + +ostream& OptionEnum::toString(ostream& out) const +{ + return (out << values[index].second); +} + +OptionClosedHand::OptionClosedHand(string id, string displayName) : OptionEnum(id, displayName) +{ + values.push_back(assoc(INVISIBLE, "invisible")); + values.push_back(assoc(VISIBLE, "visible")); + Reload(); +}; +OptionHandDirection::OptionHandDirection(string id, string displayName) : OptionEnum(id, displayName) +{ + values.push_back(assoc(VERTICAL, "vertical")); + values.push_back(assoc(HORIZONTAL, "horizontal")); + Reload(); +};