Erwan
- 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:
@@ -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.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user