New descriptive text popup feature for deck selection

http://wololo.net/forum/viewtopic.php?f=13&t=2423
This commit is contained in:
techdragon.nguyen@gmail.com
2010-11-18 15:48:48 +00:00
parent f7bcbb42dc
commit 2a8f8074e6
17 changed files with 5715 additions and 5198 deletions
+124 -123
View File
@@ -1,123 +1,124 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// //
// JGE++ is a hardware accelerated 2D game SDK for PSP/Windows. // JGE++ is a hardware accelerated 2D game SDK for PSP/Windows.
// //
// Licensed under the BSD license, see LICENSE in JGE root for details. // Licensed under the BSD license, see LICENSE in JGE root for details.
// //
// Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) <jhkhui@gmail.com> // Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) <jhkhui@gmail.com>
// //
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
#ifndef _JGUI_H #ifndef _JGUI_H
#define _JGUI_H #define _JGUI_H
#include <ostream> #include <ostream>
#include "JGE.h" #include "JGE.h"
#include "JSprite.h" #include "JSprite.h"
#define MAX_GUIOBJECT 64 #define MAX_GUIOBJECT 64
#define JGUI_STYLE_LEFTRIGHT 0x01 #define JGUI_STYLE_LEFTRIGHT 0x01
#define JGUI_STYLE_UPDOWN 0x02 #define JGUI_STYLE_UPDOWN 0x02
#define JGUI_STYLE_WRAPPING 0x04 #define JGUI_STYLE_WRAPPING 0x04
#define JGUI_INITIAL_DELAY 0.4 #define JGUI_INITIAL_DELAY 0.4
#define JGUI_REPEAT_DELAY 0.2 #define JGUI_REPEAT_DELAY 0.2
const int kCancelMenuID = -1; const int kCancelMenuID = -1;
const int kInfoMenuID = -200;
class JGuiListener
{ class JGuiListener
public: {
virtual ~JGuiListener() {} public:
virtual void ButtonPressed(int controllerId, int controlId) = 0; virtual ~JGuiListener()
}; {
}
virtual void ButtonPressed(int controllerId, int controlId) = 0;
class JGuiObject };
{
protected: class JGuiObject
static JGE* mEngine; {
protected:
private: static JGE* mEngine;
int mId;
private:
int mId;
public:
JGuiObject(int id); public:
virtual ~JGuiObject(); JGuiObject(int id);
virtual ~JGuiObject();
virtual void Render() = 0;
virtual std::ostream& toString(std::ostream&) const = 0; virtual void Render() = 0;
virtual void Update(float dt); virtual std::ostream& toString(std::ostream&) const = 0;
virtual void Update(float dt);
virtual void Entering(); // when focus is transferring to this obj
virtual bool Leaving(JButton key); // when focus is transferring away from this obj, true to go ahead virtual void Entering(); // when focus is transferring to this obj
virtual bool ButtonPressed(); // action button pressed, return false to ignore virtual bool Leaving(JButton key); // when focus is transferring away from this obj, true to go ahead
virtual bool ButtonPressed(); // action button pressed, return false to ignore
// Used for mouse support so that the GUI engine can found out which Object was selected
virtual bool getTopLeft(int& top, int& left) {return false;}; // Used for mouse support so that the GUI engine can found out which Object was selected
virtual bool getTopLeft(int& top, int& left)
int GetId(); {
}; return false;
}
;
class JGuiController
{ int GetId();
protected: };
static JGE* mEngine;
class JGuiController
int mId; {
bool mActive; protected:
static JGE* mEngine;
JButton mActionButton; int mId;
JButton mCancelButton; bool mActive;
int mCurr;
int mStyle; JButton mActionButton;
JButton mCancelButton;
JSprite* mCursor; int mCurr;
bool mShowCursor; int mStyle;
int mCursorX;
int mCursorY; JSprite* mCursor;
bool mShowCursor;
int mBgX; int mCursorX;
int mBgY; int mCursorY;
const JTexture* mBg;
PIXEL_TYPE mShadingColor; int mBgX;
Rect* mShadingBg; int mBgY;
const JTexture* mBg;
JGuiListener* mListener; PIXEL_TYPE mShadingColor;
//int mKeyHoldTime; Rect* mShadingBg;
public: JGuiListener* mListener;
vector<JGuiObject*> mObjects; //int mKeyHoldTime;
int mCount;
public:
JGuiController(int id, JGuiListener* listener); vector<JGuiObject*> mObjects;
~JGuiController(); int mCount;
virtual void Render(); JGuiController(int id, JGuiListener* listener);
virtual void Update(float dt); ~JGuiController();
virtual bool CheckUserInput(JButton key);
virtual void Render();
void Add(JGuiObject* ctrl); virtual void Update(float dt);
void RemoveAt(int i); virtual bool CheckUserInput(JButton key);
void Remove(int id);
void Remove(JGuiObject* ctrl); void Add(JGuiObject* ctrl);
void RemoveAt(int i);
void SetActionButton(JButton button); void Remove(int id);
void SetStyle(int style); void Remove(JGuiObject* ctrl);
void SetCursor(JSprite* cursor);
void SetActionButton(JButton button);
bool IsActive(); void SetStyle(int style);
void SetActive(bool flag); void SetCursor(JSprite* cursor);
//void SetImageBackground(const JTexture* tex, int x, int y); bool IsActive();
//void SetShadingBackground(int x, int y, int width, int height, PIXEL_TYPE color); void SetActive(bool flag);
};
};
ostream& operator<<(ostream &out, const JGuiObject &j);
ostream& operator<<(ostream &out, const JGuiObject &j);
#endif
#endif
+256 -247
View File
@@ -1,247 +1,256 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// //
// JGE++ is a hardware accelerated 2D game SDK for PSP/Windows. // JGE++ is a hardware accelerated 2D game SDK for PSP/Windows.
// //
// Licensed under the BSD license, see LICENSE in JGE root for details. // Licensed under the BSD license, see LICENSE in JGE root for details.
// //
// Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) <jhkhui@gmail.com> // Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) <jhkhui@gmail.com>
// //
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
#include "../include/JGE.h" #include "../include/JGE.h"
#include "../include/JGui.h" #include "../include/JGui.h"
JGE* JGuiObject::mEngine = NULL; JGE* JGuiObject::mEngine = NULL;
JGE* JGuiController::mEngine = NULL; JGE* JGuiController::mEngine = NULL;
JGuiObject::JGuiObject(int id) :
JGuiObject::JGuiObject(int id): mId(id) mId(id)
{ {
mEngine = JGE::GetInstance(); mEngine = JGE::GetInstance();
} }
JGuiObject::~JGuiObject()
JGuiObject::~JGuiObject() {
{ // JGERelease();
// JGERelease(); }
}
bool JGuiObject::Leaving(JButton key __attribute__((unused)))
{
bool JGuiObject::Leaving(JButton key __attribute__((unused))) return true;
{ }
return true;
} bool JGuiObject::ButtonPressed()
{
return false;
bool JGuiObject::ButtonPressed() }
{
return false; void JGuiObject::Entering()
} {
}
void JGuiObject::Entering()
{ int JGuiObject::GetId()
{
} return mId;
}
int JGuiObject::GetId() void JGuiObject::Update(float dt __attribute__((unused)))
{ {
return mId; }
}
ostream& operator<<(ostream &out, const JGuiObject &j)
{
void JGuiObject::Update(float dt __attribute__((unused))) return j.toString(out);
{ }
}
JGuiController::JGuiController(int id, JGuiListener* listener) :
ostream& operator<<(ostream &out, const JGuiObject &j) mId(id), mListener(listener)
{ {
return j.toString(out); mEngine = JGE::GetInstance();
}
mBg = NULL;
JGuiController::JGuiController(int id, JGuiListener* listener) : mId(id), mListener(listener) mShadingBg = NULL;
{
mEngine = JGE::GetInstance(); mCount = 0;
mCurr = 0;
mBg = NULL;
mShadingBg = NULL; mCursorX = SCREEN_WIDTH / 2;
mCursorY = SCREEN_HEIGHT / 2;
mCount = 0; mShowCursor = false;
mCurr = 0;
mActionButton = JGE_BTN_OK;
mCursorX = SCREEN_WIDTH/2; mCancelButton = JGE_BTN_MENU;
mCursorY = SCREEN_HEIGHT/2;
mShowCursor = false; mStyle = JGUI_STYLE_WRAPPING;
mActionButton = JGE_BTN_OK; mActive = true;
mCancelButton = JGE_BTN_MENU; }
mStyle = JGUI_STYLE_WRAPPING; JGuiController::~JGuiController()
{
mActive = true; for (int i = 0; i < mCount; i++)
} if (mObjects[i] != NULL) delete mObjects[i];
}
JGuiController::~JGuiController()
{ void JGuiController::Render()
for (int i=0;i<mCount;i++) {
if (mObjects[i]!=NULL) for (int i = 0; i < mCount; i++)
delete mObjects[i]; if (mObjects[i] != NULL) mObjects[i]->Render();
}
} bool JGuiController::CheckUserInput(JButton key)
{
void JGuiController::Render() if (!mCount) return false;
{ if (key == mActionButton)
for (int i=0;i<mCount;i++) {
if (mObjects[i]!=NULL) if (!mObjects.empty() && mObjects[mCurr] != NULL && mObjects[mCurr]->ButtonPressed())
mObjects[i]->Render(); {
} if (mListener != NULL) mListener->ButtonPressed(mId, mObjects[mCurr]->GetId());
bool JGuiController::CheckUserInput(JButton key){ return true;
}
if (!mCount) return false; }
if (key == mActionButton) else if (key == mCancelButton)
{ {
if (mObjects[mCurr] != NULL && mObjects[mCurr]->ButtonPressed()) if (mListener != NULL)
{ {
if (mListener != NULL) mListener->ButtonPressed(mId, kCancelMenuID);
mListener->ButtonPressed(mId, mObjects[mCurr]->GetId()); }
return true; }
} else if (JGE_BTN_CANCEL == key)
} {
else if (key == mCancelButton) if (mListener != NULL) mListener->ButtonPressed(mId, kInfoMenuID);
{ }
if (mListener != NULL)
{ else if ((JGE_BTN_LEFT == key) || (JGE_BTN_UP == key)) // || mEngine->GetAnalogY() < 64 || mEngine->GetAnalogX() < 64)
mListener->ButtonPressed(mId, kCancelMenuID); {
} int n = mCurr;
} n--;
else if ((JGE_BTN_LEFT == key) || (JGE_BTN_UP == key)) // || mEngine->GetAnalogY() < 64 || mEngine->GetAnalogX() < 64) if (n < 0)
{ {
int n = mCurr; if ((mStyle & JGUI_STYLE_WRAPPING))
n--; n = mCount - 1;
if (n<0) else
{ n = 0;
if ((mStyle&JGUI_STYLE_WRAPPING)) }
n = mCount-1;
else if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(JGE_BTN_UP))
n = 0; {
} mCurr = n;
mObjects[mCurr]->Entering();
if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(JGE_BTN_UP)) }
{ return true;
mCurr = n; }
mObjects[mCurr]->Entering(); else if ((JGE_BTN_RIGHT == key) || (JGE_BTN_DOWN == key)) // || mEngine->GetAnalogY()>192 || mEngine->GetAnalogX()>192)
} {
return true; int n = mCurr;
} n++;
else if ((JGE_BTN_RIGHT == key) || (JGE_BTN_DOWN == key)) // || mEngine->GetAnalogY()>192 || mEngine->GetAnalogX()>192) if (n > mCount - 1)
{ {
int n = mCurr; if ((mStyle & JGUI_STYLE_WRAPPING))
n++; n = 0;
if (n>mCount-1) else
{ n = mCount - 1;
if ((mStyle&JGUI_STYLE_WRAPPING)) }
n = 0;
else if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(JGE_BTN_DOWN))
n = mCount-1; {
} mCurr = n;
mObjects[mCurr]->Entering();
if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(JGE_BTN_DOWN)) }
{ return true;
mCurr = n; }
mObjects[mCurr]->Entering(); else
} { // a dude may have clicked somewhere, we're gonna select the closest object from where he clicked
return true; int x, y;
} unsigned int distance2;
else unsigned int minDistance2 = -1;
{ // a dude may have clicked somewhere, we're gonna select the closest object from where he clicked int n = mCurr;
int x, y; if (mEngine->GetLeftClickCoordinates(x, y))
unsigned int distance2; {
unsigned int minDistance2 = -1; for (int i = 0; i < mCount; i++)
int n = mCurr; {
if(mEngine->GetLeftClickCoordinates(x, y)) int top, left;
{ if (mObjects[i]->getTopLeft(top, left))
for(int i = 0; i < mCount; i++) {
{ distance2 = (top - y) * (top - y) + (left - x) * (left - x);
int top, left; if (distance2 < minDistance2)
if(mObjects[i]->getTopLeft(top, left)) {
{ minDistance2 = distance2;
distance2 = (top-y)*(top-y) + (left-x)*(left-x); n = i;
if(distance2 < minDistance2) }
{ }
minDistance2 = distance2; }
n = i;
} if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(JGE_BTN_DOWN))
} {
} mCurr = n;
mObjects[mCurr]->Entering();
if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(JGE_BTN_DOWN)) }
{ mEngine->LeftClickedProcessed();
mCurr = n; return true;
mObjects[mCurr]->Entering(); }
} }
mEngine->LeftClickedProcessed(); return false;
return true; }
} void JGuiController::Update(float dt)
} {
return false; for (int i = 0; i < mCount; i++)
} if (mObjects[i] != NULL) mObjects[i]->Update(dt);
void JGuiController::Update(float dt)
{ JButton key = mEngine->ReadButton();
for (int i=0;i<mCount;i++) CheckUserInput(key);
if (mObjects[i]!=NULL) }
mObjects[i]->Update(dt);
void JGuiController::Add(JGuiObject* ctrl)
JButton key = mEngine->ReadButton(); {
CheckUserInput(key); mObjects.push_back(ctrl);
} mCount++;
}
void JGuiController::Add(JGuiObject* ctrl) void JGuiController::RemoveAt(int i)
{ {
mObjects.push_back(ctrl); if (!mObjects[i]) return;
mCount++; mObjects.erase(mObjects.begin() + i);
} delete mObjects[i];
mCount--;
void JGuiController::RemoveAt(int i){ if (mCurr == mCount) mCurr = 0;
if (!mObjects[i]) return; return;
mObjects.erase(mObjects.begin()+i); }
delete mObjects[i];
mCount--; void JGuiController::Remove(int id)
if (mCurr == mCount) {
mCurr = 0; for (int i = 0; i < mCount; i++)
return; {
} if (mObjects[i] != NULL && mObjects[i]->GetId() == id)
{
void JGuiController::Remove(int id) RemoveAt(i);
{ return;
for (int i=0;i<mCount;i++) }
{ }
if (mObjects[i] != NULL && mObjects[i]->GetId()==id) { }
RemoveAt(i);
return; void JGuiController::Remove(JGuiObject* ctrl)
} {
} for (int i = 0; i < mCount; i++)
} {
if (mObjects[i] != NULL && mObjects[i] == ctrl)
{
void JGuiController::Remove(JGuiObject* ctrl) RemoveAt(i);
{ return;
for (int i=0;i<mCount;i++) }
{ }
if (mObjects[i] != NULL && mObjects[i]==ctrl) { }
RemoveAt(i);
return; void JGuiController::SetActionButton(JButton button)
} {
} mActionButton = button;
} }
void JGuiController::SetStyle(int style)
{
void JGuiController::SetActionButton(JButton button) { mActionButton = button; } mStyle = style;
void JGuiController::SetStyle(int style) { mStyle = style; } }
void JGuiController::SetCursor(JSprite* cursor) { mCursor = cursor; } void JGuiController::SetCursor(JSprite* cursor)
bool JGuiController::IsActive() { return mActive; } {
void JGuiController::SetActive(bool flag) { mActive = flag; } mCursor = cursor;
}
bool JGuiController::IsActive()
{
return mActive;
}
void JGuiController::SetActive(bool flag)
{
mActive = flag;
}
+1 -1
View File
@@ -1,4 +1,4 @@
OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/AllAbilities.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardPrimitive.o objs/CardSelector.o objs/CardSelectorSingleton.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckEditorMenu.o objs/DeckMenu.o objs/DeckMenuItem.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/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/Navigator.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/Pos.o objs/PrecompiledHeader.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/AllAbilities.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardPrimitive.o objs/CardSelector.o objs/CardSelectorSingleton.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckEditorMenu.o objs/DeckMenu.o objs/DeckMenuItem.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/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/Navigator.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/Pos.o objs/PrecompiledHeader.o objs/PriceList.o objs/ReplacementEffects.o objs/Rules.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/SimplePad.o objs/SimplePopup.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)) DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS))
RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache) RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache)
+75 -63
View File
@@ -1,63 +1,75 @@
/* /*
A class for very simple menus structure A class for menus with a fixed layout
*/ */
#ifndef _DeckMenu_H_ #ifndef _DeckMenu_H_
#define _DeckMenu_H_ #define _DeckMenu_H_
#include <string> #include <string>
#include "WFont.h" #include "WFont.h"
#include "hge/hgeparticle.h" #include "hge/hgeparticle.h"
#include "DeckMetaData.h" #include "DeckMetaData.h"
#include "TextScroller.h" #include "TextScroller.h"
class DeckMenu:public JGuiController{ class DeckMenu: public JGuiController
protected: {
protected:
float mHeight, mWidth, mX, mY;
float titleX, titleY, titleWidth; float mHeight, mWidth, mX, mY;
float descX, descY, descHeight, descWidth; float titleX, titleY, titleWidth;
float statsX, statsY, statsHeight, statsWidth; float descX, descY, descHeight, descWidth;
float avatarX, avatarY; float statsX, statsY, statsHeight, statsWidth;
float starsOffsetX; float avatarX, avatarY;
float detailedInfoBoxX, detailedInfoBoxY;
bool menuInitialized; float starsOffsetX;
string backgroundName;
bool menuInitialized;
int fontId; string backgroundName;
string title;
string displayTitle; int fontId;
WFont * mFont; string title;
float menuFontScale; string displayTitle;
float titleFontScale; WFont * mFont;
float menuFontScale;
int maxItems, startId; float titleFontScale;
float selectionT, selectionY; int maxItems, startId;
float timeOpen;
float selectionT, selectionY;
static hgeParticleSystem* stars; float timeOpen;
void initMenuItems(); static hgeParticleSystem* stars;
string getDescription();
string getMetaInformation(); void initMenuItems();
string getDescription();
public: string getMetaInformation();
TextScroller * scroller; DeckMetaData *selectedDeck;
bool autoTranslate;
DeckMenu(int id, JGuiListener* listener, int fontId, const string _title = "", const float& mFontScale = 1.0f ); public:
~DeckMenu(); TextScroller * scroller;
bool autoTranslate;
void Render();
void Update(float dt); //used for detailed info button
void Add(int id, const char * Text, string desc = "", bool forceFocus = false, DeckMetaData *deckMetaData = NULL); JQuad * pspIcons[8];
void Close(); JTexture * pspIconsTexture;
void updateScroller(); DeckMetaData * getSelectedDeck();
void RenderBackground(); bool selectedDeckHasDetails();
int selectedDeckId;
float selectionTargetY; bool showDetailsScreen;
bool closed; bool enableDetails;
static void destroy(); float selectionTargetY;
}; bool closed;
DeckMenu(int id, JGuiListener* listener, int fontId, const string _title = "", const int& startIndex = 0, const float& mFontScale = 1.0f);
#endif ~DeckMenu();
void Render();
void Update(float dt);
void Add(int id, const char * Text, string desc = "", bool forceFocus = false, DeckMetaData *deckMetaData = NULL);
void Close();
void updateScroller();
void RenderBackground();
static void destroy();
};
#endif
+79 -67
View File
@@ -1,89 +1,101 @@
#ifndef _DECKSTATS_H_ #ifndef _DECKSTATS_H_
#define _DECKSTATS_H_ #define _DECKSTATS_H_
#include <map> #include <map>
#include <string> #include <string>
#include <vector> #include <vector>
#include "MTGDefinitions.h" #include "MTGDefinitions.h"
#include <DeckDataWrapper.h>
using namespace std; using namespace std;
class Player; class Player;
class GameObserver; class GameObserver;
class DeckStat{ class DeckStat
{
public: public:
int nbgames; int nbgames;
int victories; int victories;
DeckStat(int _nbgames = 0 , int _victories = 0):nbgames(_nbgames),victories(_victories){}; DeckStat(int _nbgames = 0, int _victories = 0);
int percentVictories(); int percentVictories();
}; };
class DeckStats{ class DeckStats
{
protected: protected:
static DeckStats * mInstance; static DeckStats * mInstance;
public: public:
map<string, DeckStat *>stats; map<string, DeckStat *> stats;
static DeckStats * GetInstance(); static DeckStats * GetInstance();
void saveStats(Player * player, Player * opponent, GameObserver * game); void saveStats(Player * player, Player * opponent, GameObserver * game);
void save(const char * filename); void save(const char * filename);
void save(Player * player); void save(Player * player);
void load(const char * filename); void load(const char * filename);
void load(Player * player); void load(Player * player);
void cleanStats(); void cleanStats();
~DeckStats(); ~DeckStats();
int percentVictories(string opponentsDeckFile); int percentVictories(string opponentsDeckFile);
int percentVictories(); int percentVictories();
DeckStat * getDeckStat(string opponentsFile); DeckStat * getDeckStat(string opponentsFile);
int nbGames(); int nbGames();
}; };
class StatsWrapper
{
class StatsWrapper { public:
public: StatsWrapper(int deckId);
StatsWrapper(string filename);
StatsWrapper( int deckId ); ~StatsWrapper();
~StatsWrapper();
void initStatistics(string deckstats);
// Stats parameters and status
int currentPage; // Stats parameters and status
int pageCount; int mDeckId;
bool needUpdate; int currentPage;
int pageCount;
// Actual stats bool needUpdate;
int percentVictories;
int gamesPlayed; // Actual stats
int cardCount; int percentVictories;
int countLands; int gamesPlayed;
int totalPrice; int cardCount;
int totalManaCost; int countLands;
float avgManaCost; int totalPrice;
int totalCreatureCost; int totalManaCost;
float avgCreatureCost; float avgManaCost;
int totalSpellCost; int totalCreatureCost;
float avgSpellCost; float avgCreatureCost;
int countManaProducers; int totalSpellCost;
float avgSpellCost;
int countCreatures, countSpells, countInstants, countEnchantments, countSorceries, countArtifacts; int countManaProducers;
float noLandsProbInTurn[Constants::STATS_FOR_TURNS]; int countCreatures, countSpells, countInstants, countEnchantments, countSorceries, countArtifacts;
float noCreaturesProbInTurn[Constants::STATS_FOR_TURNS];
float noLandsProbInTurn[Constants::STATS_FOR_TURNS];
int countCardsPerCost[Constants::STATS_MAX_MANA_COST+1]; float noCreaturesProbInTurn[Constants::STATS_FOR_TURNS];
int countCardsPerCostAndColor[Constants::STATS_MAX_MANA_COST+1][Constants::MTG_NB_COLORS+1];
int countCreaturesPerCost[Constants::STATS_MAX_MANA_COST+1]; int countCardsPerCost[Constants::STATS_MAX_MANA_COST + 1];
int countCreaturesPerCostAndColor[Constants::STATS_MAX_MANA_COST+1][Constants::MTG_NB_COLORS+1]; int countCardsPerCostAndColor[Constants::STATS_MAX_MANA_COST + 1][Constants::MTG_NB_COLORS + 1];
int countSpellsPerCost[Constants::STATS_MAX_MANA_COST+1]; int countCreaturesPerCost[Constants::STATS_MAX_MANA_COST + 1];
int countSpellsPerCostAndColor[Constants::STATS_MAX_MANA_COST+1][Constants::MTG_NB_COLORS+1]; int countCreaturesPerCostAndColor[Constants::STATS_MAX_MANA_COST + 1][Constants::MTG_NB_COLORS + 1];
int countLandsPerColor[Constants::MTG_NB_COLORS+1]; int countSpellsPerCost[Constants::STATS_MAX_MANA_COST + 1];
int countBasicLandsPerColor[Constants::MTG_NB_COLORS+1]; int countSpellsPerCostAndColor[Constants::STATS_MAX_MANA_COST + 1][Constants::MTG_NB_COLORS + 1];
int countNonLandProducersPerColor[Constants::MTG_NB_COLORS+1]; int countLandsPerColor[Constants::MTG_NB_COLORS + 1];
int totalCostPerColor[Constants::MTG_NB_COLORS+1]; int countBasicLandsPerColor[Constants::MTG_NB_COLORS + 1];
int totalColoredSymbols; int countNonLandProducersPerColor[Constants::MTG_NB_COLORS + 1];
int totalCostPerColor[Constants::MTG_NB_COLORS + 1];
vector<string> aiDeckNames; int totalColoredSymbols;
vector<DeckStat*> aiDeckStats;
}; void updateStats(string filename, MTGAllCards * collection);
void updateStats(DeckDataWrapper *mtgDeck);
int countCardsByType(const char * _type, DeckDataWrapper * myDeck);
float noLuck(int n, int a, int x);
vector<string> aiDeckNames;
vector<DeckStat*> aiDeckStats;
};
#endif #endif
+156 -157
View File
@@ -1,157 +1,156 @@
#ifndef _GAME_STATE_DECK_VIEWER_H_ #ifndef _GAME_STATE_DECK_VIEWER_H_
#define _GAME_STATE_DECK_VIEWER_H_ #define _GAME_STATE_DECK_VIEWER_H_
#include <math.h> #include <math.h>
#include <iostream> #include <iostream>
#include <JGE.h> #include <JGE.h>
#include "GameState.h" #include "GameState.h"
#include "DeckEditorMenu.h" #include "DeckEditorMenu.h"
#include "SimpleMenu.h" #include "SimpleMenu.h"
#include "WResourceManager.h" #include "WResourceManager.h"
#include "CardGui.h" #include "CardGui.h"
#include "GameOptions.h" #include "GameOptions.h"
#include "PriceList.h" #include "PriceList.h"
#include "PlayerData.h" #include "PlayerData.h"
#include "DeckDataWrapper.h" #include "DeckDataWrapper.h"
#include "DeckStats.h" #include "DeckStats.h"
#include "WDataSrc.h" #include "WDataSrc.h"
#include "WGui.h" #include "WGui.h"
#define NO_USER_ACTIVITY_HELP_DELAY 10 #define NO_USER_ACTIVITY_HELP_DELAY 10
#define NO_USER_ACTIVITY_SHOWCARD_DELAY 0.1 #define NO_USER_ACTIVITY_SHOWCARD_DELAY 0.1
enum enum
{ {
STAGE_TRANSITION_RIGHT = 0, STAGE_TRANSITION_RIGHT = 0,
STAGE_TRANSITION_LEFT = 1, STAGE_TRANSITION_LEFT = 1,
STAGE_WAITING = 2, STAGE_WAITING = 2,
STAGE_TRANSITION_UP = 3, STAGE_TRANSITION_UP = 3,
STAGE_TRANSITION_DOWN = 4, STAGE_TRANSITION_DOWN = 4,
STAGE_ONSCREEN_MENU = 5, STAGE_ONSCREEN_MENU = 5,
STAGE_WELCOME = 6, STAGE_WELCOME = 6,
STAGE_MENU = 7, STAGE_MENU = 7,
STAGE_FILTERS = 8 STAGE_FILTERS = 8
}; };
// TODO: need a better name for MENU_FIRST_MENU, this is reused for the 1st submenu of
// TODO: need a better name for MENU_FIRST_MENU, this is reused for the 1st submenu of // available options in the duel menu
// available options in the duel menu enum
enum {
{ MENU_CARD_PURCHASE = 2,
MENU_CARD_PURCHASE = 2, MENU_DECK_SELECTION = 10,
MENU_DECK_SELECTION = 10, MENU_DECK_BUILDER = 11,
MENU_DECK_BUILDER = 11, MENU_FIRST_DUEL_SUBMENU = 102,
MENU_FIRST_DUEL_SUBMENU = 102, MENU_LANGUAGE_SELECTION = 103,
MENU_LANGUAGE_SELECTION = 103, };
};
// enums for menu options
// enums for menu options // TODO: make these enums a little more descriptive. (ie should reflect what menu they are attached to )
// TODO: make these enums a little more descriptive. (ie should reflect what menu they are attached to ) enum DECK_VIEWER_MENU_ITEMS
enum DECK_VIEWER_MENU_ITEMS {
{ MENU_ITEM_NEW_DECK = -30,
MENU_ITEM_NEW_DECK = -30, MENU_ITEM_CHEAT_MODE = -12,
MENU_ITEM_CHEAT_MODE = -12, MENU_ITEM_CANCEL = kCancelMenuID,
MENU_ITEM_CANCEL = kCancelMenuID, MENU_ITEM_SAVE_RETURN_MAIN_MENU = 0,
MENU_ITEM_SAVE_RETURN_MAIN_MENU = 0, MENU_ITEM_SAVE_RENAME = 1,
MENU_ITEM_SAVE_RENAME = 1, MENU_ITEM_SWITCH_DECKS_NO_SAVE = 2,
MENU_ITEM_SWITCH_DECKS_NO_SAVE = 2, MENU_ITEM_MAIN_MENU = 3,
MENU_ITEM_MAIN_MENU = 3, MENU_ITEM_EDITOR_CANCEL = kCancelMenuID,
MENU_ITEM_EDITOR_CANCEL = kCancelMenuID, MENU_ITEM_SAVE_AS_AI_DECK = 5,
MENU_ITEM_SAVE_AS_AI_DECK = 5, MENU_ITEM_YES = 20,
MENU_ITEM_YES = 20, MENU_ITEM_NO = 21,
MENU_ITEM_NO = 21, MENU_ITEM_FILTER_BY = 22,
MENU_ITEM_FILTER_BY = 22 MENUITEM_MORE_INFO = kInfoMenuID
};
};
#define ALL_COLORS -1
#define ALL_COLORS -1
#define ROTATE_LEFT 1;
#define ROTATE_LEFT 1; #define ROTATE_RIGHT 0;
#define ROTATE_RIGHT 0;
#define HIGH_SPEED 15.0
#define HIGH_SPEED 15.0 #define MED_SPEED 5.0f
#define MED_SPEED 5.0f #define LOW_SPEED 1.5
#define LOW_SPEED 1.5
#define MAX_SAVED_FILTERS 8
#define MAX_SAVED_FILTERS 8
class GameStateDeckViewer: public GameState, public JGuiListener
class GameStateDeckViewer: public GameState, public JGuiListener {
{ private:
private: JQuad * mIcons[7];
JQuad * mIcons[7]; JQuad * pspIcons[8];
JQuad * pspIcons[8]; JTexture * pspIconsTexture;
JTexture * pspIconsTexture; float last_user_activity;
float last_user_activity; float onScreenTransition;
float onScreenTransition; float mRotation;
float mRotation; float mSlide;
float mSlide; int mAlpha;
int mAlpha; int mStage;
int mStage; int nbDecks;
int nbDecks; int deckNum;
int deckNum; int useFilter;
int useFilter; JMusic * bgMusic;
JMusic * bgMusic; JQuad * backQuad;
JQuad * backQuad; int lastPos;
int lastPos; int lastTotal;
int lastTotal;
WGuiFilters * filterMenu;
WGuiFilters * filterMenu; WSrcDeckViewer * source;
WSrcDeckViewer * source;
DeckEditorMenu * welcome_menu;
DeckEditorMenu * welcome_menu; SimpleMenu * subMenu;
SimpleMenu * subMenu; DeckEditorMenu * menu;
DeckEditorMenu * menu; PriceList* pricelist;
PriceList* pricelist; PlayerData * playerdata;
PlayerData * playerdata; int price;
int price; DeckDataWrapper * displayed_deck;
DeckDataWrapper * displayed_deck; DeckDataWrapper * myDeck;
DeckDataWrapper * myDeck; DeckDataWrapper * myCollection;
DeckDataWrapper * myCollection; MTGCard * cardIndex[7];
MTGCard * cardIndex[7]; StatsWrapper *stw;
StatsWrapper *stw;
int hudAlpha;
int hudAlpha; string newDeckname;
string newDeckname; bool isAIDeckSave;
bool isAIDeckSave; bool mSwitching;
bool mSwitching; void saveDeck(); //Saves the deck and additional necessary information
void saveDeck(); //Saves the deck and additional necessary information void saveAsAIDeck(string deckName); // saves deck as an AI Deck
void saveAsAIDeck(string deckName); // saves deck as an AI Deck int getCurrentPos();
int getCurrentPos();
public:
public: GameStateDeckViewer(GameApp* parent);
GameStateDeckViewer(GameApp* parent); virtual ~GameStateDeckViewer();
virtual ~GameStateDeckViewer(); void updateDecks();
void updateDecks(); void rotateCards(int direction);
void rotateCards(int direction); void loadIndexes();
void loadIndexes(); void updateFilters();
void updateFilters(); void rebuildFilters();
void rebuildFilters(); void switchDisplay();
void switchDisplay(); void Start();
void Start(); virtual void End();
virtual void End(); void addRemove(MTGCard * card);
void addRemove(MTGCard * card); virtual void Update(float dt);
virtual void Update(float dt); void renderOnScreenBasicInfo();
void renderOnScreenBasicInfo(); void renderSlideBar();
void renderSlideBar(); void renderDeckBackground();
void renderDeckBackground(); void renderOnScreenMenu();
void renderOnScreenMenu(); virtual void renderCard(int id, float rotation);
virtual void renderCard(int id, float rotation); virtual void renderCard(int id);
virtual void renderCard (int id); virtual void Render();
virtual void Render(); int loadDeck(int deckid);
int loadDeck(int deckid); void LoadDeckStatistics(int deckId);
void LoadDeckStatistics(int deckId);
void buildEditorMenu();
void buildEditorMenu(); virtual void ButtonPressed(int controllerId, int controlId);
virtual void ButtonPressed(int controllerId, int controlId); void updateStats();
void updateStats(); int countCardsByType(const char * _type);
int countCardsByType(const char * _type); };
};
// n cards total, a of them are desired, x drawn
// n cards total, a of them are desired, x drawn // returns probability of no A's
// returns probability of no A's float noLuck(int n, int a, int x);
float noLuck(int n, int a, int x);
#endif
#endif
+76 -73
View File
@@ -1,73 +1,76 @@
#ifndef _GAME_STATE_DUEL_H_ #ifndef _GAME_STATE_DUEL_H_
#define _GAME_STATE_DUEL_H_ #define _GAME_STATE_DUEL_H_
#include "GameState.h"
#include "GameState.h" #include "SimpleMenu.h"
#include "SimpleMenu.h" #include "SimplePopup.h"
#include "DeckMenu.h" #include "DeckMenu.h"
#include "MTGDeck.h" #include "MTGDeck.h"
#include "GameObserver.h" #include "GameObserver.h"
#define CHOOSE_OPPONENT 7 #define CHOOSE_OPPONENT 7
#ifdef TESTSUITE #ifdef TESTSUITE
class TestSuite; class TestSuite;
#endif #endif
class Credits; class Credits;
class Rules; class Rules;
class GameStateDuel: public GameState, public JGuiListener
class GameStateDuel: public GameState, public JGuiListener {
{ private:
private: #ifdef TESTSUITE
#ifdef TESTSUITE TestSuite * testSuite;
TestSuite * testSuite; #endif
#endif Credits * credits;
Credits * credits; int mGamePhase;
int mGamePhase; Player * mCurrentPlayer;
Player * mCurrentPlayer; Player * mPlayers[2];
Player * mPlayers[2]; MTGPlayerCards * deck[2];
MTGPlayerCards * deck[2]; GameObserver * game;
GameObserver * game; DeckMenu * deckmenu;
DeckMenu * deckmenu; DeckMenu * opponentMenu;
DeckMenu * opponentMenu; SimpleMenu * menu;
SimpleMenu * menu; SimplePopup * popupScreen; // used for informational screens, modal
bool premadeDeck; static int selectedPlayerDeckId;
int OpponentsDeckid; static int selectedAIDeckId;
string musictrack;
Rules * rules; bool premadeDeck;
int OpponentsDeckid;
bool MusicExist(string FileName); string musictrack;
void loadPlayer(int playerId, int decknb = 0, int isAI = 0); Rules * rules;
void ensureOpponentMenu(); //loads the opponentMenu if it doesn't exist
void initScroller(); bool MusicExist(string FileName);
void loadPlayer(int playerId, int decknb = 0, int isAI = 0);
public: void ensureOpponentMenu(); //loads the opponentMenu if it doesn't exist
GameStateDuel(GameApp* parent); void initScroller();
virtual ~GameStateDuel();
#ifdef TESTSUITE public:
void loadTestSuitePlayers(); GameStateDuel(GameApp* parent);
#endif virtual ~GameStateDuel();
virtual void ButtonPressed(int ControllerId, int ControlId); #ifdef TESTSUITE
virtual void Start(); void loadTestSuitePlayers();
virtual void End(); #endif
virtual void Update(float dt); virtual void ButtonPressed(int ControllerId, int ControlId);
virtual void Render(); virtual void Start();
void initRand (unsigned seed = 0); virtual void End();
virtual void Update(float dt);
enum ENUM_DUEL_STATE_MENU_ITEM virtual void Render();
{ void initRand(unsigned seed = 0);
MENUITEM_CANCEL = kCancelMenuID,
MENUITEM_NEW_DECK = -10, enum ENUM_DUEL_STATE_MENU_ITEM
MENUITEM_RANDOM_PLAYER = -11, {
MENUITEM_RANDOM_AI = -12, MENUITEM_CANCEL = kCancelMenuID,
MENUITEM_MAIN_MENU = -13, MENUITEM_NEW_DECK = -10,
MENUITEM_EVIL_TWIN = -14, MENUITEM_RANDOM_PLAYER = -11,
MENUITEM_MULLIGAN = -15 MENUITEM_RANDOM_AI = -12,
}; MENUITEM_MAIN_MENU = -13,
MENUITEM_EVIL_TWIN = -14,
}; MENUITEM_MULLIGAN = -15,
MENUITEM_MORE_INFO = kInfoMenuID
};
#endif
};
#endif
+102 -78
View File
@@ -1,78 +1,102 @@
#ifndef _PLAYER_H_ #ifndef _PLAYER_H_
#define _PLAYER_H_ #define _PLAYER_H_
#include "JGE.h" #include "JGE.h"
#include "MTGGameZones.h" #include "MTGGameZones.h"
#include "Damage.h" #include "Damage.h"
#include "Targetable.h" #include "Targetable.h"
class MTGDeck; class MTGDeck;
class MTGPlayerCards; class MTGPlayerCards;
class MTGInPlay; class MTGInPlay;
class ManaPool; class ManaPool;
class Player: public Damageable{ class Player: public Damageable
protected: {
ManaPool * manaPool; protected:
ManaPool * manaPool;
public:
enum ENUM_PLAY_MODE public:
{ enum ENUM_PLAY_MODE
MODE_TEST_SUITE, {
MODE_HUMAN, MODE_TEST_SUITE, MODE_HUMAN, MODE_AI,
MODE_AI, };
};
JTexture * mAvatarTex;
JQuad * mAvatar;
virtual void End(); int playMode;
int typeAsTarget(){return TARGET_PLAYER;} int canPutLandsIntoPlay;
const string getDisplayName() const; int nomaxhandsize;
virtual int displayStack(){return 1;} int castedspellsthisturn;
JTexture * mAvatarTex; int onlyonecast;
JQuad * mAvatar; int castcount;
int playMode; int nocreatureinstant;
int canPutLandsIntoPlay; int nospellinstant;
int nomaxhandsize; int onlyoneinstant;
int castedspellsthisturn; int castrestrictedcreature;
int onlyonecast; int castrestrictedspell;
int castcount; MTGPlayerCards * game;
int nocreatureinstant; string deckFile;
int nospellinstant; string deckFileSmall;
int onlyoneinstant; string deckName;
int castrestrictedcreature;
int castrestrictedspell; Player(MTGDeck * deck, string deckFile, string deckFileSmall);
MTGPlayerCards * game; virtual ~Player();
int afterDamage();
int poisoned(); virtual void End();
int damaged(); virtual int displayStack()
int prevented(); {
Player(MTGDeck * deck, string deckFile, string deckFileSmall); return 1;
virtual ~Player(); }
void unTapPhase(); const string getDisplayName() const;
MTGInPlay * inPlay(); int typeAsTarget()
ManaPool * getManaPool(); {
void cleanupPhase(); return TARGET_PLAYER;
virtual int Act(float dt){return 0;}; }
virtual int isAI(){return 0;};
Player * opponent(); int afterDamage();
int getId(); int poisoned();
JQuad * getIcon(); int damaged();
string deckFile; int prevented();
string deckFileSmall; void unTapPhase();
string deckName; MTGInPlay * inPlay();
ManaPool * getManaPool();
virtual int receiveEvent(WEvent * event){return 0;}; void cleanupPhase();
virtual void Render(){}; virtual int Act(float dt)
void loadAvatar(string file); {
}; return 0;
}
class HumanPlayer: public Player{
public:
HumanPlayer(MTGDeck * deck, string deckFile, string deckFileSmall); virtual int isAI()
HumanPlayer(string deckFile); {
return 0;
}; }
ostream& operator<<(ostream&, const Player&); Player * opponent();
int getId();
#endif JQuad * getIcon();
virtual int receiveEvent(WEvent * event)
{
return 0;
}
virtual void Render()
{
}
void loadAvatar(string file);
};
class HumanPlayer: public Player
{
public:
HumanPlayer(MTGDeck * deck, string deckFile, string deckFileSmall);
HumanPlayer(string deckFile);
};
ostream& operator<<(ostream&, const Player&);
#endif
+48
View File
@@ -0,0 +1,48 @@
/*
* SimplePopup.h
* Created on: Nov 18, 2010
*
* Simple popup dialog box for displaying information only.
*/
#ifndef SIMPLEPOPUP_H_
#define SIMPLEPOPUP_H_
#pragma once
#include <JGui.h>
#include <JTypes.h>
#include <WFont.h>
#include <DeckMetaData.h>
class SimplePopup: public JGuiController
{
private:
float mHeight, mWidth, mX, mY;
int mMaxLines;
int mFontId;
DeckMetaData * mDeckInformation;
string mTitle;
WFont *mTextFont;
StatsWrapper *stw;
void drawHorzPole(float x, float y, float width);
void drawVertPole(float x, float y, float height);
public:
MTGAllCards * mCollection;
bool autoTranslate;
bool closed;
SimplePopup(int id, JGuiListener* listener, const int fontId, const char * _title = "", DeckMetaData* deckInfo = NULL, MTGAllCards * collection = NULL);
~SimplePopup(void);
void Render();
void Update(DeckMetaData* deckMetaData);
string getDetailedInformation(string deckFilename);
void Update(float dt);
void Close();
};
#endif /* SIMPLEPOPUP_H_ */
+102 -103
View File
@@ -1,103 +1,102 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "DeckEditorMenu.h" #include "DeckEditorMenu.h"
#include "DeckDataWrapper.h" #include "DeckDataWrapper.h"
#include "DeckStats.h" #include "DeckStats.h"
#include "JTypes.h" #include "JTypes.h"
#include "GameApp.h" #include "GameApp.h"
#include <iomanip> #include <iomanip>
DeckEditorMenu::DeckEditorMenu(int id, JGuiListener* listener, int fontId, const char * _title, DeckDataWrapper *_selectedDeck, DeckEditorMenu::DeckEditorMenu(int id, JGuiListener* listener, int fontId, const char * _title, DeckDataWrapper *_selectedDeck, StatsWrapper *stats) :
StatsWrapper *stats) : DeckMenu(id, listener, fontId, _title), selectedDeck(_selectedDeck), stw(stats)
DeckMenu(id, listener, fontId, _title), selectedDeck(_selectedDeck), stw(stats) {
{ backgroundName = "DeckEditorMenuBackdrop";
backgroundName = "DeckEditorMenuBackdrop";
deckTitle = selectedDeck ? selectedDeck->parent->meta_name : "";
deckTitle = selectedDeck ? selectedDeck->parent->meta_name : ""; enableDetails = false;
mX = 123; mX = 123;
mY = 70; mY = 70;
starsOffsetX = 50; starsOffsetX = 50;
titleX = 110; // center point in title box titleX = 110; // center point in title box
titleY = 25; titleY = 25;
titleWidth = 180; // width of inner box of title titleWidth = 180; // width of inner box of title
descX = 275; descX = 275;
descY = 80; descY = 80;
descHeight = 154; descHeight = 154;
descWidth = 175; descWidth = 175;
statsHeight = 50; statsHeight = 50;
statsWidth = 185; statsWidth = 185;
statsX = 280; statsX = 280;
statsY = 12; statsY = 12;
avatarX = 222; avatarX = 222;
avatarY = 8; avatarY = 8;
float scrollerWidth = 80; float scrollerWidth = 80;
SAFE_DELETE(scroller); // need to delete the scroller init in the base class SAFE_DELETE(scroller); // need to delete the scroller init in the base class
scroller = NEW TextScroller(Fonts::MAIN_FONT, 40, 230, scrollerWidth, 100, 1, 1); this->showDetailsScreen = false;
scroller = NEW TextScroller(Fonts::MAIN_FONT, 40, 230, scrollerWidth, 100, 1, 1);
}
}
void DeckEditorMenu::Render()
{ void DeckEditorMenu::Render()
JRenderer *r = JRenderer::GetInstance(); {
r->FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, ARGB(200,0,0,0)); JRenderer *r = JRenderer::GetInstance();
r->FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, ARGB(200,0,0,0));
DeckMenu::Render();
if (deckTitle.size() > 0) DeckMenu::Render();
{ if (deckTitle.size() > 0)
WFont *mainFont = resources.GetWFont(Fonts::OPTION_FONT); {
DWORD currentColor = mainFont->GetColor(); WFont *mainFont = resources.GetWFont(Fonts::OPTION_FONT);
mainFont->SetColor(ARGB(255,255,255,255)); DWORD currentColor = mainFont->GetColor();
mainFont->DrawString(deckTitle.c_str(), statsX + (statsWidth / 2), statsHeight / 2, JGETEXT_CENTER); mainFont->SetColor(ARGB(255,255,255,255));
mainFont->SetColor(currentColor); mainFont->DrawString(deckTitle.c_str(), statsX + (statsWidth / 2), statsHeight / 2, JGETEXT_CENTER);
} mainFont->SetColor(currentColor);
}
if (stw && selectedDeck)
drawDeckStatistics(); if (stw && selectedDeck) drawDeckStatistics();
} }
void DeckEditorMenu::drawDeckStatistics() void DeckEditorMenu::drawDeckStatistics()
{ {
ostringstream deckStatsString; ostringstream deckStatsString;
deckStatsString deckStatsString
<< "------- Deck Summary -----" << endl << "------- Deck Summary -----" << endl
<< "Cards: "<< selectedDeck->getCount() << endl << "Cards: "<< stw->cardCount << endl
<< "Creatures: "<< setw(2) << stw->countCreatures << "Creatures: "<< setw(2) << stw->countCreatures
<< " Enchantments: " << stw->countEnchantments << endl << " Enchantments: " << stw->countEnchantments << endl
<< "Instants: " << setw(4) << stw->countInstants << "Instants: " << setw(4) << stw->countInstants
<< " Sorceries: " << setw(2) << stw->countSorceries << endl << " Sorceries: " << setw(2) << stw->countSorceries << endl
<< "Lands: " << "Lands: "
<< "A: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_ARTIFACT ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_ARTIFACT ] << " " << "A: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_ARTIFACT ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_ARTIFACT ] << " "
<< "G: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_GREEN ] + stw->countLandsPerColor[ Constants::MTG_COLOR_GREEN ] << " " << "G: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_GREEN ] + stw->countLandsPerColor[ Constants::MTG_COLOR_GREEN ] << " "
<< "R: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_RED ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_RED ] << " " << "R: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_RED ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_RED ] << " "
<< "U: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_BLUE ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_BLUE ] << " " << "U: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_BLUE ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_BLUE ] << " "
<< "B: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_BLACK ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_BLACK ] << " " << "B: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_BLACK ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_BLACK ] << " "
<< "W: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_WHITE ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_WHITE ] << endl << "W: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_WHITE ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_WHITE ] << endl
<< " --- Card color count --- " << endl
<< " --- Card color count --- " << endl << "A: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_ARTIFACT) << " "
<< "A: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_ARTIFACT) << " " << "G: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_GREEN) << " "
<< "G: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_GREEN) << " " << "U: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_BLUE) << " "
<< "U: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_BLUE) << " " << "R: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_RED) << " "
<< "R: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_RED) << " " << "B: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_BLACK) << " "
<< "B: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_BLACK) << " " << "W: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_WHITE) << endl
<< "W: " << setw(2) << left << selectedDeck->getCount(Constants::MTG_COLOR_WHITE) << endl
<< " --- Average Cost --- " << endl
<< " --- Average Cost --- " << endl << "Creature: "<< setprecision(2) << stw->avgCreatureCost << endl
<< "Creature: "<< setprecision(2) << stw->avgCreatureCost << endl << "Mana: " << setprecision(2) << stw->avgManaCost << " "
<< "Mana: " << setprecision(2) << stw->avgManaCost << " " << "Spell: " << setprecision(2) << stw->avgSpellCost << endl;
<< "Spell: " << setprecision(2) << stw->avgSpellCost << endl;
WFont *mainFont = resources.GetWFont(Fonts::MAIN_FONT);
WFont *mainFont = resources.GetWFont( Fonts::MAIN_FONT ); mainFont->DrawString(deckStatsString.str().c_str(), descX, descY + 25);
mainFont->DrawString( deckStatsString.str().c_str(), descX, descY + 25 ); }
}
DeckEditorMenu::~DeckEditorMenu()
DeckEditorMenu::~DeckEditorMenu() {
{ SAFE_DELETE( scroller );
SAFE_DELETE( scroller ); }
}
+328 -281
View File
@@ -1,281 +1,328 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "DeckMenu.h" #include "DeckMenu.h"
#include "DeckMenuItem.h" #include "DeckMenuItem.h"
#include "DeckMetaData.h" #include "DeckMetaData.h"
#include "JTypes.h" #include "JTypes.h"
#include "GameApp.h" #include "GameApp.h"
#include "Translate.h" #include "Translate.h"
#include "TextScroller.h" #include "TextScroller.h"
#include "Tasks.h" #include "Tasks.h"
#include <iomanip> #include <iomanip>
namespace namespace
{ {
const float kVerticalMargin = 16; const float kVerticalMargin = 16;
const float kHorizontalMargin = 20; const float kHorizontalMargin = 20;
const float kLineHeight = 20; const float kLineHeight = 20;
const float kDescriptionVerticalBoxPadding = 5; const float kDescriptionVerticalBoxPadding = 5;
const float kDescriptionHorizontalBoxPadding = 5; const float kDescriptionHorizontalBoxPadding = 5;
} const int DETAILED_INFO_THRESHOLD = 4;
}
hgeParticleSystem* DeckMenu::stars = NULL;
hgeParticleSystem* DeckMenu::stars = NULL;
//
// For the additional info window, maximum characters per line is roughly 30 characters across. //
// TODO: figure a way to get incoming text to wrap. // For the additional info window, maximum characters per line is roughly 30 characters across.
// // TODO: figure a way to get incoming text to wrap.
// used fixed locations where the menu, title and descriptive text are located. //
// * menu at (125, 60 ) // used fixed locations where the menu, title and descriptive text are located.
// * descriptive information 125 // * menu at (125, 60 )
// *** Need to make this configurable in a file somewhere to allow for class reuse // * descriptive information 125
// *** Need to make this configurable in a file somewhere to allow for class reuse
DeckMenu::DeckMenu(int id, JGuiListener* listener, int fontId, const string _title, const float& mFontScale) :
JGuiController(id, listener), fontId(fontId), menuFontScale(mFontScale) DeckMenu::DeckMenu(int id, JGuiListener* listener, int fontId, const string _title, const int& startIndex, const float& mFontScale) :
{ JGuiController(id, listener), fontId(fontId), menuFontScale(mFontScale)
{
backgroundName = "DeckMenuBackdrop";
backgroundName = "DeckMenuBackdrop";
mY = 55;
mWidth = 176; selectedDeck = NULL;
mX = 125; enableDetails = true;
mY = 55;
titleX = 130; // center point in title box mWidth = 176;
titleY = 28; mX = 125;
titleWidth = 180; // width of inner box of title
titleX = 130; // center point in title box
descX = 230 + kDescriptionVerticalBoxPadding; titleY = 28;
descY = 65 + kDescriptionHorizontalBoxPadding; titleWidth = 180; // width of inner box of title
descHeight = 145;
descWidth = 220; descX = 230 + kDescriptionVerticalBoxPadding;
descY = 65 + kDescriptionHorizontalBoxPadding;
starsOffsetX = 50; descHeight = 145;
descWidth = 220;
statsX = 280;
statsY = 8; detailedInfoBoxX = 400;
statsHeight = 50; detailedInfoBoxY = 235;
statsWidth = 227; starsOffsetX = 50;
avatarX = 230; statsX = 280;
avatarY = 8; statsY = 8;
statsHeight = 50;
menuInitialized = false; statsWidth = 227;
float scrollerWidth = 80; selectedDeckId = startIndex;
scroller = NEW TextScroller(Fonts::MAIN_FONT, 40, 230, scrollerWidth, 100, 1, 1);
avatarX = 230;
autoTranslate = true; avatarY = 8;
maxItems = 7;
mHeight = 2 * kVerticalMargin + (maxItems * kLineHeight); menuInitialized = false;
// we want to cap the deck titles to 15 characters to avoid overflowing deck names float scrollerWidth = 80;
title = _(_title); scroller = NEW TextScroller(Fonts::MAIN_FONT, 40, 230, scrollerWidth, 100, 1, 1);
displayTitle = title;
mFont = resources.GetWFont(fontId); autoTranslate = true;
maxItems = 7;
startId = 0; mHeight = 2 * kVerticalMargin + (maxItems * kLineHeight);
selectionT = 0;
timeOpen = 0; // we want to cap the deck titles to 15 characters to avoid overflowing deck names
closed = false; title = _(_title);
displayTitle = title;
if (mFont->GetStringWidth(title.c_str()) > titleWidth) mFont = resources.GetWFont(fontId);
titleFontScale = 0.75f;
else startId = 0;
titleFontScale = 1.0f; selectionT = 0;
timeOpen = 0;
selectionTargetY = selectionY = kVerticalMargin; closed = false;
if (NULL == stars) if (mFont->GetStringWidth(title.c_str()) > titleWidth)
stars = NEW hgeParticleSystem(resources.RetrievePSI("stars.psi", resources.GetQuad("stars"))); titleFontScale = 0.75f;
stars->FireAt(mX, mY); else
titleFontScale = 1.0f;
updateScroller();
} selectionTargetY = selectionY = kVerticalMargin;
void DeckMenu::RenderBackground() if (NULL == stars) stars = NEW hgeParticleSystem(resources.RetrievePSI("stars.psi", resources.GetQuad("stars")));
{ stars->FireAt(mX, mY);
ostringstream bgFilename;
bgFilename << backgroundName << ".png"; updateScroller();
}
static bool loadBackground = true;
if (loadBackground) void DeckMenu::RenderBackground()
{ {
JQuad *background = resources.RetrieveTempQuad(bgFilename.str(), TEXTURE_SUB_5551); ostringstream bgFilename;
if (background) bgFilename << backgroundName << ".png";
JRenderer::GetInstance()->RenderQuad(background, 0, 0);
else static bool loadBackground = true;
loadBackground = false; if (loadBackground)
} {
} JQuad *background = resources.RetrieveTempQuad(bgFilename.str(), TEXTURE_SUB_5551);
if (background)
void DeckMenu::initMenuItems() JRenderer::GetInstance()->RenderQuad(background, 0, 0);
{ else
float sY = mY + kVerticalMargin; loadBackground = false;
for (int i = startId; i < startId + mCount; ++i) }
{ }
float y = mY + kVerticalMargin + i * kLineHeight;
DeckMenuItem * currentMenuItem = static_cast<DeckMenuItem*> (mObjects[i]); DeckMetaData * DeckMenu::getSelectedDeck()
currentMenuItem->Relocate(mX, y); {
if (currentMenuItem->hasFocus()) if (selectedDeck) return selectedDeck;
sY = y;
} return NULL;
selectionTargetY = selectionY = sY; }
}
bool DeckMenu::selectedDeckHasDetails()
void DeckMenu::Render() {
{ DeckMetaData * currentMenuItem = getSelectedDeck();
JRenderer * renderer = JRenderer::GetInstance(); if (currentMenuItem) return (enableDetails && currentMenuItem->getGamesPlayed() > DETAILED_INFO_THRESHOLD);
float height = mHeight;
return false;
if (!menuInitialized) }
{
initMenuItems(); void DeckMenu::initMenuItems()
stars->Fire(); {
timeOpen = 0; float sY = mY + kVerticalMargin;
menuInitialized = true; for (int i = startId; i < startId + mCount; ++i)
} {
if (timeOpen < 1) float y = mY + kVerticalMargin + i * kLineHeight;
height *= timeOpen > 0 ? timeOpen : -timeOpen; DeckMenuItem * currentMenuItem = static_cast<DeckMenuItem*> (mObjects[i]);
currentMenuItem->Relocate(mX, y);
renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE); if (currentMenuItem->hasFocus()) sY = y;
stars->Render(); }
renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); selectionTargetY = selectionY = sY;
for (int i = startId; i < startId + maxItems; i++) //Grab a texture in VRAM.
{ pspIconsTexture = resources.RetrieveTexture("iconspsp.png", RETRIEVE_LOCK);
if (i > mCount - 1)
break; char buf[512];
DeckMenuItem *currentMenuItem = static_cast<DeckMenuItem*> (mObjects[i]); for (int i = 0; i < 8; i++)
if (currentMenuItem->mY - kLineHeight * startId < mY + height - kLineHeight + 7) {
{ sprintf(buf, "iconspsp%d", i);
if (currentMenuItem->hasFocus()) pspIcons[i] = resources.RetrieveQuad("iconspsp.png", (float) i * 32, 0, 32, 32, buf);
{ pspIcons[i]->SetHotSpot(16, 16);
// display the avatar image }
if (currentMenuItem->imageFilename.size() > 0)
{ }
JQuad * quad = resources.RetrieveTempQuad(currentMenuItem->imageFilename, TEXTURE_SUB_AVATAR);
if (quad) void DeckMenu::Render()
renderer->RenderQuad(quad, avatarX, avatarY); {
} JRenderer * renderer = JRenderer::GetInstance();
// fill in the description part of the screen float height = mHeight;
string text = currentMenuItem->desc;
WFont *mainFont = resources.GetWFont(Fonts::MAIN_FONT); if (!menuInitialized)
mainFont->DrawString(text.c_str(), descX, descY); {
mFont->SetColor(ARGB(255,255,255,255)); initMenuItems();
stars->Fire();
// fill in the statistical portion timeOpen = 0;
if (currentMenuItem->meta) menuInitialized = true;
{ }
ostringstream oss; if (timeOpen < 1) height *= timeOpen > 0 ? timeOpen : -timeOpen;
oss << "Deck: " << currentMenuItem->meta->getName() << endl;
oss << currentMenuItem->meta->getStatsSummary(); for (int i = startId; i < startId + maxItems; i++)
{
mainFont->DrawString(oss.str(), statsX, statsY); if (i > mCount - 1) break;
} DeckMenuItem *currentMenuItem = static_cast<DeckMenuItem*> (mObjects[i]);
} if (currentMenuItem->mY - kLineHeight * startId < mY + height - kLineHeight + 7)
else {
{ if (currentMenuItem->hasFocus())
mFont->SetColor(ARGB(150,255,255,255)); {
} selectedDeckId = i;
mFont->SetScale(menuFontScale); selectedDeck = currentMenuItem->meta;
currentMenuItem->RenderWithOffset(-kLineHeight * startId);
} WFont *mainFont = resources.GetWFont(Fonts::MAIN_FONT);
}
// display the "more info" button if special condition is met
RenderBackground(); if (selectedDeckHasDetails())
{
if (!title.empty()) showDetailsScreen = true;
{ float pspIconsSize = 0.5;
mFont->SetColor(ARGB(255,255,255,255)); const string detailedInfoString = "Detailed Info";
mFont->SetScale(titleFontScale); float stringWidth = mainFont->GetStringWidth(detailedInfoString.c_str());
mFont->DrawString(title.c_str(), titleX, titleY, JGETEXT_CENTER); float boxStartX = detailedInfoBoxX - stringWidth / 2;
} DWORD currentColor = mainFont->GetColor();
mFont->SetScale(1.0f); renderer->FillRoundRect( boxStartX, detailedInfoBoxY - 5, stringWidth,
scroller->Render(); mainFont->GetHeight() + 15, .5, ARGB( 125, 0, 255, 255) );
renderer->RenderQuad(pspIcons[5], detailedInfoBoxX, detailedInfoBoxY + 2, 0, pspIconsSize, pspIconsSize);
} mainFont->SetColor(currentColor);
mainFont->DrawString(detailedInfoString, boxStartX, detailedInfoBoxY + 10);
void DeckMenu::Update(float dt) }
{ else
JGuiController::Update(dt); showDetailsScreen = false;
if (mCurr > startId + maxItems - 1)
startId = mCurr - maxItems + 1; // display the avatar image
else if (mCurr < startId) if (currentMenuItem->imageFilename.size() > 0)
startId = mCurr; {
stars->Update(dt); JQuad * quad = resources.RetrieveTempQuad(currentMenuItem->imageFilename, TEXTURE_SUB_AVATAR);
selectionT += 3 * dt; if (quad) renderer->RenderQuad(quad, avatarX, avatarY);
selectionY += (selectionTargetY - selectionY) * 8 * dt; }
// fill in the description part of the screen
float starsX = starsOffsetX + ((mWidth - 2 * kHorizontalMargin) * (1 + cos(selectionT)) / 2); string text = currentMenuItem->desc;
float starsY = selectionY + 5 * cos(selectionT * 2.35f) + kLineHeight / 2 - kLineHeight * startId; mainFont->DrawString(text.c_str(), descX, descY);
stars->MoveTo(starsX, starsY); mFont->SetColor(ARGB(255,255,255,255));
if (timeOpen < 0)
{ // fill in the statistical portion
timeOpen += dt * 10; if (currentMenuItem->meta)
if (timeOpen >= 0) {
{ ostringstream oss;
timeOpen = 0; oss << "Deck: " << currentMenuItem->meta->getName() << endl;
closed = true; oss << currentMenuItem->meta->getStatsSummary();
stars->FireAt(mX, mY);
} mainFont->DrawString(oss.str(), statsX, statsY);
} }
else }
{ else
closed = false; {
timeOpen += dt * 10; mFont->SetColor(ARGB(150,255,255,255));
} }
mFont->SetScale(menuFontScale);
scroller->Update(dt); currentMenuItem->RenderWithOffset(-kLineHeight * startId);
} }
}
void DeckMenu::Add(int id, const char * text, string desc, bool forceFocus, DeckMetaData * deckMetaData)
{ RenderBackground();
DeckMenuItem * menuItem = NEW DeckMenuItem(this, id, fontId, text, 0, mY + kVerticalMargin + mCount * kLineHeight,
(mCount == 0), autoTranslate, deckMetaData); if (!title.empty())
Translator * t = Translator::GetInstance(); {
map<string, string>::iterator it = t->deckValues.find(text); mFont->SetColor(ARGB(255,255,255,255));
if (it != t->deckValues.end()) //translate decks desc mFont->SetScale(titleFontScale);
menuItem->desc = it->second; mFont->DrawString(title.c_str(), titleX, titleY, JGETEXT_CENTER);
else }
menuItem->desc = deckMetaData ? deckMetaData->getDescription() : desc; mFont->SetScale(1.0f);
scroller->Render();
JGuiController::Add(menuItem);
if (mCount <= maxItems) }
mHeight += kLineHeight;
if (forceFocus) void DeckMenu::Update(float dt)
{ {
mObjects[mCurr]->Leaving(JGE_BTN_DOWN); JGuiController::Update(dt);
mCurr = mCount - 1; if (mCurr > startId + maxItems - 1)
menuItem->Entering(); startId = mCurr - maxItems + 1;
} else if (mCurr < startId) startId = mCurr;
} stars->Update(dt);
selectionT += 3 * dt;
void DeckMenu::updateScroller() selectionY += (selectionTargetY - selectionY) * 8 * dt;
{
// add all the items from the Tasks db. float starsX = starsOffsetX + ((mWidth - 2 * kHorizontalMargin) * (1 + cos(selectionT)) / 2);
TaskList taskList; float starsY = selectionY + 5 * cos(selectionT * 2.35f) + kLineHeight / 2 - kLineHeight * startId;
scroller->Reset(); stars->MoveTo(starsX, starsY);
for (vector<Task*>::iterator it = taskList.tasks.begin(); it != taskList.tasks.end(); it++) if (timeOpen < 0)
{ {
ostringstream taskDescription; timeOpen += dt * 10;
taskDescription << "[ " << setw(4) << (*it)->getReward() << " / " << (*it)->getExpiration() << " ] " if (timeOpen >= 0)
<< (*it)->getDesc() << endl; {
scroller->Add(taskDescription.str()); timeOpen = 0;
} closed = true;
} stars->FireAt(mX, mY);
}
void DeckMenu::Close() }
{ else
timeOpen = -1.0; {
stars->Stop(true); closed = false;
} timeOpen += dt * 10;
}
void DeckMenu::destroy() if (scroller) scroller->Update(dt);
{ }
SAFE_DELETE(DeckMenu::stars);
} void DeckMenu::Add(int id, const char * text, string desc, bool forceFocus, DeckMetaData * deckMetaData)
{
DeckMenu::~DeckMenu() DeckMenuItem * menuItem = NEW DeckMenuItem(this, id, fontId, text, 0, mY + kVerticalMargin + mCount * kLineHeight,
{ (mCount == 0), autoTranslate, deckMetaData);
SAFE_DELETE(scroller); Translator * t = Translator::GetInstance();
} map<string, string>::iterator it = t->deckValues.find(text);
if (it != t->deckValues.end()) //translate decks desc
menuItem->desc = it->second;
else
menuItem->desc = deckMetaData ? deckMetaData->getDescription() : desc;
JGuiController::Add(menuItem);
if (mCount <= maxItems) mHeight += kLineHeight;
if (forceFocus)
{
mObjects[mCurr]->Leaving(JGE_BTN_DOWN);
mCurr = mCount - 1;
menuItem->Entering();
}
}
void DeckMenu::updateScroller()
{
// add all the items from the Tasks db.
TaskList taskList;
scroller->Reset();
for (vector<Task*>::iterator it = taskList.tasks.begin(); it != taskList.tasks.end(); it++)
{
ostringstream taskDescription;
taskDescription << "[ " << setw(4) << (*it)->getReward() << " / " << (*it)->getExpiration() << " ] "
<< (*it)->getDesc() << endl;
scroller->Add(taskDescription.str());
}
}
void DeckMenu::Close()
{
timeOpen = -1.0;
stars->Stop(true);
}
void DeckMenu::destroy()
{
SAFE_DELETE(DeckMenu::stars);
}
DeckMenu::~DeckMenu()
{
resources.Release(pspIconsTexture);
SAFE_DELETE(scroller);
scroller = NULL;
}
+466 -242
View File
@@ -1,242 +1,466 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "DeckStats.h" #include "DeckStats.h"
#include "Player.h" #include "Player.h"
#include "GameObserver.h" #include "GameObserver.h"
#include "MTGDeck.h"
DeckStats * DeckStats::mInstance = NULL; #include "ManaCostHybrid.h"
int DeckStat::percentVictories() DeckStats * DeckStats::mInstance = NULL;
{
if (nbgames == 0) DeckStat::DeckStat(int _nbgames, int _victories) : nbgames(_nbgames), victories(_victories)
return 50; {
return (100 * victories / nbgames); }
}
int DeckStat::percentVictories()
DeckStats * DeckStats::GetInstance() {
{ if (nbgames == 0) return 50;
if (!mInstance) return (100 * victories / nbgames);
{ }
mInstance = NEW DeckStats();
DeckStats * DeckStats::GetInstance()
} {
return mInstance; if (!mInstance)
} {
mInstance = NEW DeckStats();
void DeckStats::cleanStats()
{ }
map<string, DeckStat *>::iterator it; return mInstance;
for (it = stats.begin(); it != stats.end(); it++) }
{
SAFE_DELETE(it->second); void DeckStats::cleanStats()
} {
map<string, DeckStat *>::iterator it;
stats.clear(); for (it = stats.begin(); it != stats.end(); it++)
} {
SAFE_DELETE(it->second);
DeckStats::~DeckStats() }
{
cleanStats(); stats.clear();
} }
int DeckStats::percentVictories(string opponentsFile) DeckStats::~DeckStats()
{ {
map<string, DeckStat *>::iterator it = stats.find(opponentsFile); cleanStats();
if (it == stats.end()) }
{
return 50; int DeckStats::percentVictories(string opponentsFile)
} {
else map<string, DeckStat *>::iterator it = stats.find(opponentsFile);
{ if (it == stats.end())
return (it->second->percentVictories()); {
} return 50;
} }
else
DeckStat* DeckStats::getDeckStat(string opponentsFile) {
{ return (it->second->percentVictories());
map<string, DeckStat *>::iterator it = stats.find(opponentsFile); }
if (it == stats.end()) }
{
return NULL; DeckStat* DeckStats::getDeckStat(string opponentsFile)
} {
else map<string, DeckStat *>::iterator it = stats.find(opponentsFile);
{ if (it == stats.end())
return it->second; {
} return NULL;
} }
else
int DeckStats::nbGames() {
{ return it->second;
int nbgames = 0; }
map<string, DeckStat *>::iterator it; }
for (it = stats.begin(); it != stats.end(); it++)
{ int DeckStats::nbGames()
DeckStat * d = it->second; {
nbgames += d->nbgames; int nbgames = 0;
} map<string, DeckStat *>::iterator it;
return nbgames; for (it = stats.begin(); it != stats.end(); it++)
} {
DeckStat * d = it->second;
int DeckStats::percentVictories() nbgames += d->nbgames;
{ }
int victories = 0; return nbgames;
int nbgames = 0; }
map<string, DeckStat *>::iterator it;
for (it = stats.begin(); it != stats.end(); it++) int DeckStats::percentVictories()
{ {
DeckStat * d = it->second; int victories = 0;
nbgames += d->nbgames; int nbgames = 0;
victories += d->victories; map<string, DeckStat *>::iterator it;
} for (it = stats.begin(); it != stats.end(); it++)
if (nbgames) {
{ DeckStat * d = it->second;
return (victories * 100) / nbgames; nbgames += d->nbgames;
} victories += d->victories;
return 50; }
} if (nbgames)
{
void DeckStats::load(Player * player) return (victories * 100) / nbgames;
{ }
char filename[512]; return 50;
sprintf(filename, "stats/%s.txt", player->deckFileSmall.c_str()); }
load(options.profileFile(filename).c_str());
} void DeckStats::load(Player * player)
{
void DeckStats::load(const char * filename) char filename[512];
{ sprintf(filename, "stats/%s.txt", player->deckFileSmall.c_str());
cleanStats(); load(options.profileFile(filename).c_str());
std::ifstream file(filename); }
std::string s;
void DeckStats::load(const char * filename)
if (file) {
{ cleanStats();
while (std::getline(file, s)) std::ifstream file(filename);
{ std::string s;
string deckfile = s;
std::getline(file, s); if (file)
int games = atoi(s.c_str()); {
std::getline(file, s); while (std::getline(file, s))
int victories = atoi(s.c_str()); {
map<string, DeckStat *>::iterator it = stats.find(deckfile); string deckfile = s;
if (it == stats.end()) std::getline(file, s);
{ int games = atoi(s.c_str());
stats[deckfile] = NEW DeckStat(games, victories); std::getline(file, s);
} int victories = atoi(s.c_str());
} map<string, DeckStat *>::iterator it = stats.find(deckfile);
file.close(); if (it == stats.end())
} {
} stats[deckfile] = NEW DeckStat(games, victories);
}
void DeckStats::save(Player * player) }
{ file.close();
char filename[512]; }
sprintf(filename, "stats/%s.txt", player->deckFileSmall.c_str()); }
save(options.profileFile(filename).c_str());
} void DeckStats::save(Player * player)
{
void DeckStats::save(const char * filename) char filename[512];
{ sprintf(filename, "stats/%s.txt", player->deckFileSmall.c_str());
std::ofstream file(filename); save(options.profileFile(filename).c_str());
char writer[512]; }
if (file)
{ void DeckStats::save(const char * filename)
map<string, DeckStat *>::iterator it; {
for (it = stats.begin(); it != stats.end(); it++) std::ofstream file(filename);
{ char writer[512];
sprintf(writer, "%s\n", it->first.c_str()); if (file)
file << writer; {
sprintf(writer, "%i\n", it->second->nbgames); map<string, DeckStat *>::iterator it;
file << writer; for (it = stats.begin(); it != stats.end(); it++)
sprintf(writer, "%i\n", it->second->victories); {
file << writer; sprintf(writer, "%s\n", it->first.c_str());
} file << writer;
file.close(); sprintf(writer, "%i\n", it->second->nbgames);
} file << writer;
} sprintf(writer, "%i\n", it->second->victories);
file << writer;
void DeckStats::saveStats(Player *player, Player *opponent, GameObserver * game) }
{ file.close();
int victory = 1; }
if (!game->gameOver) }
{
if (player->life == opponent->life) void DeckStats::saveStats(Player *player, Player *opponent, GameObserver * game)
return; {
if (player->life < opponent->life) int victory = 1;
victory = 0; if (!game->gameOver)
} {
else if (game->gameOver == player) if (player->life == opponent->life) return;
{ if (player->life < opponent->life) victory = 0;
victory = 0; }
} else if (game->gameOver == player)
load(player); {
map<string, DeckStat *>::iterator it = stats.find(opponent->deckFileSmall); victory = 0;
if (it == stats.end()) }
{ load(player);
stats[opponent->deckFileSmall] = NEW DeckStat(1, victory); map<string, DeckStat *>::iterator it = stats.find(opponent->deckFileSmall);
} if (it == stats.end())
else {
{ stats[opponent->deckFileSmall] = NEW DeckStat(1, victory);
it->second->victories += victory; }
it->second->nbgames += 1; else
} {
save(player); it->second->victories += victory;
} it->second->nbgames += 1;
}
StatsWrapper::StatsWrapper(int deckId) save(player);
{ }
// Load deck statistics StatsWrapper::StatsWrapper(int deckId)
char buffer[512]; {
DeckStats * stats = DeckStats::GetInstance(); mDeckId = deckId;
aiDeckNames.clear(); char buffer[512];
aiDeckStats.clear(); sprintf(buffer, "stats/player_deck%i.txt", deckId);
string deckstats = options.profileFile(buffer);
sprintf(buffer, "stats/player_deck%i.txt", deckId); initStatistics(deckstats);
string deckstats = options.profileFile(buffer); }
if (fileExists(deckstats.c_str())) StatsWrapper::StatsWrapper(string deckstats)
{ {
stats->load(deckstats.c_str()); initStatistics(deckstats);
percentVictories = stats->percentVictories(); }
gamesPlayed = stats->nbGames();
void StatsWrapper::initStatistics(string deckstats)
// Detailed deck statistics against AI {
int found = 1; // Load deck statistics
int nbDecks = 0; DeckStats * stats = DeckStats::GetInstance();
while (found) aiDeckNames.clear();
{ aiDeckStats.clear();
found = 0;
char buffer[512]; if (fileExists(deckstats.c_str()))
char smallDeckName[512]; {
sprintf(buffer, "%s/deck%i.txt", RESPATH"/ai/baka", nbDecks + 1); stats->load(deckstats.c_str());
if (fileExists(buffer)) percentVictories = stats->percentVictories();
{ gamesPlayed = stats->nbGames();
MTGDeck * mtgd = NEW MTGDeck(buffer, NULL, 1);
found = 1; // Detailed deck statistics against AI
nbDecks++; int found = 1;
int nbDecks = 0;
sprintf(smallDeckName, "%s_deck%i", "ai_baka", nbDecks); found = 0;
DeckStat* deckStat = stats->getDeckStat(string(smallDeckName)); char buffer[512];
char smallDeckName[512];
if ((deckStat != NULL) && (deckStat->nbgames > 0)) sprintf(buffer, "%s/deck%i.txt", RESPATH"/ai/baka", nbDecks + 1);
{ if (fileExists(buffer))
int percentVictories = stats->percentVictories(string(smallDeckName)); {
aiDeckNames.push_back(string(mtgd->meta_name)); MTGDeck * mtgd = NEW MTGDeck(buffer, NULL, 1);
aiDeckStats.push_back(deckStat); found = 1;
} nbDecks++;
delete mtgd; sprintf(smallDeckName, "%s_deck%i", "ai_baka", nbDecks);
} DeckStat* deckStat = stats->getDeckStat(string(smallDeckName));
}
} if ((deckStat != NULL) && (deckStat->nbgames > 0))
else {
{ int percentVictories = stats->percentVictories(string(smallDeckName));
gamesPlayed = 0; aiDeckNames.push_back(string(mtgd->meta_name));
percentVictories = 0; aiDeckStats.push_back(deckStat);
} }
}
delete mtgd;
StatsWrapper::~StatsWrapper() }
{ }
aiDeckNames.clear(); else
aiDeckStats.clear(); {
} gamesPlayed = 0;
percentVictories = 0;
}
}
void StatsWrapper::updateStats(string filename, MTGAllCards *collection)
{
if (fileExists(filename.c_str()))
{
MTGDeck * mtgd = NEW MTGDeck(filename.c_str(), collection);
DeckDataWrapper *deckDataWrapper = NEW DeckDataWrapper(mtgd);
updateStats(deckDataWrapper);
SAFE_DELETE( mtgd );
SAFE_DELETE( deckDataWrapper );
}
}
void StatsWrapper::updateStats(DeckDataWrapper *myDeck)
{
if (!this->needUpdate || !myDeck) return;
this->needUpdate = false;
this->cardCount = myDeck->getCount(WSrcDeck::UNFILTERED_COPIES);
this->countLands = myDeck->getCount(Constants::MTG_COLOR_LAND);
this->totalPrice = myDeck->totalPrice();
this->countManaProducers = 0;
// Mana cost
int currentCount, convertedCost;
ManaCost * currentCost;
this->totalManaCost = 0;
this->totalCreatureCost = 0;
this->totalSpellCost = 0;
MTGCard * current = myDeck->getCard();
// Clearing arrays
for (int i = 0; i <= Constants::STATS_MAX_MANA_COST; i++)
{
this->countCardsPerCost[i] = 0;
this->countCreaturesPerCost[i] = 0;
this->countSpellsPerCost[i] = 0;
}
for (int i = 0; i <= Constants::MTG_NB_COLORS; i++)
{
this->totalCostPerColor[i] = 0;
this->countLandsPerColor[i] = 0;
this->countBasicLandsPerColor[i] = 0;
this->countNonLandProducersPerColor[i] = 0;
}
for (int i = 0; i <= Constants::STATS_MAX_MANA_COST; i++)
{
for (int k = 0; k <= Constants::MTG_NB_COLORS; k++)
{
this->countCardsPerCostAndColor[i][k] = 0;
this->countCreaturesPerCostAndColor[i][k] = 0;
this->countSpellsPerCostAndColor[i][k] = 0;
}
}
for (int ic = 0; ic < myDeck->Size(true); ic++)
{
current = myDeck->getCard(ic, true);
currentCost = current->data->getManaCost();
convertedCost = currentCost->getConvertedCost();
currentCount = myDeck->count(current);
// Add to the cards per cost counters
this->totalManaCost += convertedCost * currentCount;
if (convertedCost > Constants::STATS_MAX_MANA_COST)
{
convertedCost = Constants::STATS_MAX_MANA_COST;
}
this->countCardsPerCost[convertedCost] += currentCount;
if (current->data->isCreature())
{
this->countCreaturesPerCost[convertedCost] += currentCount;
this->totalCreatureCost += convertedCost * currentCount;
}
else if (current->data->isSpell())
{
this->countSpellsPerCost[convertedCost] += currentCount;
this->totalSpellCost += convertedCost * currentCount;
}
// Lets look for mana producing abilities
vector<string> abilitiesVector;
string thisstring = current->data->magicText;
abilitiesVector = split(thisstring, '\n');
for (int v = 0; v < (int) abilitiesVector.size(); v++)
{
string s = abilitiesVector[v];
size_t t = s.find("add");
if (t != string::npos)
{
s = s.substr(t + 3);
ManaCost * mc = ManaCost::parseManaCost(s);
for (int j = 0; j < Constants::MTG_NB_COLORS; j++)
{
if (mc->hasColor(j))
{
if (current->data->isLand())
{
if (current->data->hasType("Basic"))
{
this->countBasicLandsPerColor[j] += currentCount;
}
else
{
this->countLandsPerColor[j] += currentCount;
}
}
else
{
this->countNonLandProducersPerColor[j] += currentCount;
}
}
}
SAFE_DELETE(mc);
}
}
// Add to the per color counters
// a. regular costs
for (int j = 0; j < Constants::MTG_NB_COLORS; j++)
{
this->totalCostPerColor[j] += currentCost->getCost(j) * currentCount;
if (current->data->hasColor(j))
{
// Add to the per cost and color counter
this->countCardsPerCostAndColor[convertedCost][j] += currentCount;
if (current->data->isCreature())
{
this->countCreaturesPerCostAndColor[convertedCost][j] += currentCount;
}
else if (current->data->isSpell())
{
this->countSpellsPerCostAndColor[convertedCost][j] += currentCount;
}
}
}
// b. Hybrid costs
ManaCostHybrid * hybridCost;
int i;
i = 0;
while ((hybridCost = currentCost->getHybridCost(i++)) != NULL)
{
this->totalCostPerColor[hybridCost->color1] += hybridCost->value1 * currentCount;
this->totalCostPerColor[hybridCost->color2] += hybridCost->value2 * currentCount;
}
}
this->totalColoredSymbols = 0;
for (int j = 1; j < Constants::MTG_NB_COLORS; j++)
{
this->totalColoredSymbols += this->totalCostPerColor[j];
}
this->countCardsPerCost[0] -= this->countLands;
// Counts by type
this->countCreatures = countCardsByType("Creature", myDeck);
this->countInstants = countCardsByType("Instant", myDeck);
this->countEnchantments = countCardsByType("Enchantment", myDeck);
this->countSorceries = countCardsByType("Sorcery", myDeck);
this->countSpells = this->countInstants + this->countEnchantments + this->countSorceries;
//this->countArtifacts = countCardsByType("Artifact", myDeck);
// Average mana costs
this->avgManaCost = ((this->cardCount - this->countLands) <= 0) ? 0 : (float) this->totalManaCost / (this->cardCount
- this->countLands);
this->avgCreatureCost = (this->countCreatures <= 0) ? 0 : (float) this->totalCreatureCost / this->countCreatures;
this->avgSpellCost = (this->countSpells <= 0) ? 0 : (float) this->totalSpellCost / this->countSpells;
// Probabilities
// TODO: this could be optimized by reusing results
for (int i = 0; i < Constants::STATS_FOR_TURNS; i++)
{
this->noLandsProbInTurn[i] = noLuck(this->cardCount, this->countLands, 7 + i) * 100;
this->noCreaturesProbInTurn[i] = noLuck(this->cardCount, this->countCreatures, 7 + i) * 100;
}
}
// This should probably be cached in DeckDataWrapper
// or at least be calculated for all common types in one go
int StatsWrapper::countCardsByType(const char * _type, DeckDataWrapper * myDeck)
{
int result = 0;
for (int i = 0; i < myDeck->Size(true); i++)
{
MTGCard * current = myDeck->getCard(i, true);
if (current->data->hasType(_type))
{
result += myDeck->count(current);
}
}
return result;
}
// n cards total, a of them are of desired type (A), x drawn
// returns probability of no A's
float StatsWrapper::noLuck(int n, int a, int x)
{
if ((a >= n) || (a == 0)) return 1;
if ((n == 0) || (x == 0) || (x > n) || (n - a < x)) return 0;
a = n - a;
float result = 1;
for (int i = 0; i < x; i++)
result *= (float) (a - i) / (n - i);
return result;
}
StatsWrapper::~StatsWrapper()
{
aiDeckNames.clear();
aiDeckStats.clear();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1164 -1220
View File
File diff suppressed because it is too large Load Diff
+115
View File
@@ -0,0 +1,115 @@
/*
* SimplePopup.cpp
*
* Created on: Nov 18, 2010
* Author: Michael
*/
#include "PrecompiledHeader.h"
#include "SimplePopup.h"
#include "JTypes.h"
#include "GameApp.h"
#include "DeckStats.h"
#include "DeckManager.h"
#include <iomanip>
SimplePopup::SimplePopup(int id, JGuiListener* listener, const int fontId, const char * _title, DeckMetaData* deckMetaData, MTGAllCards * collection) :
JGuiController(id, listener), mFontId(fontId), mCollection(collection)
{
mX = 35;
mY = 50;
mTitle = _title;
mMaxLines = 10;
mTextFont = resources.GetWFont(fontId);
this->mCount = 1;
stw = NULL;
Update(deckMetaData);
}
void SimplePopup::Render()
{
closed = false;
JRenderer *r = JRenderer::GetInstance();
string detailedInformation = getDetailedInformation(mDeckInformation->getFilename());
mTextFont->SetScale(0.85f);
const float textWidth = 183.0f;
const float textHeight = mTextFont->GetHeight() * 10;
r->DrawRoundRect(mX, mY, textWidth, textHeight, 2.0f, ARGB( 255, 125, 255, 0) );
r->FillRoundRect(mX, mY, textWidth, textHeight, 2.0f, ARGB( 255, 0, 0, 0 ) );
mTextFont->DrawString(detailedInformation.c_str(), mX + 20 , mY + 10);
}
void SimplePopup::Update(DeckMetaData* selectedDeck)
{
mDeckInformation = selectedDeck;
SAFE_DELETE(stw);
stw = NEW StatsWrapper(mDeckInformation->getDeckId());
stw->updateStats(mDeckInformation->getFilename(), mCollection);
}
string SimplePopup::getDetailedInformation(string filename)
{
ostringstream oss;
oss
<< "------- Deck Summary -----" << endl
<< "Cards: "<< stw->cardCount << endl
<< "Creatures: "<< setw(2) << stw->countCreatures
<< " Enchantments: " << stw->countEnchantments << endl
<< "Instants: " << setw(4) << stw->countInstants
<< " Sorceries: " << setw(2) << stw->countSorceries << endl
<< "Lands: "
<< "A: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_ARTIFACT ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_ARTIFACT ] << " "
<< "G: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_GREEN ] + stw->countLandsPerColor[ Constants::MTG_COLOR_GREEN ] << " "
<< "R: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_RED ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_RED ] << " "
<< "U: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_BLUE ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_BLUE ] << " "
<< "B: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_BLACK ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_BLACK ] << " "
<< "W: " << setw(2) << left << stw->countLandsPerColor[ Constants::MTG_COLOR_WHITE ] + stw->countBasicLandsPerColor[ Constants::MTG_COLOR_WHITE ] << endl
<< " --- Mana Curve --- " << endl;
for ( int costIdx = 0; costIdx < 15; ++costIdx )
if ( stw->countCardsPerCost[ costIdx ] > 0 )
oss << costIdx << ": " << setw(2) << left << stw->countCardsPerCost[ costIdx ] << " ";
oss << endl;
oss
<< " --- Average Cost --- " << endl
<< "Creature: "<< setprecision(2) << stw->avgCreatureCost << endl
<< "Mana: " << setprecision(2) << stw->avgManaCost << " "
<< "Spell: " << setprecision(2) << stw->avgSpellCost << endl;
return oss.str();
}
void SimplePopup::Update(float dt)
{
JButton key = mEngine->ReadButton();
CheckUserInput(key);
}
void SimplePopup::Close()
{
closed = true;
mCount = 0;
}
SimplePopup::~SimplePopup(void)
{
mTextFont = NULL;
mDeckInformation = NULL;
SAFE_DELETE(stw);
}
void SimplePopup::drawHorzPole(float x, float y, float width)
{
}
void SimplePopup::drawVertPole(float x, float y, float height)
{
}
+12
View File
@@ -837,6 +837,10 @@
RelativePath=".\src\SimplePad.cpp" RelativePath=".\src\SimplePad.cpp"
> >
</File> </File>
<File
RelativePath=".\src\SimplePopup.cpp"
>
</File>
<File <File
RelativePath=".\src\StoryFlow.cpp" RelativePath=".\src\StoryFlow.cpp"
> >
@@ -1254,6 +1258,10 @@
RelativePath=".\include\Rules.h" RelativePath=".\include\Rules.h"
> >
</File> </File>
<File
RelativePath=".\include\ShopItem.h"
>
</File>
<File <File
RelativePath=".\include\SimpleMenu.h" RelativePath=".\include\SimpleMenu.h"
> >
@@ -1266,6 +1274,10 @@
RelativePath=".\include\SimplePad.h" RelativePath=".\include\SimplePad.h"
> >
</File> </File>
<File
RelativePath=".\include\SimplePopup.h"
>
</File>
<File <File
RelativePath=".\include\StoryFlow.h" RelativePath=".\include\StoryFlow.h"
> >