- fix issue 392 (broken tests)
- Fix a bunch of memory leaks (guys please be careful!)
- Added Logging facility in JGE
- HBL Compatibility (cleaned up some code with MP3 in JGE)
- Added "winGame" ability. Currently used mostly by the story mode, but some cards could probably need it too
- Improved story mode and uncommented it from the source.
-- The current campaign is of course very basic, anybody who wants to improve it or create other ones feel free to do so
-- TODO (short term): save progress, rewards system, improve tutorial campaign
-- I'll talk a bit more about this on the forums/email after a night of sleep
This commit is contained in:
wagic.the.homebrew@gmail.com
2010-04-26 14:27:34 +00:00
parent d311f88f93
commit a3cbbedd3c
30 changed files with 468 additions and 210 deletions
+14 -7
View File
@@ -17,8 +17,7 @@
#include "../include/GameStateOptions.h"
#include "../include/GameStateShop.h"
#include "../include/GameStateAwards.h"
//Story mode not yet ready
//#include "../include/GameStateStory.h"
#include "../include/GameStateStory.h"
#include "../include/DeckStats.h"
#include "../include/DeckMetaData.h"
#include "../include/Translate.h"
@@ -89,8 +88,10 @@ void GameApp::Create()
options.theGame = this;
//Ensure that options are partially loaded before loading files.
LOG("options.reloadProfile()");
options.reloadProfile();
LOG("Checking for music files");
//Test for Music files presence
string filepath = RESPATH;
filepath = filepath + "/" + resources.musicFile("Track0.mp3");
@@ -108,7 +109,10 @@ void GameApp::Create()
else
HasMusic = 0;
LOG("Loading Textures");
LOG("--Loading menuicons.png");
resources.RetrieveTexture("menuicons.png",RETRIEVE_MANAGE);
//Creating thes quad in this specific order allows us to have them in the correct order to call them by integer id
manaIcons[Constants::MTG_COLOR_GREEN] = resources.RetrieveQuad("menuicons.png", 2 + 0*36, 38, 32, 32, "c_green",RETRIEVE_MANAGE);
manaIcons[Constants::MTG_COLOR_BLUE] = resources.RetrieveQuad("menuicons.png", 2 + 1*36, 38, 32, 32, "c_blue",RETRIEVE_MANAGE);
@@ -121,6 +125,7 @@ void GameApp::Create()
for (int i = sizeof(manaIcons)/sizeof(manaIcons[0]) - 1; i >= 0; --i) manaIcons[i]->SetHotSpot(16,16);
LOG("--Loading Other Textures");
resources.RetrieveTexture("back.jpg",RETRIEVE_MANAGE);
JQuad * jq = resources.RetrieveQuad("back.jpg", 0, 0, 0, 0, "back",RETRIEVE_MANAGE);
if (jq) jq->SetHotSpot(jq->mWidth/2, jq->mHeight/2);
@@ -158,9 +163,11 @@ void GameApp::Create()
jq = resources.RetrieveQuad("shadow.png", 0, 0, 16, 16,"shadow",RETRIEVE_MANAGE);
jq->SetHotSpot(8, 8);
jq = resources.RetrieveQuad("phasebar.png",0,0,0,0,"phasebar",RETRIEVE_MANAGE);
LOG("Init Collection");
collection = NEW MTGAllCards();
LOG("Loading Particles");
Particles[0] = NEW hgeParticleSystem("graphics/particle1.psi", resources.GetQuad("particles"));
Particles[1] = NEW hgeParticleSystem("graphics/particle2.psi", resources.GetQuad("particles"));
Particles[2] = NEW hgeParticleSystem("graphics/particle3.psi", resources.GetQuad("particles"));
@@ -168,6 +175,7 @@ void GameApp::Create()
Particles[4] = NEW hgeParticleSystem("graphics/particle5.psi", resources.GetQuad("particles"));
Particles[5] = NEW hgeParticleSystem("graphics/particle7.psi", resources.GetQuad("particles"));
LOG("Creating Game States");
mGameStates[GAME_STATE_DECK_VIEWER] = NEW GameStateDeckViewer(this);
mGameStates[GAME_STATE_DECK_VIEWER]->Create();
@@ -186,10 +194,8 @@ void GameApp::Create()
mGameStates[GAME_STATE_AWARDS] = NEW GameStateAwards(this);
mGameStates[GAME_STATE_AWARDS]->Create();
//Story mode not yet ready
//mGameStates[GAME_STATE_STORY] = NEW GameStateStory(this);
//mGameStates[GAME_STATE_STORY]->Create();
mGameStates[GAME_STATE_STORY] = NEW GameStateStory(this);
mGameStates[GAME_STATE_STORY]->Create();
mGameStates[GAME_STATE_TRANSITION] = NULL;
@@ -206,6 +212,7 @@ void GameApp::Create()
sprintf(buf, "size of CardPrimitive : %llu\n" , (long long unsigned int)sizeof(CardPrimitive));
OutputDebugString(buf);
LOG("Game Creation Done.");
}
+8 -4
View File
@@ -130,6 +130,7 @@ void GameStateMenu::Destroy()
}
void GameStateMenu::Start(){
LOG("GameStateMenu::Start");
JRenderer::GetInstance()->EnableVSync(true);
subMenuController = NULL;
SAFE_DELETE(mGuiController);
@@ -293,6 +294,7 @@ void GameStateMenu::setLang(int id){
}
void GameStateMenu::loadLangMenu(){
LOG("GameStateMenu::loadLangMenu");
subMenuController = NEW SimpleMenu(103, this, Constants::MENU_FONT, 150,60);
if (!subMenuController) return;
resetDirectory();
@@ -320,9 +322,11 @@ void GameStateMenu::loadLangMenu(){
}
}
resetDirectory();
LOG("GameStateMenu::loadLangMenu - Done");
}
void GameStateMenu::listPrimitives(){
LOG("GameStateMenu::listPrimitives");
resetDirectory();
if (!mDip){
mDip = opendir("Res/sets/primitives/");
@@ -338,6 +342,7 @@ void GameStateMenu::listPrimitives(){
}
resetDirectory();
primitivesLoadCounter = 0;
LOG("GameStateMenu::listPrimitives - Done");
}
void GameStateMenu::ensureMGuiController(){
@@ -446,8 +451,7 @@ void GameStateMenu::Update(float dt)
currentState = MENU_STATE_MAJOR_SUBMENU;
subMenuController = NEW SimpleMenu(102, this, Constants::MENU_FONT, 150,60);
if (subMenuController){
//Story mode not yet ready
//subMenuController->Add(SUBMENUITEM_STORY,"Story");
subMenuController->Add(SUBMENUITEM_STORY,"Story");
subMenuController->Add(SUBMENUITEM_CLASSIC,"Classic");
if (options[Options::MOMIR_MODE_UNLOCKED].number)
subMenuController->Add(SUBMENUITEM_MOMIR, "Momir Basic");
@@ -458,8 +462,8 @@ void GameStateMenu::Update(float dt)
subMenuController->Add(SUBMENUITEM_CANCEL, "Cancel");
}
}else{
if (mParent->gameType == GAME_TYPE_STORY)
mParent->DoTransition(TRANSITION_FADE,GAME_STATE_STORY);
if (mParent->gameType == GAME_TYPE_STORY )
mParent->DoTransition(TRANSITION_FADE, GAME_STATE_STORY);
else
mParent->DoTransition(TRANSITION_FADE,GAME_STATE_DUEL);
currentState = MENU_STATE_MAJOR_MAINMENU;
+3 -1
View File
@@ -71,12 +71,14 @@ void GameStateStory::Update(float dt) {
//return;
}
if (flow){
flow->Update(dt);
if (flow->currentPageId == "End") {
if (mEngine->GetButtonClick(JGE_BTN_OK) || mEngine->GetButtonClick(JGE_BTN_SEC)){
mParent->DoTransition(TRANSITION_FADE,GAME_STATE_MENU);
}
}
else {
flow->Update(dt);
}
}
}
+23 -13
View File
@@ -57,6 +57,7 @@ Counter * AbilityFactory::parseCounter(string s, MTGCardInstance * target, Spell
wpi = NEW WParsedInt(atoi(nbstr.c_str()));
}
nb = wpi->getValue();
delete(wpi);
end = separator;
}
@@ -560,6 +561,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
OutputDebugString("MTGABILITY: Parsing Error:");
OutputDebugString(s.c_str());
OutputDebugString("\n");
delete(cost);
return NULL;
}
@@ -757,6 +759,16 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
return a;
}
// Win the game
found = s.find("wingame");
if (found != string::npos){
Damageable * d = NULL;
if (spell) d = spell->getNextDamageableTarget();
MTGAbility * a = NEW AAWinGame(id,card,d,NULL,0,who);
a->oneShot = 1;
return a;
}
//Draw
found = s.find("draw:");
if (found != string::npos){
@@ -849,6 +861,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
Counter * counter = parseCounter(counterString,target,spell);
if (counter){
MTGAbility * a = NEW AACounter(id,card,target,counter->name.c_str(),counter->power,counter->toughness,counter->nb);
delete(counter);
a->oneShot = 1;
return a;
}
@@ -1297,11 +1310,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
game->addObserver(NEW AFireball(_id, card,spell, x));
break;
}
case 1245: //Force of Nature
{
game->addObserver(NEW AForceOfNature(_id,card));
break;
}
case 1112: //Howling Mine
{
game->addObserver(NEW AHowlingMine(_id, card));
@@ -1457,11 +1465,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
game->addObserver(NEW ALivingArtifact( _id, card, card->target));
break;
}
case 1166: //Lord Of The Pit
{
game->addObserver(NEW ALordOfThePit( _id, card));
break;
}
case 1209: //Mana Short
{
Player * player = spell->getNextPlayerTarget();
@@ -1906,6 +1909,7 @@ int ActivatedAbility::reactToClick(MTGCardInstance * card){
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
game->currentlyActing()->getManaPool()->pay(cost);
cost->doPayExtra();
SAFE_DELETE(abilityCost);
abilityCost = previousManaPool->Diff(player->getManaPool());
delete previousManaPool;
}
@@ -1928,6 +1932,7 @@ int ActivatedAbility::reactToTargetClick(Targetable * object){
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
game->currentlyActing()->getManaPool()->pay(cost);
cost->doPayExtra();
SAFE_DELETE(abilityCost);
abilityCost = previousManaPool->Diff(player->getManaPool());
delete previousManaPool;
}
@@ -1938,9 +1943,12 @@ int ActivatedAbility::reactToTargetClick(Targetable * object){
}
ActivatedAbility::~ActivatedAbility(){
if (!isClone){
//Ok, this will probably lead to crashes, maybe with lord abilities involving "X" costs.
// If that's the case, we need to improve the clone() method of GenericActivatedAbility and GenericTargetAbility, I think
// Erwan 2004/04/25
//if (!isClone){
SAFE_DELETE(abilityCost);
}
//}
}
ostream& ActivatedAbility::toString(ostream& out) const
@@ -2011,7 +2019,9 @@ void TargetAbility::Render(){
int TargetAbility::resolve(){
Targetable * t = tc->getNextTarget();
if (t && ability){
source->X = abilityCost->Diff(cost)->hasX();
ManaCost * diff = abilityCost->Diff(cost);
source->X = diff->hasX();
delete (diff);
ability->target = t;
if (ability->oneShot) return ability->resolve();
MTGAbility * a = ability->clone();
+2 -2
View File
@@ -70,9 +70,9 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
OutputDebugString("Counter\n");
size_t counter_start = value.find("(");
size_t counter_end = value.find(")", counter_start);
AbilityFactory * abf = NEW AbilityFactory();
AbilityFactory abf;
string counterString = value.substr(counter_start+1,counter_end-counter_start-1);
Counter * counter = abf->parseCounter(counterString,c);
Counter * counter = abf.parseCounter(counterString,c);
size_t separator = value.find(",",counter_start);
size_t separator2 = string::npos;
if (separator != string::npos) {
+98 -7
View File
@@ -8,9 +8,64 @@
#include <JGE.h>
#include <JFileSystem.h>
StoryGraphicalElement::StoryGraphicalElement(float x, float y): JGuiObject(0), mX(x),mY(y) {
}
StoryText::StoryText(string text, float _mX, float _mY, string _align):StoryGraphicalElement(_mX,_mY), text(text) {
align = JGETEXT_LEFT;
if (_align.compare("center") == 0) {
align = JGETEXT_CENTER;
}else if (_align.compare("right") == 0) {
align = JGETEXT_RIGHT;
}
if (align == JGETEXT_CENTER && mX == 0){
mX = SCREEN_WIDTH/2;
}
}
void StoryText::Render() {
JLBFont * mFont = resources.GetJLBFont(Constants::MAIN_FONT);
mFont->SetColor(ARGB(200,255,255,255));
mFont->SetScale(1.0);
mFont->DrawString(text.c_str(), mX, mY, align);
}
void StoryText::Update(float dt){
//Nothing for now
}
ostream& StoryText::toString(ostream& out) const
{
return out << "StoryText ::: text : " << text;
}
StoryImage::StoryImage(string img, float mX, float mY):StoryGraphicalElement(mX,mY), img(img) {
}
void StoryImage::Render() {
JQuad * quad = resources.RetrieveQuad(img);
if (quad) {
float x = mX;
if (mX == -1) {
x = SCREEN_WIDTH/2;
quad->SetHotSpot(quad->mWidth/2, 0);
}
JRenderer::GetInstance()->RenderQuad(quad,x, mY);
}
}
void StoryImage::Update(float dt){
//Nothing for now
}
ostream& StoryImage::toString(ostream& out) const
{
return out << "StoryImage ::: img : " << img;
}
StoryPage::StoryPage(StoryFlow * mParent):mParent(mParent){
}
StoryFlow::StoryFlow(string folder): folder(folder){
string path = "campaigns/";
path.append(folder).append("/story.xml");
@@ -155,15 +210,43 @@ void StoryDuel::Render(){
game->Render();
}
string StoryDialog::safeAttribute(TiXmlElement* element, string attribute) {
string s;
if (element->Attribute(attribute.c_str())){
s = element->Attribute(attribute.c_str());
}
return s;
}
StoryDialog::StoryDialog(TiXmlElement* root, StoryFlow * mParent):JGuiListener(), JGuiController(1,NULL), StoryPage(mParent) {
StoryDialog::StoryDialog(TiXmlElement* root, StoryFlow * mParent):StoryPage(mParent), JGuiListener(), JGuiController(1,NULL) {
for (TiXmlNode* node = root->FirstChild(); node; node = node->NextSibling()) {
TiXmlElement* element = node->ToElement();
if (element) {
if (strcmp(element->Value(), "text")==0) {
const char* textC = element->GetText();
text = textC;
string sX = safeAttribute(element, "x");
float x = atof(sX.c_str());
string sY = safeAttribute(element,"y");
float y = atof(sY.c_str());
string align = safeAttribute(element,"align");
const char* textC = element->GetText();
string text = textC;
graphics.push_back(NEW StoryText(text,x,y,align));
}
else if (strcmp(element->Value(), "img")==0) {
string sX = safeAttribute(element,"x");
float x = atof(sX.c_str());
//special case to force center
if (sX.compare("") == 0 ){
x = -1;
}
string sY = safeAttribute(element,"y");
float y = atof(sY.c_str());
const char* imgC = element->GetText();
string img = imgC;
img = string("campaigns/").append(mParent->folder).append("/").append(img);
graphics.push_back(NEW StoryImage(img,x,y));
}
else if (strcmp(element->Value(), "answer")==0){
string id = element->Attribute("goto");
@@ -183,14 +266,16 @@ StoryDialog::StoryDialog(TiXmlElement* root, StoryFlow * mParent):JGuiListener()
void StoryDialog::Update(float dt){
JGuiController::Update(dt);
for (size_t i = 0; i < graphics.size(); ++i){
graphics[i]->Update(dt);
}
}
void StoryDialog::Render() {
JLBFont * mFont = resources.GetJLBFont(Constants::MAIN_FONT);
mFont->SetColor(ARGB(255,255,255,255));
mFont->SetScale(1.0);
mFont->DrawString(text.c_str(), 0, 0);
for (size_t i = 0; i < graphics.size(); ++i){
graphics[i]->Render();
}
JGuiController::Render();
}
@@ -198,6 +283,12 @@ void StoryDialog::ButtonPressed(int controllerid,int controlid) {
mParent->gotoPage(((StoryChoice *)mObjects[controlid])->pageId);
}
StoryDialog::~StoryDialog(){
for (size_t i = 0; i < graphics.size(); ++i){
delete(graphics[i]);
}
}
StoryPage * StoryFlow::loadPage(TiXmlElement* element){
TiXmlNode* typeNode = element->FirstChild("type");
if (!typeNode) return NULL;
+3 -2
View File
@@ -215,13 +215,14 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
size_t start = attribute.find("{");
size_t end = attribute.find("}");
string counterString = attribute.substr(start+1,end-start-1);
AbilityFactory * abf = NEW AbilityFactory();
Counter * counter = abf->parseCounter(counterString,card);
AbilityFactory abf;
Counter * counter = abf.parseCounter(counterString,card);
if (counter) {
cd->counterName = counter->name;
cd->counterNB = counter->nb;
cd->counterPower = counter->power;
cd->counterToughness = counter->toughness;
delete(counter);
}
if (minus) {
cd->counterComparisonMode = COMPARISON_LESS;
+6 -2
View File
@@ -5,6 +5,10 @@
#include "../include/CardDescriptor.h"
ThisDescriptor::~ThisDescriptor(){
//nothing to do for now
}
//Returns the amount by which a value passes the comparison.
int ThisDescriptor::matchValue(int value){
switch (comparisonMode){
@@ -98,8 +102,8 @@ ThisDescriptor * ThisDescriptorFactory::createThisDescriptor(string s){
size_t start = s.find("{");
size_t end = s.find("}");
string counterString = s.substr(start+1,end-start-1);
AbilityFactory * abf = NEW AbilityFactory();
Counter * counter = abf->parseCounter(counterString,NULL);
AbilityFactory abf;
Counter * counter = abf.parseCounter(counterString,NULL);
if (counter) {
if (criterionFound) counter->nb = criterion;
ThisCounter * td = NEW ThisCounter(counter);
+5
View File
@@ -534,6 +534,11 @@ string WResourceManager::graphicsFile(const string filename){
if(fileOK(buf,true))
return buf;
//Failure. Check raw faile.
sprintf(buf,"%s",filename.c_str());
if(fileOK(buf,true))
return buf;
//Complete abject failure. Probably a crash...
return graphdir;
}