Jeck - Added theme substyles, which are chosen dynamically based on the player's deck composition. Also added lazy unit test for booster packs, though there should be a better way to framework this.

This commit is contained in:
wagic.jeck
2010-08-28 10:51:38 +00:00
parent 3ad28096b1
commit 8114944db9
46 changed files with 415 additions and 26 deletions
+2
View File
@@ -193,6 +193,8 @@ void GameObserver::startGame(Rules * rules){
if (rules)
rules->initPlayers();
options.automaticStyle(players[0],players[1]);
mLayers = NEW DuelLayers();
mLayers->init();
+34
View File
@@ -4,6 +4,7 @@
#include "../include/GameOptions.h"
#include "../include/Translate.h"
#include "../include/OptionItem.h"
#include "../include/StyleManager.h"
#include <iostream>
#include <sstream>
#include <fstream>
@@ -31,6 +32,7 @@ const string Options::optionNames[] = {
"maxGrade",
"economic_difficulty",
"transitions",
"bgStyle",
"interruptSeconds",
#if defined(WIN32)
"keybindings_win",
@@ -409,16 +411,46 @@ GameSettings options;
GameSettings::GameSettings()
{
styleMan = NULL;
globalOptions = NULL;
theGame = NULL;
profileOptions = NULL;
//reloadProfile should be before using options.
}
WStyle * GameSettings::getStyle() {
if(!styleMan) styleMan = new StyleManager();
return styleMan->get();
}
StyleManager * GameSettings::getStyleMan() {
if(!styleMan) styleMan = new StyleManager();
return styleMan;
}
void GameSettings::automaticStyle(Player * p1, Player * p2){
if(!styleMan) styleMan = new StyleManager();
MTGDeck * decks[2];
for(int i=0;i<2;i++){
decks[i] = new MTGDeck(GameApp::collection);
Player * p; if(i == 0) p = p1; else p = p2;
map<MTGCardInstance *,int>::iterator it;
for(it = p->game->library->cardsMap.begin();it != p->game->library->cardsMap.end();it++){
decks[i]->add(it->first);
}
}
styleMan->determineActive(decks[0],decks[1]);
for(int i=0;i<2;i++){
SAFE_DELETE(decks[i]);
}
}
GameSettings::~GameSettings(){
SAFE_DELETE(globalOptions);
SAFE_DELETE(profileOptions);
SAFE_DELETE(keypad);
SAFE_DELETE(styleMan);
}
bool GameSettings::newAward(){
@@ -591,6 +623,7 @@ void GameSettings::checkProfile(){
//Give the player their first deck
createUsersFirstDeck(setId);
}
getStyleMan()->determineActive(NULL,NULL);
}
void GameSettings::createUsersFirstDeck(int setId){
@@ -766,6 +799,7 @@ OptionEconDifficulty::OptionEconDifficulty(){
mDef.values.push_back(EnumDefinition::assoc(Constants::ECON_LUCK, "Luck"));
mDef.values.push_back(EnumDefinition::assoc(Constants::ECON_EASY, "Easy"));
};
//GameOptionAward
GameOptionAward::GameOptionAward(){
achieved = time(NULL);
+1
View File
@@ -242,6 +242,7 @@ void GameStateDuel::Update(float dt)
rules = NEW Rules("testsuite.txt");
loadTestSuitePlayers();
mGamePhase = DUEL_STATE_PLAY;
testSuite->pregameTests();
testSuite->initGame();
}else{
if (!game){
+7 -1
View File
@@ -51,12 +51,18 @@ void GameStateOptions::Start()
optionsList->Add(NEW WGuiHeader("User Options"));
WDecoConfirm * cPrf = NEW WDecoConfirm(this,NEW OptionProfile(mParent,this));
cPrf->confirm = "Use this Profile";
OptionDirectory * od = NEW OptionTheme();
OptionThemeStyle * ots = NEW OptionThemeStyle("Theme Style");
OptionDirectory * od = NEW OptionTheme(ots);
WDecoConfirm * cThm = NEW WDecoConfirm(this,od);
cThm->confirm = "Use this Theme";
WDecoConfirm * cStyle = NEW WDecoConfirm(this,ots);
cStyle->confirm = "Use this Style";
optionsList->Add(NEW WGuiSplit(cPrf,cThm));
optionsList->Add(cStyle);
optionsList->Add(NEW WGuiButton(NEW WGuiHeader("New Profile"),-102,4,this));
optionsList->Add(NEW WDecoCheat(NEW OptionInteger(Options::CHEATMODE, "Enable cheat mode")));
optionsTabs->Add(optionsList);
+46
View File
@@ -9,6 +9,8 @@
#include "../include/MTGPack.h"
#include "../include/Translate.h"
#include "../include/GameOptions.h"
#include "../include/TestSuiteAI.h"
#include <hge/hgedistort.h>
float GameStateShop::_x1[] = { 79, 19, 27,103,154,187,102,144,198,133,183};
@@ -787,3 +789,47 @@ void ShopBooster::addToDeck(MTGDeck * d, WSrcCards * srcCards){
else
pack->assemblePack(d);
}
#ifdef TESTSUITE
bool ShopBooster::unitTest(){
//this tests the default random pack creation.
MTGDeck * d = NEW MTGDeck(GameApp::collection);
char result[1024];
randomStandard();
MTGPack * mP = MTGPacks::getDefault();
if(!altSet && mainSet->mPack) mP = mainSet->mPack;
char buf[512];
if(!altSet) sprintf(buf,"set:%s;",mainSet->id.c_str());
else sprintf(buf,"set:%s;|set:%s;",mainSet->id.c_str(),altSet->id.c_str());
mP->pool = buf;
mP->assemblePack(d); //Use the primary packfile. assemblePack deletes pool.
DeckDataWrapper* ddw = NEW DeckDataWrapper(d);
int u = 0, r = 0;
int card = 0;
for(int i=0;i<ddw->Size(true);i++){
MTGCard * c = ddw->getCard(i);
if(!c) break;
if(c->getRarity() == Constants::RARITY_R || c->getRarity() == Constants::RARITY_M)
r+=ddw->count(c);
else if(c->getRarity() == Constants::RARITY_U)
u+=ddw->count(c);
card++;
}
if(r != 1 || u != 3 ){
sprintf(result, "<span class=\"error\">==Unexpected rarity count==</span><br />");
TestSuite::Log(result);
return false;
}
if(ddw->getCount() < 14) {
sprintf(result, "<span class=\"error\">==Unexpected card count==</span><br />");
TestSuite::Log(result);
return false;
}
sprintf(result, "<span class=\"success\">==Test Succesful !==</span><br />");
TestSuite::Log(result);
return true;
}
#endif
+3 -12
View File
@@ -27,22 +27,13 @@ HandLimitor::HandLimitor(GuiHand* hand) : hand(hand) {}
GuiHand::GuiHand(CardSelector* cs, MTGHand* hand) : GuiLayer(), hand(hand), cs(cs)
{
JTexture* texture = resources.GetTexture("handback.png");
if (texture)
{
back = NEW JQuad(texture, 0, 0, 101, 250);
back->SetTextureRect(1, 0, 100, 250);
}
else
{
back = NULL;
GameApp::systemError = "Error loading hand texture : " __FILE__;
}
back = resources.RetrieveTempQuad("handback.png");
if(back) back->SetTextureRect(1, 0, 100, 250);
else GameApp::systemError = "Error loading hand texture : " __FILE__;
}
GuiHand::~GuiHand()
{
delete(back);
for (vector<CardView*>::iterator it = cards.begin(); it != cards.end(); ++it)
delete(*it);
}
+2 -5
View File
@@ -24,15 +24,12 @@ static int colors[] =
GuiPhaseBar::GuiPhaseBar() : phase(NULL), angle(0.0f)
{
JQuad * quad;
JQuad * quad = NULL;
if ((quad = resources.GetQuad("phasebar")) != NULL){
quad->mHeight = Height;
quad->mWidth = Width;
}
else
{
GameApp::systemError = "Error loading phasebar texture : " __FILE__;
}
else GameApp::systemError = "Error loading phasebar texture : " __FILE__;
}
GuiPhaseBar::~GuiPhaseBar()
+27 -1
View File
@@ -5,6 +5,7 @@
#include "../include/Translate.h"
#include "../include/Subtypes.h"
#include "../include/TranslateKeys.h"
#include "../include/StyleManager.h"
#include <dirent.h>
#include <stdlib.h>
#include <algorithm>
@@ -216,6 +217,27 @@ void OptionProfile::confirmChange(bool confirmed){
}
return;
}
//OptionThemeStyle
OptionThemeStyle::OptionThemeStyle(string _displayValue) : OptionSelect(Options::GUI_STYLE,_displayValue)
{
Reload();
initSelections();
};
bool OptionThemeStyle::Visible() {
return (selections.size() > 1);
};
void OptionThemeStyle::confirmChange(bool confirmed){
options.getStyleMan()->determineActive(NULL,NULL);
}
void OptionThemeStyle::Reload(){
selections.clear();
addSelection("Dynamic");
map<string,WStyle*>::iterator it;
StyleManager * sm = options.getStyleMan();
for(it=sm->styles.begin();it!=sm->styles.end();it++)
addSelection(it->first);
}
//OptionLanguage
OptionLanguage::OptionLanguage(string _displayValue) : OptionSelect(Options::LANG,_displayValue)
{
@@ -348,12 +370,13 @@ OptionDirectory::OptionDirectory(string root, int id, string displayValue, strin
}
const string OptionTheme::DIRTESTER = "preview.png";
OptionTheme::OptionTheme() : OptionDirectory(RESPATH"/themes", Options::ACTIVE_THEME, "Current Theme", DIRTESTER){
OptionTheme::OptionTheme(OptionThemeStyle * style) : OptionDirectory(RESPATH"/themes", Options::ACTIVE_THEME, "Current Theme", DIRTESTER){
addSelection("Default");
sort(selections.begin(),selections.end());
initSelections();
mFocus=false;
bChecked = false;
ts = style;
}
JQuad * OptionTheme::getImage(){
char buf[512];
@@ -429,6 +452,9 @@ void OptionTheme::confirmChange(bool confirmed){
value = prior_value;
else{
setData();
options.getStyleMan()->loadRules();
if(ts) ts->Reload();
resources.Refresh(); //Update images
prior_value = value;
}
+146
View File
@@ -0,0 +1,146 @@
#include "../include/config.h"
#include "../include/GameApp.h"
#include "../include/GuiBackground.h"
#include "../include/GameObserver.h"
#include "../include/Rules.h"
#include "../include/DeckDataWrapper.h"
#include "../include/WFilter.h"
#include "../include/StyleManager.h"
#include "../../../JGE/src/tinyxml/tinyxml.h"
void StyleManager::killRules(){
activeStyle = "";
vector<WStyleRule*>::iterator i;
for(i=rules.begin();i!=rules.end();i++)
SAFE_DELETE(*i);
rules.clear();
map<string,WStyle*>::iterator mi;
for(mi=styles.begin();mi!=styles.end();mi++){
SAFE_DELETE(mi->second);
}
styles.clear();
}
StyleManager::StyleManager(){
loadRules();
}
StyleManager::~StyleManager(){
killRules();
}
string WStyle::stylized(string filename){
if(mapping.find(filename) != mapping.end())
return mapping[filename];
return filename;
}
void StyleManager::loadRules(){
killRules();
//TODO Placeholder until XML format available.
string filename = RESPATH"/" + resources.graphicsFile("style.txt");
TiXmlDocument xmlfile(filename.c_str());
if(!xmlfile.LoadFile())
return;
TiXmlHandle hDoc(&xmlfile);
TiXmlElement * pRule;
for(pRule = hDoc.FirstChildElement().Element();pRule!=NULL;pRule=pRule->NextSiblingElement()){
//root should be "pack"
string tag = pRule->Value();
std::transform(tag.begin(),tag.end(),tag.begin(),::tolower);
if(tag == "activebg"){
//After validating, handle actual loading.
TiXmlElement * pSlot;
const char * holder = NULL;
holder = pRule->Attribute("source");
if(holder) playerSrc = atoi(holder); else playerSrc = -1;
for (pSlot=pRule->FirstChildElement();pSlot!=NULL;pSlot=pSlot->NextSiblingElement()){
//Load slot.
tag = pSlot->Value();
std::transform(tag.begin(),tag.end(),tag.begin(),::tolower);
if(tag != "case") continue;
WStyleRule * r = NEW WStyleRule();
rules.push_back(r);
holder = pSlot->Attribute("rule");
if(holder) r->filter = holder;
r->style = pSlot->GetText();
}
} else if(tag == "style"){
TiXmlElement * pSlot;
const char * holder = NULL;
holder = pRule->Attribute("name");
if(!holder) continue;
string sname = holder;
WStyle * s = NEW WStyle();
for (pSlot=pRule->FirstChildElement();pSlot!=NULL;pSlot=pSlot->NextSiblingElement()){
tag = pSlot->Value();
std::transform(tag.begin(),tag.end(),tag.begin(),::tolower);
if(tag.size() && pSlot->GetText())
s->mapping[tag] = pSlot->GetText();
}
if(styles[sname]) SAFE_DELETE(styles[sname]);
styles[sname] = s;
}
}
determineActive(NULL,NULL);
return;
}
WStyle * StyleManager::get() {
if(styles.find(activeStyle) != styles.end())
return styles[activeStyle];
return NULL;
};
void StyleManager::determineActive(MTGDeck * p1, MTGDeck * p2)
{
string check = options[Options::GUI_STYLE].str;
if(check.size() && styles.find(check) != styles.end()){
string prior = activeStyle;
activeStyle = check;
if(prior != activeStyle)
resources.Refresh();
return;
}
topRule = -1; topSize = 0;
MTGDeck * tempDeck = NEW MTGDeck(GameApp::collection);
if(p1 && playerSrc != 2) tempDeck->add(p1);
if(p2 && playerSrc != 1) tempDeck->add(p2);
WCFilterFactory * ff = WCFilterFactory::GetInstance();
if(tempDeck){
DeckDataWrapper * ddw = NEW DeckDataWrapper(tempDeck);
for(int r=0;r<(int)rules.size();r++){
ddw->clearFilters();
ddw->addFilter(ff->Construct(rules[r]->filter));
ddw->validate();
int ct = ddw->getCount(WSrcDeck::FILTERED_COPIES);
if(ct > topSize) {
topRule = r;
topSize = ct;
}
}
delete tempDeck;
delete ddw;
}
string prior = activeStyle;
activeStyle = "";
if(topRule >= 0){
map<string,WStyle*>::iterator mi = styles.find(rules[topRule]->style);
if(mi != styles.end())
activeStyle = mi->first;
}
if(prior != activeStyle)
resources.Refresh();
}
+15 -1
View File
@@ -6,6 +6,7 @@
#include "../include/GuiCombat.h"
#include "../include/Rules.h"
#include "../include/GameObserver.h"
#include "../include/GameStateShop.h"
#include <string>
using std::string;
@@ -297,7 +298,6 @@ void TestSuite::initGame(){
}
OutputDebugString("TESTUITE Init Game Done !\n");
}
int TestSuite::Log(const char * text){
ofstream file (RESPATH"/test/results.html",ios_base::app);
if (file){
@@ -582,3 +582,17 @@ int TestSuite::load(const char * _filename){
return 1;
}
void TestSuite::pregameTests(){
//Test Booster Generation
srand(1024);
char result[1024];
ShopBooster sb;
for(int i=0;i<5;i++){
nbTests++;
sprintf(result, "<h3>pregame/BoosterTest#%i</h3>", i);
Log(result);
if(!sb.unitTest())
nbFailed++;
}
}
+11
View File
@@ -9,6 +9,7 @@
#include <JFileSystem.h>
#include <assert.h>
#include "../include/WResourceManager.h"
#include "../include/StyleManager.h"
#if defined (WIN32)
#include <sys/types.h>
#include <sys/stat.h>
@@ -515,6 +516,16 @@ string WResourceManager::graphicsFile(const string filename){
//Check the theme folder.
string theme = options[Options::ACTIVE_THEME].str;
//Check for a theme style renaming:
if(filename != "style.txt"){
WStyle * ws = options.getStyle();
if(ws){
sprintf(buf,"themes/%s/%s",theme.c_str(),ws->stylized(filename).c_str());
if(fileOK(buf,true))
return buf;
}
}
if(theme != "" && theme != "Default"){
sprintf(buf,"themes/%s/%s",theme.c_str(),filename.c_str());
if(fileOK(buf,true))