Jeck - Resolved issue 44 and issue 45.

* Options can now use specialized loading functions. OptionEnum should work now.
 * Options are now stored in memory as a map<integer,GameOption>.
This commit is contained in:
wagic.jeck
2009-09-23 00:24:43 +00:00
parent 433897bf38
commit e577f3e378
10 changed files with 650 additions and 244 deletions

View File

@@ -1,46 +1,46 @@
#ifndef _CREDITS_H_ #ifndef _CREDITS_H_
#define _CREDITS_H_ #define _CREDITS_H_
#include <vector> #include <vector>
#include <string> #include <string>
#include <JGE.h> #include <JGE.h>
#include <JLBFont.h> #include <JLBFont.h>
#include "../include/Player.h" #include "../include/Player.h"
class GameApp; class GameApp;
using namespace std; using namespace std;
class CreditBonus{ class CreditBonus{
public: public:
int value; int value;
string text; string text;
CreditBonus(int _value, string _text); CreditBonus(int _value, string _text);
void Render(float x, float y, JLBFont * font); void Render(float x, float y, JLBFont * font);
}; };
class Credits{ class Credits{
private: private:
int isDifficultyUnlocked(); int isDifficultyUnlocked();
int isMomirUnlocked(); int isMomirUnlocked();
int isEvilTwinUnlocked(); int isEvilTwinUnlocked();
int isRandomDeckUnlocked(); int isRandomDeckUnlocked();
int unlockRandomSet(); int unlockRandomSet();
public: public:
int value; int value;
Player * p1, *p2; Player * p1, *p2;
GameApp * app; GameApp * app;
int showMsg; int showMsg;
int unlocked; int unlocked;
JQuad * unlockedQuad; JQuad * unlockedQuad;
JTexture * unlockedTex; JTexture * unlockedTex;
string unlockedString; string unlockedString;
vector<CreditBonus *> bonus; vector<CreditBonus *> bonus;
Credits(); Credits();
~Credits(); ~Credits();
void compute(Player * _p1, Player * _p2, GameApp * _app); void compute(Player * _p1, Player * _p2, GameApp * _app);
void Render(); void Render();
}; };
#endif #endif

View File

@@ -14,25 +14,95 @@ using std::string;
#define PLAYER_SETTINGS "options.txt" #define PLAYER_SETTINGS "options.txt"
#define PLAYER_COLLECTION "collection.dat" #define PLAYER_COLLECTION "collection.dat"
struct Options { #define INVALID_OPTION -1
static const string MUSICVOLUME;
static const string SFXVOLUME; //Note to self-- provide some form of options initialization.
static const string DIFFICULTY_MODE_UNLOCKED;
static const string MOMIR_MODE_UNLOCKED; class Options {
static const string EVILTWIN_MODE_UNLOCKED; public:
static const string RANDOMDECK_MODE_UNLOCKED; friend class GameSettings;
static const string DIFFICULTY; enum {
static const string CACHESIZE; //Values /must/ match ordering in optionNames, or everything loads wrong.
static const string PLASMAEFFECT; //Profile settings
static const string INTERRUPT_SECONDS; ACTIVE_THEME,
static const string INTERRUPTMYSPELLS; ACTIVE_MODE,
static const string INTERRUPTMYABILITIES; MUSICVOLUME,
static const string OSD; SFXVOLUME,
static const string ACTIVE_PROFILE; DIFFICULTY,
static const string ACTIVE_THEME; PLASMAEFFECT,
static const string ACTIVE_MODE; OSD,
static const string CLOSEDHAND; CLOSEDHAND,
static const string HANDDIRECTION; HANDDIRECTION,
INTERRUPT_SECONDS,
//My interrupts
INTERRUPTMYSPELLS,
INTERRUPTMYABILITIES,
//Other interrupts
INTERRUPT_BEFOREBEGIN,
INTERRUPT_UNTAP,
INTERRUPT_UPKEEP,
INTERRUPT_DRAW,
INTERRUPT_FIRSTMAIN,
INTERRUPT_BEGINCOMBAT,
INTERRUPT_ATTACKERS,
INTERRUPT_BLOCKERS,
INTERRUPT_DAMAGE,
INTERRUPT_ENDCOMBAT,
INTERRUPT_SECONDMAIN,
INTERRUPT_ENDTURN,
INTERRUPT_CLEANUP,
INTERRUPT_AFTEREND,
//Global settings
ACTIVE_PROFILE,
DIFFICULTY_MODE_UNLOCKED,
MOMIR_MODE_UNLOCKED,
EVILTWIN_MODE_UNLOCKED,
RANDOMDECK_MODE_UNLOCKED,
CACHESIZE,
//Theme metrics. These will be phased out fairly soon.
THEME_METRICS, //Start of theme metrics.
LOADING_TC = THEME_METRICS,
STATS_TC,
SCROLLER_TC,
SCROLLER_FC,
MAINMENU_TC,
POPUP_MENU_FC,
POPUP_MENU_TC,
POPUP_MENU_TCH,
MSG_FAIL_TC,
OPTION_ITEM_FC,
OPTION_ITEM_TC,
OPTION_ITEM_TCH,
OPTION_HEADER_FC,
OPTION_HEADER_TC,
OPTION_SCROLLBAR_FC,
OPTION_SCROLLBAR_FCH,
OPTION_TAB_FC,
OPTION_TAB_FCH,
OPTION_TAB_TC,
OPTION_TAB_TCH,
OPTION_TEXT_TC,
OPTION_TEXT_FC,
KEY_TC,
KEY_TCH,
KEY_FC,
KEY_FCH,
KEYPAD_FC,
KEYPAD_FCH,
KEYPAD_TC,
LAST_NAMED, //Any option after this does not look up in optionNames.
SET_UNLOCKS = LAST_NAMED + 1, //For sets.
};
static int optionSet(int setID);
static int optionInterrupt(int gamePhase);
static int getID(string name);
static string getName(int option);
private:
static const char* optionNames[];
}; };
struct Metrics { struct Metrics {
@@ -40,35 +110,37 @@ struct Metrics {
//*_FC is fill-color, *_FCH is highlighted fill color //*_FC is fill-color, *_FCH is highlighted fill color
//*_B and *_BH are for secondary text/fill colors, if needed //*_B and *_BH are for secondary text/fill colors, if needed
//*_X, *_Y, *_W, *_H are x, y, width and height. //*_X, *_Y, *_W, *_H are x, y, width and height.
static const string LOADING_TC; enum {
static const string STATS_TC; LOADING_TC = Options::THEME_METRICS,
static const string SCROLLER_TC; STATS_TC,
static const string SCROLLER_FC; SCROLLER_TC,
static const string MAINMENU_TC; SCROLLER_FC,
static const string POPUP_MENU_FC; MAINMENU_TC,
static const string POPUP_MENU_TC; POPUP_MENU_FC,
static const string POPUP_MENU_TCH; POPUP_MENU_TC,
static const string MSG_FAIL_TC; POPUP_MENU_TCH,
static const string OPTION_ITEM_FC; MSG_FAIL_TC,
static const string OPTION_ITEM_TC; OPTION_ITEM_FC,
static const string OPTION_ITEM_TCH; OPTION_ITEM_TC,
static const string OPTION_HEADER_FC; OPTION_ITEM_TCH,
static const string OPTION_HEADER_TC; OPTION_HEADER_FC,
static const string OPTION_SCROLLBAR_FC; OPTION_HEADER_TC,
static const string OPTION_SCROLLBAR_FCH; OPTION_SCROLLBAR_FC,
static const string OPTION_TAB_FC; OPTION_SCROLLBAR_FCH,
static const string OPTION_TAB_FCH; OPTION_TAB_FC,
static const string OPTION_TAB_TC; OPTION_TAB_FCH,
static const string OPTION_TAB_TCH; OPTION_TAB_TC,
static const string OPTION_TEXT_TC; OPTION_TAB_TCH,
static const string OPTION_TEXT_FC; OPTION_TEXT_TC,
static const string KEY_TC; OPTION_TEXT_FC,
static const string KEY_TCH; KEY_TC,
static const string KEY_FC; KEY_TCH,
static const string KEY_FCH; KEY_FC,
static const string KEYPAD_FC; KEY_FCH,
static const string KEYPAD_FCH; KEYPAD_FC,
static const string KEYPAD_TC; KEYPAD_FCH,
KEYPAD_TC,
};
}; };
class GameOption { class GameOption {
@@ -83,6 +155,12 @@ public:
GameOption(int, string); GameOption(int, string);
}; };
struct EnumDefinition {
int findIndex(int value);
typedef pair<int, string> assoc;
vector<assoc> values;
};
class GameOptions { class GameOptions {
public: public:
@@ -90,13 +168,20 @@ class GameOptions {
int save(); int save();
int load(); int load();
static const char * phaseInterrupts[]; GameOption& operator[](int);
GameOption& operator[](string);
GameOptions(string filename); GameOptions(string filename);
~GameOptions(); ~GameOptions();
private: private:
map<string,GameOption> values; bool load_option(int id, string input); //Sends an option to the proper reader.
bool read_default(int id, string input);
bool read_enum(int id, string input, EnumDefinition * def);
bool save_option(std::ofstream * file, int id, string name, GameOption * opt); //Sends an option to the proper writer.
bool write_default(std::ofstream * file, string name, GameOption * opt);
bool write_enum(std::ofstream * file, string name, GameOption * opt, EnumDefinition * def);
map<int,GameOption> values;
}; };
class GameSettings{ class GameSettings{
@@ -124,11 +209,13 @@ public:
void checkProfile(); //Confirms that a profile is loaded and contains a collection. void checkProfile(); //Confirms that a profile is loaded and contains a collection.
void createUsersFirstDeck(int setId); void createUsersFirstDeck(int setId);
GameOption& operator[](string); GameOption& operator[](int);
GameOptions* profileOptions; GameOptions* profileOptions;
GameOptions* globalOptions; GameOptions* globalOptions;
GameOptions* themeOptions; GameOptions* themeOptions;
static GameOption invalid_option;
private: private:
GameApp * theGame; GameApp * theGame;
SimplePad * keypad; SimplePad * keypad;

View File

@@ -5,6 +5,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include "../include/GameApp.h" #include "../include/GameApp.h"
#include "../include/GameOptions.h"
using std::string; using std::string;
@@ -21,7 +22,8 @@ using std::string;
class OptionItem { class OptionItem {
public: public:
string displayValue, id; string displayValue;
int id;
int hasFocus; int hasFocus;
bool canSelect; bool canSelect;
bool bHidden; bool bHidden;
@@ -29,7 +31,7 @@ public:
float width, height; float width, height;
virtual ostream& toString(ostream& out)const; virtual ostream& toString(ostream& out)const;
OptionItem( string _id, string _displayValue); OptionItem( int _id, string _displayValue);
virtual ~OptionItem() {}; virtual ~OptionItem() {};
virtual bool Selectable() {return (canSelect && !bHidden);}; virtual bool Selectable() {return (canSelect && !bHidden);};
@@ -52,9 +54,9 @@ class OptionInteger:public OptionItem{
string strDefault; //What to call the default value. string strDefault; //What to call the default value.
int maxValue, increment; int maxValue, increment;
OptionInteger(string _id, string _displayValue, int _maxValue = 1, int _increment = 1, int _defV = 0, string _sDef = ""); OptionInteger(int _id, string _displayValue, int _maxValue = 1, int _increment = 1, int _defV = 0, string _sDef = "");
virtual void Reload() {if(id != "") value = options[id].number;}; virtual void Reload() {if(id != INVALID_OPTION) value = options[id].number;};
virtual void Render(); virtual void Render();
virtual void setData(); virtual void setData();
virtual void updateValue(){value+=increment; if (value>maxValue) value=0;}; virtual void updateValue(){value+=increment; if (value>maxValue) value=0;};
@@ -64,19 +66,19 @@ class OptionInteger:public OptionItem{
class OptionString:public OptionItem{ class OptionString:public OptionItem{
public: public:
string value; string value;
OptionString(string _id, string _displayValue); OptionString(int _id, string _displayValue);
virtual void Render(); virtual void Render();
virtual void setData(); virtual void setData();
virtual void updateValue(); virtual void updateValue();
virtual void Reload() {if(id != "") value = options[id].str;}; virtual void Reload() {if(id != INVALID_OPTION) value = options[id].str;};
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
bool bShowValue; bool bShowValue;
}; };
class OptionNewProfile:public OptionString{ class OptionNewProfile:public OptionString{
public: public:
OptionNewProfile(string _id, string _displayValue) : OptionString(_id, _displayValue) {bShowValue=false;}; OptionNewProfile(string _displayValue) : OptionString(INVALID_OPTION, _displayValue) {bShowValue=false;};
virtual void updateValue(); virtual void updateValue();
virtual void Update(float dt); virtual void Update(float dt);
virtual int Submode(); virtual int Submode();
@@ -85,7 +87,7 @@ class OptionNewProfile:public OptionString{
class OptionHeader:public OptionItem{ class OptionHeader:public OptionItem{
public: public:
OptionHeader(string _displayValue): OptionItem("", _displayValue) { canSelect=false;}; OptionHeader(string _displayValue): OptionItem(INVALID_OPTION, _displayValue) { canSelect=false;};
virtual void Render(); virtual void Render();
virtual void setData() {}; virtual void setData() {};
virtual void updateValue() {}; virtual void updateValue() {};
@@ -93,7 +95,7 @@ class OptionHeader:public OptionItem{
class OptionText:public OptionItem{ class OptionText:public OptionItem{
public: public:
OptionText(string _displayValue): OptionItem("", _displayValue) { canSelect=false;}; OptionText(string _displayValue): OptionItem(INVALID_OPTION, _displayValue) { canSelect=false;};
virtual void Render(); virtual void Render();
virtual void setData() {}; virtual void setData() {};
virtual void updateValue() {}; virtual void updateValue() {};
@@ -105,7 +107,7 @@ class OptionSelect:public OptionItem{
vector<string> selections; vector<string> selections;
virtual void addSelection(string s); virtual void addSelection(string s);
OptionSelect(string _id, string _displayValue): OptionItem(_id, _displayValue) {value = 0;}; OptionSelect(int _id, string _displayValue): OptionItem(_id, _displayValue) {value = 0;};
virtual void Reload(){initSelections();}; virtual void Reload(){initSelections();};
virtual void Render(); virtual void Render();
virtual void setData(); virtual void setData();
@@ -118,7 +120,7 @@ class OptionSelect:public OptionItem{
class OptionDirectory:public OptionSelect{ class OptionDirectory:public OptionSelect{
public: public:
virtual void Reload(); virtual void Reload();
OptionDirectory(string _root, string _id, string _displayValue); OptionDirectory(string _root, int _id, string _displayValue);
private: private:
string root; string root;
}; };
@@ -130,7 +132,7 @@ class OptionTheme:public OptionDirectory{
class OptionVolume: public OptionInteger{ class OptionVolume: public OptionInteger{
public: public:
OptionVolume(string _id, string _displayName, bool _bMusic = false); OptionVolume(int _id, string _displayName, bool _bMusic = false);
virtual void updateValue(); virtual void updateValue();
private: private:
bool bMusic; bool bMusic;
@@ -208,27 +210,43 @@ class OptionsMenu
class OptionEnum : public OptionItem { class OptionEnum : public OptionItem {
protected: protected:
typedef pair<int, string> assoc;
unsigned index; unsigned index;
vector<assoc> values;
public: public:
OptionEnum(string id, string displayValue) : OptionItem(id, displayValue), index(0) {}; OptionEnum(int id, string displayValue);
virtual void Reload(); virtual void Reload();
virtual void Render(); virtual void Render();
virtual void setData(); virtual void setData();
virtual void updateValue(); virtual void updateValue();
//ourDefined is a virtual wrapper for getDefinition()
virtual EnumDefinition * ourDefined() const {return getDefinition();};
static EnumDefinition * getDefinition();
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
}; };
class OptionClosedHand : public OptionEnum { class OptionClosedHand : public OptionEnum {
public: public:
friend class GameSettings;
enum { INVISIBLE = 0, VISIBLE = 1 }; enum { INVISIBLE = 0, VISIBLE = 1 };
OptionClosedHand(string id, string displayValue); OptionClosedHand(int id, string displayValue);
static EnumDefinition * getDefinition();
EnumDefinition * ourDefined() const { return getDefinition();};
private:
static EnumDefinition * definition;
}; };
class OptionHandDirection : public OptionEnum { class OptionHandDirection : public OptionEnum {
public: public:
friend class GameSettings;
enum { VERTICAL = 0, HORIZONTAL = 1}; enum { VERTICAL = 0, HORIZONTAL = 1};
OptionHandDirection(string id, string displayValue); OptionHandDirection(int id, string displayValue);
static EnumDefinition * getDefinition();
EnumDefinition * ourDefined() const { return getDefinition();};
private:
static EnumDefinition * definition;
}; };
#endif #endif

View File

@@ -103,10 +103,7 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app){
}else if((unlocked = unlockRandomSet())) { }else if((unlocked = unlockRandomSet())) {
unlockedTex = resources.RetrieveTexture("set_unlocked.png", RETRIEVE_VRAM); unlockedTex = resources.RetrieveTexture("set_unlocked.png", RETRIEVE_VRAM);
unlockedQuad = resources.RetrieveQuad("set_unlocked.png", 2, 2, 396, 96); unlockedQuad = resources.RetrieveQuad("set_unlocked.png", 2, 2, 396, 96);
char buffer[4096]; options[Options::optionSet(unlocked - 1)] = GameOption(1);
unlockedString = MtgSets::SetsList->values[unlocked -1];
sprintf(buffer,"unlocked_%s", unlockedString.c_str());
options[buffer] = GameOption(1);
options.save(); options.save();
} }
if (unlocked){ if (unlocked){
@@ -239,9 +236,9 @@ int Credits::isRandomDeckUnlocked(){
int Credits::unlockRandomSet(){ int Credits::unlockRandomSet(){
if (rand() % 2) return 0; if (rand() % 2) return 0;
int setId = rand() % MtgSets::SetsList->nb_items; int setId = rand() % MtgSets::SetsList->nb_items;
char buffer[4096];
string s = MtgSets::SetsList->values[setId]; if (1 == options[Options::optionSet(setId)].number)
sprintf(buffer,"unlocked_%s", s.c_str()); return 0;
if (1 == options[buffer].number) return 0;
return setId + 1; return setId + 1; //We add 1 here to show success/failure. Be sure to subtract later.
} }

View File

@@ -165,13 +165,13 @@ void GameObserver::userRequestNextGamePhase(){
Phase * cPhaseOld = phaseRing->getCurrentPhase(); Phase * cPhaseOld = phaseRing->getCurrentPhase();
if ((cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == ORDER) || if ((cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == ORDER) ||
cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE || cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE ||
opponent()->isAI() || opponent()->isAI() ||
options[GameOptions::phaseInterrupts[currentGamePhase]].number) options[Options::optionInterrupt(currentGamePhase)].number)
mLayers->stackLayer()->AddNextGamePhase(); mLayers->stackLayer()->AddNextGamePhase();
else else
nextGamePhase(); nextGamePhase();
} }

View File

@@ -2,49 +2,188 @@
#include "../include/utils.h" #include "../include/utils.h"
#include "../include/MTGDeck.h" #include "../include/MTGDeck.h"
#include "../include/GameOptions.h" #include "../include/GameOptions.h"
#include "../include/OptionItem.h"
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <stdlib.h> #include <stdlib.h>
#include <JGE.h> #include <JGE.h>
const char* GameOptions::phaseInterrupts[] = { const char * Options::optionNames[] = {
"interrupt ---", //Options set on a per-profile basis
"interrupt Untap", "Theme",
"interrupt Upkeep", "Mode",
"interrupt Draw", "musicVolume",
"interrupt Main phase 1", "sfxVolume",
"interrupt Combat begins", "difficulty",
"interrupt Attackers", "plasmaEffect",
"interrupt Blockers", "displayOSD",
"interrupt Combat damage", "closed_hand",
"interrupt Combat ends", "hand_direction",
"interrupt Main phase 2", "interruptSeconds",
"interrupt End of turn", "interruptMySpells",
"interrupt Cleanup", "interruptMyAbilities",
"interrupt ---" //General interrupts
}; "interruptBeforeBegin",
//Profile options "interruptUntap",
const string Options::MUSICVOLUME = "musicVolume"; "interruptUpkeep",
const string Options::SFXVOLUME = "sfxVolume"; "interruptDraw",
const string Options::DIFFICULTY = "difficulty"; "interruptFirstMain",
const string Options::PLASMAEFFECT = "plasmaEffect"; "interruptBeginCombat",
const string Options::INTERRUPT_SECONDS = "interruptSeconds"; "interruptAttackers",
const string Options::INTERRUPTMYSPELLS = "interruptMySpells"; "interruptBlockers",
const string Options::INTERRUPTMYABILITIES = "interruptMyAbilities"; "interruptDamage",
const string Options::OSD = "displayOSD"; "interruptEndCombat",
const string Options::ACTIVE_THEME = "Theme"; "interruptSecondMain",
const string Options::ACTIVE_MODE = "Mode"; "interruptEndTurn",
"interruptCleanup",
"interruptAfterEnd",
//Global options //Global options
const string Options::ACTIVE_PROFILE = "_gProfile"; "_gProfile",
const string Options::DIFFICULTY_MODE_UNLOCKED = "_gprx_handler"; //huhu "_gprx_handler",
const string Options::MOMIR_MODE_UNLOCKED = "_gprx_rimom"; //haha "_gprx_rimom",
const string Options::EVILTWIN_MODE_UNLOCKED = "_gprx_eviltwin"; "_gprx_eviltwin",
const string Options::RANDOMDECK_MODE_UNLOCKED = "_gprx_rnddeck"; "_gprx_rnddeck",
const string Options::CACHESIZE = "_gcacheSize"; "_gcacheSize",
const string Options::CLOSEDHAND = "closed_hand";
const string Options::HANDDIRECTION = "hand_direction";
//Theme metrics //Theme metrics
"_tLoadingTC",
"_tStatsTC",
"_tScrollerTC",
"_tScrollerFC",
"_tMainMenuTC",
"_tPopupMenuFC",
"_tPopupMenuTC",
"_tPopupMenuTCH",
"_tMsgFailTC",
"_tOptionItemFC",
"_tOptionItemTC",
"_tOptionItemTCH",
"_tOptionHeaderFC",
"_tOptionHeaderTC",
"_tOptionScrollbarFC",
"_tOptionScrollbarFCH",
"_tOptionHeaderFC",
"_tOptionHeaderFCH",
"_tOptionTabTC",
"_tOptionHeaderTCH",
"_tOptionTextTC",
"_tOptionTextFC",
"_tKeyTC",
"_tKeyTCH",
"_tKeyFC",
"_tKeyFCH",
"_tKeypadFC",
"_tKeypadFCH",
"_tKeypadTC"
};
int Options::getID(string name){
if(!name.size())
INVALID_OPTION;
std::transform(name.begin(),name.end(),name.begin(),::tolower);
//Is it a named option?
for(int x = 0; x < LAST_NAMED; x++){
string lower = Options::optionNames[x];
std::transform(lower.begin(),lower.end(),lower.begin(),::tolower);
if(lower == name)
return x;
}
//Is it an unlocked set?
if(MtgSets::SetsList){
int unlocked = MtgSets::SetsList->find(name);
if(unlocked != -1)
return Options::optionSet(unlocked);
}
//Failure.
return INVALID_OPTION;
}
string Options::getName(int option){
//Invalid options
if(option < 0)
return "";
//Standard named options
if(option < LAST_NAMED)
return optionNames[option];
//Unlocked sets.
if(MtgSets::SetsList){
int setID = option - SET_UNLOCKS;
if(setID >= 0 && setID < MtgSets::SetsList->nb_items){
char buf[512];
sprintf(buf,"unlocked_%s",MtgSets::SetsList->values[setID].c_str());
return buf;
}
}
//Failed.
return "";
}
int Options::optionSet(int setID){
//Sanity check if possible
if(setID < 0 || (MtgSets::SetsList && setID > MtgSets::SetsList->nb_items))
return INVALID_OPTION;
return SET_UNLOCKS + setID;
}
int Options::optionInterrupt(int gamePhase){
//Huge, nearly illegible switch block spread out to improve readability.
switch(gamePhase){
case Constants::MTG_PHASE_BEFORE_BEGIN:
return INTERRUPT_BEFOREBEGIN;
case Constants::MTG_PHASE_UNTAP:
return INTERRUPT_UNTAP;
case Constants::MTG_PHASE_UPKEEP:
return INTERRUPT_UPKEEP;
case Constants::MTG_PHASE_DRAW:
return INTERRUPT_DRAW;
case Constants::MTG_PHASE_FIRSTMAIN:
return INTERRUPT_FIRSTMAIN;
case Constants::MTG_PHASE_COMBATBEGIN:
return INTERRUPT_BEGINCOMBAT;
case Constants::MTG_PHASE_COMBATATTACKERS:
return INTERRUPT_ATTACKERS;
case Constants::MTG_PHASE_COMBATBLOCKERS:
return INTERRUPT_BLOCKERS;
case Constants::MTG_PHASE_COMBATDAMAGE:
return INTERRUPT_DAMAGE;
case Constants::MTG_PHASE_COMBATEND:
return INTERRUPT_ENDCOMBAT;
case Constants::MTG_PHASE_SECONDMAIN:
return INTERRUPT_SECONDMAIN;
case Constants::MTG_PHASE_ENDOFTURN:
return INTERRUPT_ENDTURN;
case Constants::MTG_PHASE_CLEANUP:
return INTERRUPT_CLEANUP;
case Constants::MTG_PHASE_AFTER_EOT:
return INTERRUPT_AFTEREND;
}
return INVALID_OPTION;
}
//Theme metrics
/*
const string Metrics::LOADING_TC = "_tLoadingTC"; const string Metrics::LOADING_TC = "_tLoadingTC";
const string Metrics::STATS_TC = "_tStatsTC"; const string Metrics::STATS_TC = "_tStatsTC";
const string Metrics::SCROLLER_TC = "_tScrollerTC"; const string Metrics::SCROLLER_TC = "_tScrollerTC";
@@ -73,7 +212,7 @@ const string Metrics::KEY_FC = "_tKeyFC";
const string Metrics::KEY_FCH = "_tKeyFCH"; const string Metrics::KEY_FCH = "_tKeyFCH";
const string Metrics::KEYPAD_FC = "_tKeypadFC"; const string Metrics::KEYPAD_FC = "_tKeypadFC";
const string Metrics::KEYPAD_FCH = "_tKeypadFCH"; const string Metrics::KEYPAD_FCH = "_tKeypadFCH";
const string Metrics::KEYPAD_TC = "_tKeypadTC"; const string Metrics::KEYPAD_TC = "_tKeypadTC"; */
GameOption::GameOption(int value) : number(value){} GameOption::GameOption(int value) : number(value){}
@@ -130,6 +269,59 @@ GameOptions::GameOptions(string filename){
mFilename = filename; mFilename = filename;
load(); load();
} }
bool GameOptions::read_default(int id, string input){
bool bNumeric = true;
if(!input.size()){
values[id] = GameOption(0);
return true; //Default reader doesn't care about invalid formatting.
}
//Is it a number?
for(size_t x=0;x<input.size();x++) {
if(!isdigit(input[x])) {
bNumeric = false;
break;
}
}
if(bNumeric)
values[id] = GameOption(atoi(input.c_str()));
else
values[id] = GameOption(input);
return true;
}
bool GameOptions::read_enum(int id, string input, EnumDefinition * def){
if(!def)
return false;
std::transform(input.begin(),input.end(),input.begin(),::tolower);
vector<EnumDefinition::assoc>::iterator it;
for(it=def->values.begin();it != def->values.end();it++){
if(it->second == input){
values[id] = GameOption(it->first);
return true;
}
}
return false;
}
bool GameOptions::load_option(int id, string input){
switch(id){
case Options::HANDDIRECTION:
return read_enum(id, input, OptionHandDirection::getDefinition());
case Options::CLOSEDHAND:
return read_enum(id, input, OptionClosedHand::getDefinition());
default:
return read_default(id, input);
}
return false;
}
int GameOptions::load(){ int GameOptions::load(){
std::ifstream file(mFilename.c_str()); std::ifstream file(mFilename.c_str());
std::string s; std::string s;
@@ -137,47 +329,91 @@ int GameOptions::load(){
if(file){ if(file){
while(std::getline(file,s)){ while(std::getline(file,s)){
int found =s.find("="); int found =s.find("=");
bool bnumber = true;
string name = s.substr(0,found); string name = s.substr(0,found);
string val = s.substr(found+1); string val = s.substr(found+1);
for(size_t x=0;x<val.size();x++) { int id = Options::getID(name);
if(!isdigit(val[x])) { if(id == INVALID_OPTION)
bnumber = false; continue;
break;
} load_option(id,val);
}
if(bnumber)
values[name] = GameOption(atoi(val.c_str()));
else
values[name] = GameOption(val);
} }
file.close(); file.close();
} }
return 1; return 1;
} }
bool GameOptions::save_option(std::ofstream * file, int id, string name, GameOption * opt){
if(!opt)
return false;
switch(id){
case Options::HANDDIRECTION:
return write_enum(file, name, opt, OptionHandDirection::getDefinition());
case Options::CLOSEDHAND:
return write_enum(file, name, opt, OptionClosedHand::getDefinition());
default:
return write_default(file, name, opt);
}
return false;
}
bool GameOptions::write_default(std::ofstream * file, string name, GameOption * opt){
char writer[1024];
if(!file || !opt)
return false;
if(opt->str ==""){
if(opt->number == 0) //This is absolutely default. No need to write it.
return true;
//It's a number!
sprintf(writer,"%s=%d\n", name.c_str(), opt->number);
}
else
sprintf(writer,"%s=%s\n", name.c_str(), opt->str.c_str());
(*file)<<writer;
return true;
}
bool GameOptions::write_enum(std::ofstream * file, string name, GameOption * opt, EnumDefinition * def){
if(!file || !def || !opt)
return false;
if(opt->number < 0 || opt->number >= (int) def->values.size())
return false;
char writer[1024];
sprintf(writer,"%s=%s\n", name.c_str(), def->values[opt->number].second.c_str());
(*file)<<writer;
return true;
}
int GameOptions::save(){ int GameOptions::save(){
std::ofstream file(mFilename.c_str()); std::ofstream file(mFilename.c_str());
char writer[1024];
if (file){ if (file){
map<string, GameOption>::iterator it; map<int, GameOption>::iterator it;
for ( it=values.begin() ; it != values.end(); it++ ){ for ( it=values.begin() ; it != values.end(); it++ ){
if(it->second.str ==""){
sprintf(writer,"%s=%d\n", it->first.c_str(), it->second.number); //Check that this is a valid option.
if(it->second.number==0) string name = Options::getName(it->first);
continue; if(!name.size())
} continue;
else
sprintf(writer,"%s=%s\n", it->first.c_str(), it->second.str.c_str()); //Save it.
file<<writer; save_option(&file, it->first, name, &it->second);
} }
file.close(); file.close();
} }
return 1; return 1;
} }
GameOption& GameOptions::operator[](string option_name) { GameOption& GameOptions::operator[](int optionID) {
return values[option_name]; return values[optionID];
} }
GameOptions::~GameOptions(){ GameOptions::~GameOptions(){
@@ -206,19 +442,35 @@ GameSettings::~GameSettings(){
SAFE_DELETE(globalOptions); SAFE_DELETE(globalOptions);
SAFE_DELETE(profileOptions); SAFE_DELETE(profileOptions);
SAFE_DELETE(themeOptions); SAFE_DELETE(themeOptions);
SAFE_DELETE(OptionHandDirection::definition);
SAFE_DELETE(OptionClosedHand::definition);
} }
GameOption& GameSettings::operator[](string option_name){ GameOption GameSettings::invalid_option = GameOption(0);
if(option_name.size() > 2){
if(option_name[0] == '_' && option_name[1] == 't') GameOption& GameSettings::operator[](int optionID){
return (*themeOptions)[option_name.substr(2)]; string option_name = Options::getName(optionID);
else if(option_name[0] == '_' && option_name[1] == 'g')
return (*globalOptions)[option_name.substr(2)]; //Last chance sanity checking.
if(!option_name.size()){
OutputDebugString("Error: Accessing invalid option.\n");
invalid_option.number = 0;
invalid_option.str = "";
return invalid_option;
} }
return (*profileOptions)[option_name]; if(option_name.size() > 2){
if(option_name[0] == '_' && option_name[1] == 't')
return (*themeOptions)[optionID];
else if(option_name[0] == '_' && option_name[1] == 'g')
return (*globalOptions)[optionID];
}
return (*profileOptions)[optionID];
} }
int GameSettings::save(){ int GameSettings::save(){
if(globalOptions) if(globalOptions)
globalOptions->save(); globalOptions->save();
@@ -308,7 +560,7 @@ void GameSettings::checkProfile(){
if(theGame == NULL || theGame->collection == NULL) if(theGame == NULL || theGame->collection == NULL)
return; return;
string pcFile = profileFile(PLAYER_COLLECTION); string pcFile = profileFile(PLAYER_COLLECTION,"",false);
if(!pcFile.size() || !fileExists(pcFile.c_str())) if(!pcFile.size() || !fileExists(pcFile.c_str()))
{ {
//If we had any default settings, we'd set them here. //If we had any default settings, we'd set them here.
@@ -324,11 +576,21 @@ void GameSettings::checkProfile(){
} }
} }
//Make the proper directories
if(profileOptions){
//Force our directories to exist.
MAKEDIR(RESPATH"/profiles");
string temp = profileFile("","",false,false);
MAKEDIR(temp.c_str());
temp+="/stats";
MAKEDIR(temp.c_str());
temp = profileFile(PLAYER_SETTINGS,"",false);
profileOptions->save();
}
//Save this set as "unlocked" //Save this set as "unlocked"
char buffer[4096]; (*profileOptions)[Options::optionSet(setId)]=1;
string s = MtgSets::SetsList->values[setId];
sprintf(buffer,"unlocked_%s", s.c_str());
(*profileOptions)[buffer]=1;
profileOptions->save(); profileOptions->save();
//Give the player their first deck //Give the player their first deck
@@ -411,3 +673,13 @@ string GameSettings::keypadFinish(){
void GameSettings::keypadShutdown(){ void GameSettings::keypadShutdown(){
SAFE_DELETE(keypad); SAFE_DELETE(keypad);
} }
int EnumDefinition::findIndex(int value){
vector<assoc>::iterator it;
for(it = values.begin();it!=values.end();it++){
if(it->first == value)
return it - values.begin();
}
return 0; //Default!
}

View File

@@ -188,7 +188,6 @@ void GameStateMenu::fillScroller(){
int totalGames = 0; int totalGames = 0;
for (int j=1; j<6; j++){ for (int j=1; j<6; j++){
sprintf(buffer, "stats/player_deck%i.txt",j); sprintf(buffer, "stats/player_deck%i.txt",j);
string deckstats = options.profileFile(buffer); string deckstats = options.profileFile(buffer);
if(fileExists(deckstats.c_str())){ if(fileExists(deckstats.c_str())){
@@ -224,9 +223,7 @@ void GameStateMenu::fillScroller(){
//Unlocked sets //Unlocked sets
int nbunlocked = 0; int nbunlocked = 0;
for (int i = 0; i < MtgSets::SetsList->nb_items; i++){ for (int i = 0; i < MtgSets::SetsList->nb_items; i++){
string s = MtgSets::SetsList->values[i]; if (1 == options[Options::optionSet(i)].number) nbunlocked++;
sprintf(buffer,"unlocked_%s", s.c_str());
if (1 == options[buffer].number) nbunlocked++;
} }
sprintf(buff2, _("You have unlocked %i expansions out of %i").c_str(),nbunlocked, MtgSets::SetsList->nb_items); sprintf(buff2, _("You have unlocked %i expansions out of %i").c_str(),nbunlocked, MtgSets::SetsList->nb_items);
scroller->Add(buff2); scroller->Add(buff2);

View File

@@ -48,7 +48,7 @@ void GameStateOptions::Start()
optionsTabs->Add(optionsList); optionsTabs->Add(optionsList);
optionsList = NEW OptionsList("Profiles"); optionsList = NEW OptionsList("Profiles");
OptionNewProfile * key = NEW OptionNewProfile("","New Profile"); OptionNewProfile * key = NEW OptionNewProfile("New Profile");
key->bShowValue = false; key->bShowValue = false;
optionsList->Add(key); optionsList->Add(key);
OptionProfile * pickProf = NEW OptionProfile(mParent); OptionProfile * pickProf = NEW OptionProfile(mParent);

View File

@@ -71,18 +71,14 @@ void GameStateShop::load(){
for (int i = 0; i < MtgSets::SetsList->nb_items; i++){ for (int i = 0; i < MtgSets::SetsList->nb_items; i++){
string s = MtgSets::SetsList->values[i]; string s = MtgSets::SetsList->values[i];
if (s.compare("10E") == 0) defaultSet = i; if (s.compare("10E") == 0) defaultSet = i;
char buffer[4096];
sprintf(buffer,"unlocked_%s", s.c_str()); unlocked[i] = options[Options::optionSet(i)].number;
unlocked[i] = options[buffer].number;
if (unlocked[i]) if (unlocked[i])
ok = 1; ok = 1;
} }
if (!ok){ if (!ok){
unlocked[defaultSet] = 1; unlocked[defaultSet] = 1;
string s = MtgSets::SetsList->values[defaultSet]; options[Options::optionSet(defaultSet)] = GameOption(1);
char buffer[4096];
sprintf(buffer,"unlocked_%s", s.c_str());
options[buffer] = GameOption(1);
options.save(); options.save();
} }

View File

@@ -1,8 +1,6 @@
#include "../include/config.h" #include "../include/config.h"
#include "../include/OptionItem.h" #include "../include/OptionItem.h"
#include "../include/GameApp.h"
#include <JGE.h> #include <JGE.h>
#include "../include/GameOptions.h"
#include "../include/PlayerData.h" #include "../include/PlayerData.h"
#include "../include/Translate.h" #include "../include/Translate.h"
#include <dirent.h> #include <dirent.h>
@@ -34,7 +32,7 @@ return out << "OptionItem ::: displayValue : " << displayValue
<< " ; x,y : " << x << "," << y; << " ; x,y : " << x << "," << y;
} }
OptionItem::OptionItem( string _id, string _displayValue) { OptionItem::OptionItem( int _id, string _displayValue) {
id = _id; id = _id;
displayValue = _(_displayValue); displayValue = _(_displayValue);
canSelect=true; canSelect=true;
@@ -72,7 +70,7 @@ void OptionInteger::Render(){
mFont->DrawString(buf,width -10 ,y,JGETEXT_RIGHT); mFont->DrawString(buf,width -10 ,y,JGETEXT_RIGHT);
} }
OptionInteger::OptionInteger(string _id, string _displayValue, int _maxValue, int _increment, int _defV, string _sDef): OptionItem(_id, _displayValue){ OptionInteger::OptionInteger(int _id, string _displayValue, int _maxValue, int _increment, int _defV, string _sDef): OptionItem(_id, _displayValue){
defValue = _defV; defValue = _defV;
strDefault = _sDef; strDefault = _sDef;
maxValue = _maxValue; maxValue = _maxValue;
@@ -84,7 +82,7 @@ OptionInteger::OptionInteger(string _id, string _displayValue, int _maxValue, in
} }
void OptionInteger::setData(){ void OptionInteger::setData(){
if(id != "") if(id != INVALID_OPTION)
options[id] = GameOption(value); options[id] = GameOption(value);
} }
@@ -130,7 +128,8 @@ void OptionSelect::Render(){
void OptionSelect::setData() void OptionSelect::setData()
{ {
if(id == "") return; if(id == INVALID_OPTION) return;
if (value < selections.size()) if (value < selections.size())
options[id] = GameOption(selections[value]); options[id] = GameOption(selections[value]);
} }
@@ -356,7 +355,7 @@ void OptionDirectory::Reload(){
initSelections(); initSelections();
} }
OptionDirectory::OptionDirectory(string _root, string _id, string _displayValue): OptionSelect(_id, _displayValue){ OptionDirectory::OptionDirectory(string _root, int _id, string _displayValue): OptionSelect(_id, _displayValue){
DIR *mDip; DIR *mDip;
struct dirent *mDit; struct dirent *mDit;
char buf[4096]; char buf[4096];
@@ -741,8 +740,8 @@ void OptionString::Render(){
} }
void OptionString::setData(){ void OptionString::setData(){
if(id != "") if(id != INVALID_OPTION)
options[id] = GameOption(value); options[id] = GameOption(value);
} }
void OptionString::updateValue(){ void OptionString::updateValue(){
options.keypadStart(value,&value); options.keypadStart(value,&value);
@@ -780,10 +779,10 @@ int OptionNewProfile::Submode(){
return OPTIONS_SUBMODE_NORMAL; return OPTIONS_SUBMODE_NORMAL;
} }
OptionString::OptionString(string _id, string _displayValue): OptionItem(_id, _displayValue) OptionString::OptionString(int _id, string _displayValue): OptionItem(_id, _displayValue)
{ {
bShowValue=true; bShowValue=true;
if(_id != "") if(id != INVALID_OPTION)
value=options[_id].str; value=options[_id].str;
} }
@@ -810,23 +809,31 @@ void OptionVolume::updateValue(){
value=0; value=0;
} }
OptionVolume::OptionVolume(string id, string displayName, bool music): OptionInteger(id, displayName, 100, 10, 0, "Muted") { OptionVolume::OptionVolume(int id, string displayName, bool music): OptionInteger(id, displayName, 100, 10, 0, "Muted") {
bMusic = music; bMusic = music;
} }
void OptionEnum::setData() void OptionEnum::setData()
{ {
options[id] = GameOption(values[index].first, values[index].second); EnumDefinition * def = ourDefined();
if(def)
options[id] = GameOption(def->values[index].first);
} }
void OptionEnum::updateValue() void OptionEnum::updateValue()
{ {
EnumDefinition * def = ourDefined();
if(!def)
return;
++index; ++index;
if (index >= values.size()) index = 0; if (index >= def->values.size()) index = 0;
} }
void OptionEnum::Render() void OptionEnum::Render()
{ {
EnumDefinition * def = ourDefined();
JLBFont * mFont = resources.GetJLBFont("f3"); JLBFont * mFont = resources.GetJLBFont("f3");
if (hasFocus) if (hasFocus)
mFont->SetColor(options[Metrics::OPTION_ITEM_TCH].asColor(ARGB(255,255,255,0))); mFont->SetColor(options[Metrics::OPTION_ITEM_TCH].asColor(ARGB(255,255,255,0)));
@@ -835,34 +842,66 @@ void OptionEnum::Render()
JRenderer * renderer = JRenderer::GetInstance(); 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))); 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(displayValue.c_str(),x,y);
mFont->DrawString(values[index].second.c_str(), width -10, y, JGETEXT_RIGHT);
if(def)
mFont->DrawString(def->values[index].second.c_str(), width -10, y, JGETEXT_RIGHT);
else
mFont->DrawString("Default", width -10, y, JGETEXT_RIGHT);
}
OptionEnum::OptionEnum(int id, string displayValue) : OptionItem(id, displayValue){
Reload();
} }
void OptionEnum::Reload() void OptionEnum::Reload()
{ {
for (vector<assoc>::iterator it = values.begin(); it != values.end(); ++it) EnumDefinition * def = ourDefined();
if (it->second == options[id].str) if(def != NULL)
{ index = def->findIndex(options[id].number);
index = it - values.begin(); }
return;
} EnumDefinition * OptionEnum::getDefinition(){
index = 0; return NULL;
} }
ostream& OptionEnum::toString(ostream& out) const ostream& OptionEnum::toString(ostream& out) const
{ {
return (out << values[index].second); EnumDefinition * def = ourDefined();
if(!def)
return (out << "OptionEnum ::: INVALID");
return (out << "OptionEnum ::: " << def->values[index].second);
} }
OptionClosedHand::OptionClosedHand(string id, string displayName) : OptionEnum(id, displayName) EnumDefinition * OptionClosedHand::definition = NULL;
EnumDefinition * OptionClosedHand::getDefinition(){
if(!definition){
definition = NEW EnumDefinition();
definition->values.push_back(EnumDefinition::assoc(INVISIBLE, "invisible"));
definition->values.push_back(EnumDefinition::assoc(VISIBLE, "visible"));
}
return definition;
}
OptionClosedHand::OptionClosedHand(int id, string displayName) : OptionEnum(id, displayName)
{ {
values.push_back(assoc(INVISIBLE, "invisible")); getDefinition();
values.push_back(assoc(VISIBLE, "visible"));
Reload(); Reload();
}; };
OptionHandDirection::OptionHandDirection(string id, string displayName) : OptionEnum(id, displayName)
EnumDefinition * OptionHandDirection::definition = NULL;
EnumDefinition * OptionHandDirection::getDefinition(){
if(!definition){
definition = NEW EnumDefinition();
definition->values.push_back(EnumDefinition::assoc(VERTICAL, "vertical"));
definition->values.push_back(EnumDefinition::assoc(HORIZONTAL, "horizontal"));
}
return definition;
}
OptionHandDirection::OptionHandDirection(int id, string displayName) : OptionEnum(id, displayName)
{ {
values.push_back(assoc(VERTICAL, "vertical")); getDefinition();
values.push_back(assoc(HORIZONTAL, "horizontal"));
Reload(); Reload();
}; };