diff --git a/JGE/include/Threading.h b/JGE/include/Threading.h index 532467515..fe3c79068 100644 --- a/JGE/include/Threading.h +++ b/JGE/include/Threading.h @@ -449,15 +449,15 @@ namespace boost { detail::thread_data_ptr mThreadInfo; public: - static threadImpl* spThreadImpl; threadImpl(detail::thread_data_ptr threadInfo) : mThreadInfo(threadInfo) { setTerminationEnabled(); - spThreadImpl = this; }; static void mymsleep(unsigned long msecs) { - spThreadImpl->msleep(msecs); + QThread* currentThread = QThread::currentThread(); + if(currentThread) + currentThread->msleep(msecs); } protected: void run() @@ -467,8 +467,6 @@ namespace boost } }; - threadImpl* threadImpl::spThreadImpl = 0; - /** ** A simplistic implementation of boost::thread, using QThread. ** diff --git a/projects/mtg/include/AIMomirPlayer.h b/projects/mtg/include/AIMomirPlayer.h index 39ca3fc95..07526778f 100644 --- a/projects/mtg/include/AIMomirPlayer.h +++ b/projects/mtg/include/AIMomirPlayer.h @@ -10,7 +10,7 @@ public: int getEfficiency(OrderedAIAction * action); int momir(); int computeActions(); - static MTGAbility * momirAbility; + MTGAbility * momirAbility; MTGAbility * getMomirAbility(); }; diff --git a/projects/mtg/include/AIPlayer.h b/projects/mtg/include/AIPlayer.h index d09802f3f..6042dd9fa 100644 --- a/projects/mtg/include/AIPlayer.h +++ b/projects/mtg/include/AIPlayer.h @@ -26,8 +26,6 @@ class AIPlayer; class AIAction { -protected: - static int currentId; public: AIPlayer * owner; MTGAbility * ability; @@ -43,7 +41,6 @@ public: AIAction(AIPlayer * owner, MTGAbility * a, MTGCardInstance * c, MTGCardInstance * t = NULL) : owner(owner), ability(a), player(NULL), click(c), target(t),playerAbilityTarget(NULL) { - id = currentId++; }; AIAction(AIPlayer * owner, MTGCardInstance * c, MTGCardInstance * t = NULL); @@ -56,13 +53,11 @@ public: AIAction(AIPlayer * owner, MTGAbility * a, MTGCardInstance * c, vectortargetCards) : owner(owner), ability(a), player(NULL), click(c), mAbilityTargets(targetCards),playerAbilityTarget(NULL) { - id = currentId++; }; AIAction(AIPlayer * owner, MTGAbility * a, Player * p, MTGCardInstance * c)//player targeting through abilities. : owner(owner), ability(a), click(c),target(NULL), playerAbilityTarget(p) { - id = currentId++; }; int Act(); int clickMultiAct(vector&actionTargets); diff --git a/projects/mtg/include/ActionStack.h b/projects/mtg/include/ActionStack.h index a8c5f5917..03c9ec1a2 100644 --- a/projects/mtg/include/ActionStack.h +++ b/projects/mtg/include/ActionStack.h @@ -176,6 +176,7 @@ public: DrawAction(GameObserver* observer, int id, Player * _player, int _nbcards); }; +class ATutorialMessage; class LifeAction: public Interruptible { public: @@ -196,6 +197,7 @@ protected: int currentState; int mode; int checked; + ATutorialMessage* currentTutorial; public: @@ -216,7 +218,7 @@ public: int getNextIndex(Interruptible * previous, int type = 0, int state = 0 , int display = -1); void Fizzle(Interruptible * action); Interruptible * getAt(int id); - void cancelInterruptOffer(int cancelMode = 1); + void cancelInterruptOffer(int cancelMode = 1, bool log = true); void endOfInterruption(bool log = true); Interruptible * getLatest(int state); Player * askIfWishesToInterrupt; @@ -241,7 +243,8 @@ public: #if defined (WIN32) || defined (LINUX) || defined (IOS) void Dump(); #endif - + void setCurrentTutorial(ATutorialMessage* message) {currentTutorial = message;}; + ATutorialMessage* getCurrentTutorial() {return currentTutorial;}; }; #endif diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 3fb3898e0..2adb79277 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -781,9 +781,6 @@ public: //JGuiListener Implementation void ButtonPressed(int controllerId, int controlId); - - static ATutorialMessage * Current; - }; diff --git a/projects/mtg/include/DuelLayers.h b/projects/mtg/include/DuelLayers.h index 931df1446..52986e645 100644 --- a/projects/mtg/include/DuelLayers.h +++ b/projects/mtg/include/DuelLayers.h @@ -26,6 +26,7 @@ protected: ActionStack* stack; GuiHandSelf *hand; GuiAvatars * avatars; + GameObserver* observer; public: DuelLayers(); diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index 25b969eb6..91d421fcd 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -13,6 +13,7 @@ #include #include + class MTGGamePhase; class MTGAbility; class MTGCardInstance; @@ -20,7 +21,8 @@ struct CardGui; class Player; class TargetChooser; class Rules; -class TestSuite; +class TestSuiteGame; +class Trash; using namespace std; class GameObserver{ @@ -46,6 +48,7 @@ class GameObserver{ void nextGamePhase(); void shuffleLibrary(Player* p); RandomGenerator randomGenerator; + WResourceManager* mResourceManager; public: int currentPlayerId; @@ -66,6 +69,8 @@ class GameObserver{ time_t startedAt; Rules * mRules; GameType mGameType; + MTGCardInstance* ExtraRules; + Trash* mTrash; TargetChooser * getCurrentTargetChooser(); void stackObjectClicked(Interruptible * action); @@ -80,19 +85,19 @@ class GameObserver{ void userRequestNextGamePhase(bool allowInterrupt = true, bool log = true); void cleanupPhase(); void nextPlayer(); - void setPlayers(vector _players); #ifdef TESTSUITE - void loadTestSuitePlayer(int playerId, TestSuite* testSuite); + void loadTestSuitePlayer(int playerId, TestSuiteGame* testSuite); #endif //TESTSUITE void loadPlayer(int playerId, PlayerType playerType = PLAYER_TYPE_HUMAN, int decknb=0, bool premadeDeck=false); + void loadPlayer(int playerId, Player* player); + Player * currentPlayer; Player * currentActionPlayer; Player * isInterrupting; Player * opponent(); Player * currentlyActing(); - GameObserver(); - GameObserver(vector _players); + GameObserver(WResourceManager* resourceManager = NULL); ~GameObserver(); void gameStateBasedEffects(); void enchantmentStatus(); @@ -125,6 +130,8 @@ class GameObserver{ Player* getPlayer(size_t index) { return players[index];}; bool isStarted() { return (mLayers!=NULL);}; RandomGenerator* getRandomGenerator() { return &randomGenerator; }; + WResourceManager* getResourceManager() { if(this) return mResourceManager;else return 0;}; + CardSelectorBase* getCardSelector() { return mLayers->mCardSelector;}; }; #endif diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 613c1c90b..c5e40899a 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -208,8 +208,6 @@ public: static MTGCardInstance AnyCard; static MTGCardInstance NoCard; - static MTGCardInstance ExtraRules[2]; - bool parseLine(const string& ss); }; diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index c677d2a69..9016f4fe6 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -306,8 +306,8 @@ class MTGMomirRule: public PermanentAbility { private: int genRandomCreatureId(int convertedCost); - static vector pool[20]; - static int initialized; + vector pool[20]; + int initialized; int textAlpha; string text; @@ -335,8 +335,8 @@ class MTGStoneHewerRule: public PermanentAbility { private: int genRandomEquipId(int convertedCost); - static vector pool[20]; - static int initialized; + vector pool[20]; + int initialized; public: MTGAllCards * collection; MTGCardInstance * genEquip(int id); diff --git a/projects/mtg/include/SimpleMenu.h b/projects/mtg/include/SimpleMenu.h index 9593eaa90..c9e1786f7 100644 --- a/projects/mtg/include/SimpleMenu.h +++ b/projects/mtg/include/SimpleMenu.h @@ -28,8 +28,7 @@ private: static JQuadPtr spadeR, spadeL, jewel, side; static JTexture *spadeRTex, *spadeLTex, *jewelTex, *sideTex; - static WFont* titleFont; - static hgeParticleSystem* stars; + hgeParticleSystem* stars; inline void MogrifyJewel(); void drawHorzPole(float x, float y, float width); diff --git a/projects/mtg/include/TestSuiteAI.h b/projects/mtg/include/TestSuiteAI.h index f82567571..ccaf9b3ab 100644 --- a/projects/mtg/include/TestSuiteAI.h +++ b/projects/mtg/include/TestSuiteAI.h @@ -6,6 +6,7 @@ #define MAX_TESTSUITE_ACTIONS 100 #define MAX_TESTUITE_CARDS 100 +#include "Threading.h" #include "AIPlayerBaka.h" class TestSuiteActions @@ -19,6 +20,7 @@ public: }; +class TestSuiteGame; class TestSuite; class TestSuiteAI; class TestSuiteState @@ -30,64 +32,87 @@ public: ~TestSuiteState(); vector players; - void cleanup(TestSuite*); + void cleanup(TestSuiteGame* tsGame); }; -class TestSuitePregame +class TestSuiteGame { + friend class TestSuiteAI; + friend class TestSuite; +protected: + string filename; + int summoningSickness; + bool forceAbility; + GameType gameType; + unsigned int seed; + int aiMaxCalls; + TestSuiteState endState; + TestSuiteState initState; + TestSuiteActions actions; + float timerLimit; + bool isOK; + int currentAction; + GameObserver* observer; + + static boost::mutex mMutex; + virtual void handleResults(bool wasAI, int error); + TestSuite* testsuite; + bool load(); + public: - virtual void performTest() = 0; + ~TestSuiteGame(); + TestSuiteGame(TestSuite* testsuite); + TestSuiteGame(TestSuite* testsuite, string _filename); + void initGame(); + void assertGame(); + MTGPlayerCards * buildDeck(Player* player, int playerId); + GameType getGameType() { return gameType; }; + string getNextAction(); + Interruptible * getActionByMTGId(int mtgid); + static int Log(const char * text); + void setObserver(GameObserver* anObserver) {observer = anObserver; }; }; -class TestSuite +class TestSuite : public TestSuiteGame { private: int currentfile; int nbfiles; string files[1024]; - TestSuiteState endState; - TestSuiteActions actions; - bool forceAbility; - int load(const char * filename); void cleanup(); - -public: - /* but only used by the testsuite classes */ - float timerLimit; - int aiMaxCalls; - int currentAction; - int summoningSickness; - - TestSuiteState initState; - string getNextAction(); - MTGPlayerCards * buildDeck(Player*, int playerId); - Interruptible * getActionByMTGId(GameObserver* observer, int mtgid); - int assertGame(GameObserver*); + vector mWorkerThread; + Rules* mRules; + bool mProcessing; public: int startTime, endTime; - GameType gameType; unsigned int seed; int nbFailed, nbTests, nbAIFailed, nbAITests; TestSuite(const char * filename); void initGame(GameObserver* g); void pregameTests(); int loadNext(); - static int Log(const char * text); - + string getNextFile() { + boost::mutex::scoped_lock lock(mMutex); + if (currentfile >= nbfiles) return ""; + currentfile++; + return files[currentfile - 1]; + }; + static void ThreadProc(void* inParam); + void setRules(Rules* rules) {mRules = rules;}; + void handleResults(bool wasAI, int error); }; -// TODO This should inherit from AIPlayer instead! class TestSuiteAI:public AIPlayerBaka { private: MTGCardInstance * getCard(string action); float timer; - TestSuite * suite; + TestSuiteGame * suite; public: - TestSuiteAI(GameObserver *observer, TestSuite * suite, int playerId); + TestSuiteAI(TestSuiteGame *tsGame, int playerId); virtual int Act(float dt); virtual int displayStack(); bool summoningSickness() {return (suite->summoningSickness == 1); } diff --git a/projects/mtg/include/Trash.h b/projects/mtg/include/Trash.h index 830d5a112..14c781b53 100644 --- a/projects/mtg/include/Trash.h +++ b/projects/mtg/include/Trash.h @@ -4,22 +4,39 @@ #include #include "Pos.h" #include "WEvent.h" +#include "DamagerDamaged.h" + +class CardView; +class AttackerDamaged; +class DamagerDamaged; +typedef DamagerDamaged DefenserDamaged; template void trash(T*); -class Trash -{ -public: - static void cleanup(); -}; template class TrashBin { - std::vector bin; + std::vector bin; void put_out(); int receiveEvent(WEvent* e); template friend void trash(Q*); friend class Trash; }; + +class Trash +{ +private: + TrashBin CardViewTrash; + TrashBin DefenserDamagedTrash; + TrashBin AttackerDamagedTrash; + +public: + Trash(){}; + void cleanup(); + void trash(CardView* garbage); + void trash(DefenserDamaged* garbage); + void trash(AttackerDamaged* garbage); +}; + #endif // _TRASH_H_ diff --git a/projects/mtg/src/AIMomirPlayer.cpp b/projects/mtg/src/AIMomirPlayer.cpp index 8b3d89be9..461c1aa25 100644 --- a/projects/mtg/src/AIMomirPlayer.cpp +++ b/projects/mtg/src/AIMomirPlayer.cpp @@ -6,8 +6,6 @@ #include "AIStats.h" #include "AllAbilities.h" -MTGAbility * AIMomirPlayer::momirAbility = NULL; - AIMomirPlayer::AIMomirPlayer(GameObserver *observer, string file, string fileSmall, string avatarFile, MTGDeck * deck) : AIPlayerBaka(observer, file, fileSmall, avatarFile, deck) { diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index fd27e54b6..78de54ecd 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -17,28 +17,24 @@ const char * const MTG_LAND_TEXTS[] = { "artifact", "forest", "island", "mountain", "swamp", "plains", "other lands" }; -int AIAction::currentId = 0; - AIAction::AIAction(AIPlayer * owner, MTGCardInstance * c, MTGCardInstance * t) : owner(owner), ability(NULL), player(NULL), click(c), target(t) { - id = currentId++; - // useability tweak - assume that the user is probably going to want to see the full res card, // so prefetch it. The idea is that we do it here as we want to start the prefetch before it's time to render, // and waiting for it to actually go into play is too late, as we start drawing the card during the interrupt window. // This is a good intercept point, as the AI has committed to using this card. // if we're not in text mode, always get the thumb - if (CardSelectorSingleton::Instance()->GetDrawMode() != DrawMode::kText) + if (owner->getObserver()->getCardSelector()->GetDrawMode() != DrawMode::kText) { //DebugTrace("Prefetching AI card going into play: " << c->getImageName()); - WResourceManager::Instance()->RetrieveCard(c, RETRIEVE_THUMB); + owner->getObserver()->getResourceManager()->RetrieveCard(c, RETRIEVE_THUMB); // also cache the large image if we're using kNormal mode - if (CardSelectorSingleton::Instance()->GetDrawMode() == DrawMode::kNormal) + if (owner->getObserver()->getCardSelector()->GetDrawMode() == DrawMode::kNormal) { - WResourceManager::Instance()->RetrieveCard(c); + owner->getObserver()->getResourceManager()->RetrieveCard(c); } } } diff --git a/projects/mtg/src/AIStats.cpp b/projects/mtg/src/AIStats.cpp index 28e05dc93..970572a8e 100644 --- a/projects/mtg/src/AIStats.cpp +++ b/projects/mtg/src/AIStats.cpp @@ -196,7 +196,7 @@ void AIStats::Render() x0 = 280; JRenderer::GetInstance()->FillRoundRect(x0, 10, 200, 180, 5, ARGB(50,0,0,0)); - WFont * f = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); + WFont * f = g->getResourceManager()->GetWFont(Fonts::MAIN_FONT); int i = 0; char buffer[512]; list::iterator it; diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 9e1995aac..ed61ee94d 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -48,7 +48,7 @@ const string NextGamePhase::getDisplayName() const void NextGamePhase::Render() { - WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); + WFont * mFont = observer->getResourceManager()->GetWFont(Fonts::MAIN_FONT); mFont->SetBase(0); mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); char buffer[200]; @@ -81,20 +81,20 @@ const string Interruptible::getDisplayName() const float Interruptible::GetVerticalTextOffset() const { - static const float kTextVerticalOffset = (mHeight - WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT)->GetHeight()) / 2; + static const float kTextVerticalOffset = (mHeight - observer->getResourceManager()->GetWFont(Fonts::MAIN_FONT)->GetHeight()) / 2; return kTextVerticalOffset; } void Interruptible::Render(MTGCardInstance * source, JQuad * targetQuad, string alt1, string alt2, string action, bool bigQuad) { - WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); + WFont * mFont = observer->getResourceManager()->GetWFont(Fonts::MAIN_FONT); mFont->SetColor(ARGB(255,255,255,255)); mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); mFont->DrawString(_(action).c_str(), x + 35, y + GetVerticalTextOffset(), JGETEXT_LEFT); JRenderer * renderer = JRenderer::GetInstance(); - JQuadPtr quad = WResourceManager::Instance()->RetrieveCard(source, CACHE_THUMB); + JQuadPtr quad = observer->getResourceManager()->RetrieveCard(source, CACHE_THUMB); if (!quad.get()) quad = CardGui::AlternateThumbQuad(source); if (quad.get()) @@ -111,7 +111,7 @@ void Interruptible::Render(MTGCardInstance * source, JQuad * targetQuad, string if (bigQuad) { Pos pos = Pos(CardGui::BigWidth / 2, CardGui::BigHeight / 2 - 10, 1.0, 0.0, 220); - CardGui::DrawCard(source, pos, CardSelectorSingleton::Instance()->GetDrawMode()); + CardGui::DrawCard(source, pos, observer->getCardSelector()->GetDrawMode()); } if (targetQuad) @@ -409,7 +409,7 @@ int PutInGraveyard::resolve() void PutInGraveyard::Render() { - WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); + WFont * mFont = observer->getResourceManager()->GetWFont(Fonts::MAIN_FONT); mFont->SetBase(0); mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); if (!removeFromGame) @@ -421,7 +421,7 @@ void PutInGraveyard::Render() mFont->DrawString(_("is exiled").c_str(), x + 30, y, JGETEXT_LEFT); } JRenderer * renderer = JRenderer::GetInstance(); - JQuadPtr quad = WResourceManager::Instance()->RetrieveCard(card, CACHE_THUMB); + JQuadPtr quad = observer->getResourceManager()->RetrieveCard(card, CACHE_THUMB); if (quad.get()) { quad->SetColor(ARGB(255,255,255,255)); @@ -457,7 +457,7 @@ int DrawAction::resolve() void DrawAction::Render() { - WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); + WFont * mFont = observer->getResourceManager()->GetWFont(Fonts::MAIN_FONT); mFont->SetBase(0); mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); char buffer[200]; @@ -487,7 +487,7 @@ target->life += amount; void LifeAction::Render() { - WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); + WFont * mFont = observer->getResourceManager()->GetWFont(Fonts::MAIN_FONT); mFont->SetBase(0); mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); char buffer[200]; @@ -574,7 +574,7 @@ int ActionStack::setIsInterrupting(Player * player, bool log) if (!gModRules.game.canInterrupt()) { - cancelInterruptOffer(); + cancelInterruptOffer(1, log); return 0; } @@ -632,7 +632,7 @@ Interruptible * ActionStack::getAt(int id) } ActionStack::ActionStack(GameObserver* game) - : GuiLayer(game) + : GuiLayer(game), currentTutorial(0) { for (int i = 0; i < 2; i++) interruptDecision[i] = 0; @@ -642,11 +642,12 @@ ActionStack::ActionStack(GameObserver* game) mode = ACTIONSTACK_STANDARD; checked = 0; + if(!observer->getResourceManager()) return; for (int i = 0; i < 8; ++i) { std::ostringstream stream; stream << "iconspsp" << i; - pspIcons[i] = WResourceManager::Instance()->RetrieveQuad("iconspsp.png", (float) i * 32, 0, 32, 32, stream.str(), RETRIEVE_MANAGE); + pspIcons[i] = observer->getResourceManager()->RetrieveQuad("iconspsp.png", (float) i * 32, 0, 32, 32, stream.str(), RETRIEVE_MANAGE); pspIcons[i]->SetHotSpot(16, 16); } } @@ -829,7 +830,7 @@ void ActionStack::Update(float dt) { //This is a hack to avoid updating the stack while tuto messages are being shown //Ideally, the tuto messages should be moved to a layer above this one - if (ATutorialMessage::Current) + if (getCurrentTutorial()) return; askIfWishesToInterrupt = NULL; @@ -955,14 +956,15 @@ void ActionStack::Update(float dt) } } -void ActionStack::cancelInterruptOffer(int cancelMode) +void ActionStack::cancelInterruptOffer(int cancelMode, bool log) { int playerId = (observer->isInterrupting == observer->players[1]) ? 1 : 0; interruptDecision[playerId] = cancelMode; askIfWishesToInterrupt = NULL; observer->isInterrupting = NULL; timer = -1; - observer->logAction(playerId, "no"); + if(log) + observer->logAction(playerId, "no"); } void ActionStack::endOfInterruption(bool log) @@ -1101,7 +1103,7 @@ void ActionStack::Render() { //This is a hack to avoid rendering the stack above the tuto messages //Ideally, the tuto messages should be moved to a layer above this one - if (ATutorialMessage::Current) + if (getCurrentTutorial()) return; static const float kSpacer = 8; @@ -1123,7 +1125,7 @@ void ActionStack::Render() height += current->mHeight; } - WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); + WFont * mFont = observer->getResourceManager()->GetWFont(Fonts::MAIN_FONT); mFont->SetBase(0); mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); mFont->SetColor(ARGB(255,255,255,255)); @@ -1201,7 +1203,7 @@ void ActionStack::Render() height += current->mHeight; } - WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); + WFont * mFont = observer->getResourceManager()->GetWFont(Fonts::MAIN_FONT); mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); mFont->SetColor(ARGB(255,255,255,255)); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 3da1a7287..5f67f7a90 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -2241,7 +2241,7 @@ int MayAbility::testDestroy() if(game->currentPlayer == source->controller() && game->isInterrupting == source->controller() && dynamic_cast(AbilityFactory::getCoreAbility(ability))) //if its my turn, and im interrupting myself(why?) then set interrupting to previous interrupter if the ability was a manaability //special case since they don't use the stack. - game->mLayers->stackLayer()->setIsInterrupting(previousInterrupter); + game->mLayers->stackLayer()->setIsInterrupting(previousInterrupter, false); return 1; } @@ -2305,7 +2305,7 @@ void MenuAbility::Update(float dt) { game->mLayers->actionLayer()->setCustomMenuObject(source, must,abilities); previousInterrupter = game->isInterrupting; - game->mLayers->stackLayer()->setIsInterrupting(source->controller()); + game->mLayers->stackLayer()->setIsInterrupting(source->controller(), false); } } @@ -2359,10 +2359,9 @@ int MenuAbility::reactToChoiceClick(Targetable * object,int choice,int control) mClone->resolve(); SAFE_DELETE(mClone); if (source->controller() == game->isInterrupting) - game->mLayers->stackLayer()->cancelInterruptOffer(); + game->mLayers->stackLayer()->cancelInterruptOffer(1, false); this->forceDestroy = 1; removeMenu = true; - game->logAction(source->controller(), "choice " + choice); return reactToTargetClick(object); } @@ -3913,8 +3912,6 @@ AAConnect * AAConnect::clone() const //Tutorial Messaging -ATutorialMessage * ATutorialMessage::Current = NULL; - ATutorialMessage::ATutorialMessage(GameObserver* observer, MTGCardInstance * source, string message, int limit) : MTGAbility(observer, 0, source), IconButtonsController(0, 0), mLimit(limit) { @@ -3926,7 +3923,7 @@ ATutorialMessage::ATutorialMessage(GameObserver* observer, MTGCardInstance * sou for (int i = 0; i < 9; i++) mBg[i] = NULL; - string gfx = WResourceManager::Instance()->graphicsFile(message); + string gfx = game->getResourceManager()->graphicsFile(message); if (fileExists(gfx.c_str())) { mIsImage = true; @@ -3987,10 +3984,10 @@ bool ATutorialMessage::CheckUserInput(JButton key) void ATutorialMessage::Update(float dt) { - if (!Current && !mDontShow) - Current = this; + if (!game->mLayers->stackLayer()->getCurrentTutorial() && !mDontShow) + game->mLayers->stackLayer()->setCurrentTutorial(this); - if (Current != this) + if (game->mLayers->stackLayer()->getCurrentTutorial() != this) return; if (mUserCloseRequest && mY < -SCREEN_HEIGHT) @@ -3998,7 +3995,7 @@ void ATutorialMessage::Update(float dt) if (mDontShow) { - Current = NULL; + game->mLayers->stackLayer()->setCurrentTutorial(0); forceDestroy = 1; return; } @@ -4048,14 +4045,14 @@ void ATutorialMessage::Render() { if (mIsImage) { - mBgTex = WResourceManager::Instance()->RetrieveTexture(mMessage, RETRIEVE_LOCK); + mBgTex = game->getResourceManager()->RetrieveTexture(mMessage, RETRIEVE_LOCK); if (mBgTex) { mBg[0] = NEW JQuad(mBgTex, 0, 0, (float) mBgTex->mWidth, (float) mBgTex->mHeight); mBg[0]->SetHotSpot(mBg[0]->mWidth / 2, mBg[0]->mHeight / 2); //Continue Button - JQuadPtr quad = WResourceManager::Instance()->RetrieveQuad("iconspsp.png", 4 * 32, 0, 32, 32, "iconpsp4", RETRIEVE_MANAGE); + JQuadPtr quad = game->getResourceManager()->RetrieveQuad("iconspsp.png", 4 * 32, 0, 32, 32, "iconpsp4", RETRIEVE_MANAGE); quad->SetHotSpot(16, 16); IconButton * iconButton = NEW IconButton(1, this, quad.get(), 0, mBg[0]->mHeight / 2, 0.7f, Fonts::MAGIC_FONT, _("continue"), 0, 16, true); Add(iconButton); @@ -4063,14 +4060,14 @@ void ATutorialMessage::Render() if (options[Options::SFXVOLUME].number > 0) { - JSample * sample = WResourceManager::Instance()->RetrieveSample("tutorial.wav"); + JSample * sample = game->getResourceManager()->RetrieveSample("tutorial.wav"); if (sample) JSoundSystem::GetInstance()->PlaySample(sample); } } else { - mBgTex = WResourceManager::Instance()->RetrieveTexture("taskboard.png", RETRIEVE_LOCK); + mBgTex = game->getResourceManager()->RetrieveTexture("taskboard.png", RETRIEVE_LOCK); float unitH = static_cast (mBgTex->mHeight / 4); float unitW = static_cast (mBgTex->mWidth / 4); @@ -4090,7 +4087,7 @@ void ATutorialMessage::Render() } //Continue Button - JQuadPtr quad = WResourceManager::Instance()->RetrieveQuad("iconspsp.png", 4 * 32, 0, 32, 32, "iconpsp4", RETRIEVE_MANAGE); + JQuadPtr quad = game->getResourceManager()->RetrieveQuad("iconspsp.png", 4 * 32, 0, 32, 32, "iconpsp4", RETRIEVE_MANAGE); quad->SetHotSpot(16, 16); IconButton * iconButton = NEW IconButton(1, this, quad.get(), SCREEN_WIDTH_F / 2, SCREEN_HEIGHT_F - 60, 0.7f, Fonts::MAGIC_FONT, _("continue"), 0, 16, true); Add(iconButton); @@ -4100,7 +4097,7 @@ void ATutorialMessage::Render() if (options[Options::SFXVOLUME].number > 0) { - JSample * sample = WResourceManager::Instance()->RetrieveSample("chain.wav"); + JSample * sample = game->getResourceManager()->RetrieveSample("chain.wav"); if (sample) JSoundSystem::GetInstance()->PlaySample(sample); } @@ -4126,7 +4123,7 @@ void ATutorialMessage::Render() else { //Setup fonts. - WFont * f2 = WResourceManager::Instance()->GetWFont(Fonts::MAGIC_FONT); + WFont * f2 = game->getResourceManager()->GetWFont(Fonts::MAGIC_FONT); f2->SetColor(ARGB(255, 205, 237, 240)); r->FillRect(0, mY, SCREEN_WIDTH, SCREEN_HEIGHT, ARGB(128,0,0,0)); @@ -4159,8 +4156,8 @@ void ATutorialMessage::Render() float posX = 40, posY = mY + 20; string title = _("Help"); - WFont * f = WResourceManager::Instance()->GetWFont(Fonts::MAGIC_FONT); - WFont * f3 = WResourceManager::Instance()->GetWFont(Fonts::MENU_FONT); //OPTION_FONT + WFont * f = game->getResourceManager()->GetWFont(Fonts::MAGIC_FONT); + WFont * f3 = game->getResourceManager()->GetWFont(Fonts::MENU_FONT); //OPTION_FONT f->SetColor(ARGB(255, 55, 46, 34)); f3->SetColor(ARGB(255, 219, 206, 151)); @@ -4187,7 +4184,7 @@ ATutorialMessage::~ATutorialMessage() { if (mBgTex) { - WResourceManager::Instance()->Release(mBgTex); + game->getResourceManager()->Release(mBgTex); for (int i = 0; i < 9; i++) SAFE_DELETE(mBg[i]); } diff --git a/projects/mtg/src/CardDisplay.cpp b/projects/mtg/src/CardDisplay.cpp index 4377961b7..d444597f9 100644 --- a/projects/mtg/src/CardDisplay.cpp +++ b/projects/mtg/src/CardDisplay.cpp @@ -265,7 +265,7 @@ void CardDisplay::Render() { pos.actY = 150; if (x < (CardGui::BigWidth / 2)) pos.actX = SCREEN_WIDTH - 10 - CardGui::BigWidth / 2; - drawMode = CardSelectorSingleton::Instance()->GetDrawMode(); + drawMode = observer->getCardSelector()->GetDrawMode(); } cardg->DrawCard(pos, drawMode); diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index 07a97ae52..1e030c4dc 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -130,7 +130,7 @@ void CardGui::DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode) void CardGui::Render() { - WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); + WFont * mFont = card->getObserver()->getResourceManager()->GetWFont(Fonts::MAIN_FONT); JRenderer * renderer = JRenderer::GetInstance(); GameObserver * game = card->getObserver(); @@ -140,7 +140,7 @@ void CardGui::Render() tc = game->getCurrentTargetChooser(); bool alternate = true; - JQuadPtr quad = WResourceManager::Instance()->RetrieveCard(card, CACHE_THUMB); + JQuadPtr quad = card->getObserver()->getResourceManager()->RetrieveCard(card, CACHE_THUMB); if (quad.get()) alternate = false; @@ -153,7 +153,7 @@ void CardGui::Render() JQuadPtr shadow; if (actZ > 1) { - shadow = WResourceManager::Instance()->GetQuad("shadow"); + shadow = card->getObserver()->getResourceManager()->GetQuad("shadow"); shadow->SetColor(ARGB(static_cast(actA)/2,255,255,255)); renderer->RenderQuad(shadow.get(), actX + (actZ - 1) * 15, actY + (actZ - 1) * 15, actT, 28 * actZ / 16, 40 * actZ / 16); } @@ -161,7 +161,7 @@ void CardGui::Render() JQuadPtr extracostshadow; if (card->isExtraCostTarget) { - extracostshadow = WResourceManager::Instance()->GetQuad("extracostshadow"); + extracostshadow = card->getObserver()->getResourceManager()->GetQuad("extracostshadow"); extracostshadow->SetColor(ARGB(static_cast(actA)/2,100,0,0)); renderer->RenderQuad(extracostshadow.get(), actX + (actZ - 1) * 15, actY + (actZ - 1) * 15, actT, 28 * actZ / 16, 40 * actZ / 16); } @@ -185,7 +185,7 @@ void CardGui::Render() } if (isActiveConnectedParent) { - JQuadPtr white = WResourceManager::Instance()->GetQuad("white"); + JQuadPtr white = card->getObserver()->getResourceManager()->GetQuad("white"); if(white) { white->SetColor(ARGB(255,230,50,50)); @@ -212,7 +212,7 @@ void CardGui::Render() } if (isActiveConnectedChild) { - JQuadPtr white = WResourceManager::Instance()->GetQuad("white"); + JQuadPtr white = card->getObserver()->getResourceManager()->GetQuad("white"); if(white) { white->SetColor(ARGB(255,0,0,255)); @@ -235,15 +235,15 @@ void CardGui::Render() JQuadPtr icon; if (card->hasSubtype("plains")) - icon = WResourceManager::Instance()->GetQuad("c_white"); + icon = card->getObserver()->getResourceManager()->GetQuad("c_white"); else if (card->hasSubtype("swamp")) - icon = WResourceManager::Instance()->GetQuad("c_black"); + icon = card->getObserver()->getResourceManager()->GetQuad("c_black"); else if (card->hasSubtype("forest")) - icon = WResourceManager::Instance()->GetQuad("c_green"); + icon = card->getObserver()->getResourceManager()->GetQuad("c_green"); else if (card->hasSubtype("mountain")) - icon = WResourceManager::Instance()->GetQuad("c_red"); + icon = card->getObserver()->getResourceManager()->GetQuad("c_red"); else if (card->hasSubtype("island")) - icon = WResourceManager::Instance()->GetQuad("c_blue"); + icon = card->getObserver()->getResourceManager()->GetQuad("c_blue"); if (icon.get()) { @@ -256,7 +256,7 @@ void CardGui::Render() JQuadPtr mor; if(card->isMorphed && !alternate) { - mor = WResourceManager::Instance()->GetQuad("morph"); + mor = card->getObserver()->getResourceManager()->GetQuad("morph"); mor->SetColor(ARGB(255,255,255,255)); renderer->RenderQuad(mor.get(), actX, actY, actT,scale, scale); } @@ -299,7 +299,7 @@ void CardGui::Render() if (tc && !tc->canTarget(card)) { if (!shadow) - shadow = WResourceManager::Instance()->GetQuad("shadow"); + shadow = card->getObserver()->getResourceManager()->GetQuad("shadow"); shadow->SetColor(ARGB(200,255,255,255)); renderer->RenderQuad(shadow.get(), actX, actY, actT, (28 * actZ + 1) / 16, 40 * actZ / 16); } diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index a37eafaa5..450a99847 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -1,7 +1,7 @@ #include "PrecompiledHeader.h" #include "MTGRules.h" -#include "CardSelectorSingleton.h" +#include "CardSelector.h" #include "GuiCombat.h" #include "GuiBackground.h" #include "GuiFrame.h" @@ -15,7 +15,8 @@ void DuelLayers::init(GameObserver* go) { - mCardSelector = CardSelectorSingleton::Create(go, this); + observer = go; + mCardSelector = NEW CardSelector(go, this); //1 Action Layer action = NEW ActionLayer(go); action->Add(NEW MTGGamePhase(go, action->getMaxId())); @@ -65,7 +66,7 @@ void DuelLayers::CheckUserInput(int isAI) JGE::GetInstance()->LeftClickedProcessed(); break; } - if (CardSelectorSingleton::Instance()->CheckUserInput(key)) { + if (mCardSelector->CheckUserInput(key)) { JGE::GetInstance()->LeftClickedProcessed(); break; } @@ -126,10 +127,9 @@ DuelLayers::~DuelLayers() for (size_t i = 0; i < waiters.size(); ++i) delete (waiters[i]); - Trash::cleanup(); + observer->mTrash->cleanup(); - CardSelectorSingleton::Terminate(); - mCardSelector = NULL; + SAFE_DELETE(mCardSelector); } void DuelLayers::Add(GuiLayer * layer) @@ -203,7 +203,7 @@ int DuelLayers::receiveEvent(WEvent * e) if (WEventPhaseChange *event = dynamic_cast(e)) if (Constants::MTG_PHASE_BEFORE_BEGIN == event->to->id) - Trash::cleanup(); + observer->mTrash->cleanup(); return 1; } diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index ac2bbae0b..10c98362c 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -12,6 +12,7 @@ #include "GuiPhaseBar.h" #include "AIPlayerBaka.h" #include "MTGRules.h" +#include "Trash.h" #ifdef TESTSUITE #include "TestSuiteAI.h" #endif @@ -35,6 +36,7 @@ void GameObserver::initialize() connectRule = false; mLoading = false; mLayers = NULL; + mTrash = new Trash(); } void GameObserver::cleanup() @@ -63,7 +65,6 @@ void GameObserver::cleanup() combatStep = BLOCKERS; connectRule = false; actionsList.clear(); - } GameObserver::~GameObserver() @@ -82,31 +83,21 @@ GameObserver::~GameObserver() SAFE_DELETE(players[i]); } players.clear(); + delete[] ExtraRules; + ExtraRules = 0; LOG("==GameObserver Destroyed=="); + SAFE_DELETE(mTrash); } -GameObserver::GameObserver() - : randomGenerator(true) +GameObserver::GameObserver(WResourceManager *resourceManager) + : randomGenerator(true), mResourceManager(resourceManager) + { + ExtraRules = new MTGCardInstance[2](); + initialize(); } -GameObserver::GameObserver(vector _players) - : randomGenerator(true) -{ - initialize(); - setPlayers(_players); -} - -void GameObserver::setPlayers(vector _players) -{ - for (size_t i = 0; i < _players.size(); i++) - { - players.push_back(_players[i]); - players[i]->setObserver(this); - } -} - int GameObserver::getCurrentGamePhase() { return currentGamePhase; @@ -1009,7 +1000,10 @@ int GameObserver::cardClick(MTGCardInstance * card, Targetable * object) } else { backup = card; zone = card->currentZone; - index = zone->getIndex(card); + if(zone) + { + index = zone->getIndex(card); + } } do { @@ -1136,7 +1130,7 @@ int GameObserver::cardClick(MTGCardInstance * card, Targetable * object) if (clickedPlayer) { logAction(clickedPlayer); - } else { + } else if(zone) { logAction(backup, zone, index, toReturn); } @@ -1451,7 +1445,7 @@ bool GameObserver::processActions(bool undo) if (s.find("p1") != string::npos) p = players[0]; - for (int i = 0; i<5; i++) + for (int i = 0; i<1; i++) { // let's fake an update Update(counter); @@ -1500,7 +1494,7 @@ bool GameObserver::processActions(bool undo) size_t nb = actionsList.size(); - for (int i = 0; i<5; i++) + for (int i = 0; i<3; i++) { // let's fake an update Update(counter); @@ -1563,12 +1557,17 @@ void GameObserver::Mulligan(Player* player) } #ifdef TESTSUITE -void GameObserver::loadTestSuitePlayer(int playerId, TestSuite* testSuite) +void GameObserver::loadTestSuitePlayer(int playerId, TestSuiteGame* testSuite) { - players.push_back(new TestSuiteAI(this, testSuite, playerId)); + players.push_back(new TestSuiteAI(testSuite, playerId)); } #endif //TESTSUITE +void GameObserver::loadPlayer(int playerId, Player* player) +{ + players.push_back(player); +} + void GameObserver::loadPlayer(int playerId, PlayerType playerType, int decknb, bool premadeDeck) { if (decknb) diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index c093a61fd..eb3e853c5 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -119,7 +119,7 @@ void GameStateDuel::Start() renderer->EnableVSync(true); OpponentsDeckid = 0; - game = NEW GameObserver(); + game = NEW GameObserver(WResourceManager::Instance()); #ifdef TESTSUITE SAFE_DELETE(testSuite); @@ -200,12 +200,13 @@ void GameStateDuel::loadTestSuitePlayers() if (!testSuite) return; initRand(testSuite->seed); SAFE_DELETE(game); - game = new GameObserver(); + game = new GameObserver(WResourceManager::Instance()); + testSuite->setObserver(game); for (int i = 0; i < 2; i++) { game->loadTestSuitePlayer(i, testSuite); } - mParent->gameType = testSuite->gameType; + mParent->gameType = testSuite->getGameType(); game->startGame(mParent->gameType, mParent->rules); } @@ -294,6 +295,8 @@ void GameStateDuel::Update(float dt) #ifdef TESTSUITE else if (mParent->players[1] == PLAYER_TYPE_TESTSUITE) { + testSuite->setRules(mParent->rules); + if (testSuite && testSuite->loadNext()) { loadTestSuitePlayers(); diff --git a/projects/mtg/src/GuiAvatars.cpp b/projects/mtg/src/GuiAvatars.cpp index 23bdac5f4..ebef50122 100644 --- a/projects/mtg/src/GuiAvatars.cpp +++ b/projects/mtg/src/GuiAvatars.cpp @@ -26,13 +26,13 @@ GuiAvatars::GuiAvatars(GameObserver* observer) : Add(opponentLibrary = NEW GuiLibrary(5 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 5 + GuiGameZone::Height + 5, false, observer->players[1], this)); - CardSelectorSingleton::Instance()->Add(self); - CardSelectorSingleton::Instance()->Add(selfGraveyard); - CardSelectorSingleton::Instance()->Add(selfLibrary); - CardSelectorSingleton::Instance()->Add(opponent); - CardSelectorSingleton::Instance()->Add(opponentGraveyard); - CardSelectorSingleton::Instance()->Add(opponentLibrary); - CardSelectorSingleton::Instance()->Add(opponentHand); + observer->getCardSelector()->Add(self); + observer->getCardSelector()->Add(selfGraveyard); + observer->getCardSelector()->Add(selfLibrary); + observer->getCardSelector()->Add(opponent); + observer->getCardSelector()->Add(opponentGraveyard); + observer->getCardSelector()->Add(opponentLibrary); + observer->getCardSelector()->Add(opponentHand); selfGraveyard->alpha = selfLibrary->alpha = opponentGraveyard->alpha = opponentLibrary->alpha = opponentHand->alpha = 0; } diff --git a/projects/mtg/src/GuiCombat.cpp b/projects/mtg/src/GuiCombat.cpp index 8b0b17c5f..1550253b9 100644 --- a/projects/mtg/src/GuiCombat.cpp +++ b/projects/mtg/src/GuiCombat.cpp @@ -44,17 +44,17 @@ GuiCombat::GuiCombat(GameObserver* go) : GuiLayer(go), active(false), activeAtk(NULL), ok(SCREEN_WIDTH - MARGIN, 210, 1, 0, 255), enemy_avatar(SCREEN_WIDTH - MARGIN, TOP_LINE, 2, 0, 255), cursor_pos(NONE), step(DAMAGE) { - if (NULL == ok_tex) + if (NULL == ok_tex && go->getResourceManager()) { - ok_tex = WResourceManager::Instance()->RetrieveTexture("Ok.png", RETRIEVE_LOCK); + ok_tex = go->getResourceManager()->RetrieveTexture("Ok.png", RETRIEVE_LOCK); } } GuiCombat::~GuiCombat() { - if (ok_tex) + if (ok_tex && observer->getResourceManager()) { - WResourceManager::Instance()->Release(ok_tex); + observer->getResourceManager()->Release(ok_tex); ok_tex = NULL; } @@ -199,7 +199,7 @@ bool GuiCombat::CheckUserInput(JButton key) if (NONE == cursor_pos) return false; DamagerDamaged* oldActive = active; -/* This is untested +/* int x,y; if(JGE::GetInstance()->GetLeftClickCoordinates(x, y)) { @@ -537,7 +537,7 @@ int GuiCombat::receiveEventMinus(WEvent* e) if (activeAtk == *it) activeAtk = NULL; attackers.erase(it); - trash(d); + observer->mTrash->trash(d); return 1; } else @@ -546,7 +546,7 @@ int GuiCombat::receiveEventMinus(WEvent* e) { DefenserDamaged* d = *q; (*it)->blockers.erase(q); - trash(d); + observer->mTrash->trash(d); return 1; } return 0; @@ -560,7 +560,7 @@ int GuiCombat::receiveEventMinus(WEvent* e) { AttackerDamaged* d = *it; attackers.erase(it); - trash(d); + observer->mTrash->trash(d); return 1; } return 0; @@ -574,7 +574,7 @@ int GuiCombat::receiveEventMinus(WEvent* e) { DefenserDamaged* d = *q; (*it)->blockers.erase(q); - trash(d); + observer->mTrash->trash(d); return 1; } return 0; diff --git a/projects/mtg/src/GuiFrame.cpp b/projects/mtg/src/GuiFrame.cpp index a61eecfa6..e4f764fe9 100644 --- a/projects/mtg/src/GuiFrame.cpp +++ b/projects/mtg/src/GuiFrame.cpp @@ -6,26 +6,28 @@ GuiFrame::GuiFrame(GameObserver* observer) : GuiLayer(observer) { - if (WResourceManager::Instance()->GetTexture("wood.png")) - wood = WResourceManager::Instance()->RetrieveQuad("wood.png", 0, 0, SCREEN_WIDTH, 28); - else + if (observer->getResourceManager()) { - GameApp::systemError += "Can't load wood texture : " __FILE__ "\n"; - } - - if (WResourceManager::Instance()->GetTexture("gold.png")) - { - gold1 = WResourceManager::Instance()->RetrieveQuad("gold.png", 0, 0, SCREEN_WIDTH, 6, "gold1"); - gold2 = WResourceManager::Instance()->RetrieveQuad("gold.png", 0, 6, SCREEN_WIDTH, 6, "gold2"); - if (WResourceManager::Instance()->GetTexture("goldglow.png")) - goldGlow = WResourceManager::Instance()->RetrieveQuad("goldglow.png", 1, 1, SCREEN_WIDTH - 2, 18); - if (gold2) + if (observer->getResourceManager()->GetTexture("wood.png")) + wood = observer->getResourceManager()->RetrieveQuad("wood.png", 0, 0, SCREEN_WIDTH, 28); + else { - gold2->SetColor(ARGB(127, 255, 255, 255)); - gold2->SetHFlip(true); + GameApp::systemError += "Can't load wood texture : " __FILE__ "\n"; + } + + if (observer->getResourceManager()->GetTexture("gold.png")) + { + gold1 = observer->getResourceManager()->RetrieveQuad("gold.png", 0, 0, SCREEN_WIDTH, 6, "gold1"); + gold2 = observer->getResourceManager()->RetrieveQuad("gold.png", 0, 6, SCREEN_WIDTH, 6, "gold2"); + if (observer->getResourceManager()->GetTexture("goldglow.png")) + goldGlow = observer->getResourceManager()->RetrieveQuad("goldglow.png", 1, 1, SCREEN_WIDTH - 2, 18); + if (gold2) + { + gold2->SetColor(ARGB(127, 255, 255, 255)); + gold2->SetHFlip(true); + } } } - step = 0.0; } diff --git a/projects/mtg/src/GuiHand.cpp b/projects/mtg/src/GuiHand.cpp index 5129cb43a..037660503 100644 --- a/projects/mtg/src/GuiHand.cpp +++ b/projects/mtg/src/GuiHand.cpp @@ -35,11 +35,14 @@ HandLimitor::HandLimitor(GuiHand* hand) : GuiHand::GuiHand(GameObserver* observer, MTGHand* hand) : GuiLayer(observer), hand(hand) { - back = WResourceManager::Instance()->RetrieveTempQuad("handback.png"); - if (back.get()) - back->SetTextureRect(1, 0, 100, 250); - else - GameApp::systemError = "Error loading hand texture : " __FILE__; + if(observer->getResourceManager()) + { + back = observer->getResourceManager()->RetrieveTempQuad("handback.png"); + if (back.get()) + back->SetTextureRect(1, 0, 100, 250); + else + GameApp::systemError = "Error loading hand texture : " __FILE__; + } } GuiHand::~GuiHand() @@ -175,10 +178,10 @@ bool GuiHandSelf::CheckUserInput(JButton key) { state = (Open == state ? Closed : Open); if (Open == state) - CardSelectorSingleton::Instance()->Push(); - CardSelectorSingleton::Instance()->Limit(Open == state ? limitor : NULL, CardView::handZone); + observer->getCardSelector()->Push(); + observer->getCardSelector()->Limit(Open == state ? limitor : NULL, CardView::handZone); if (Closed == state) - CardSelectorSingleton::Instance()->Pop(); + observer->getCardSelector()->Pop(); if (OptionHandDirection::HORIZONTAL == options[Options::HANDDIRECTION].number) backpos.y = Open == state ? OpenY : ClosedY; else @@ -264,7 +267,7 @@ int GuiHandSelf::receiveEventPlus(WEvent* e) card = NEW CardView(CardView::handZone, ev->card, ClosedRowX, 0); card->t = 6 * M_PI; cards.push_back(card); - CardSelectorSingleton::Instance()->Add(card); + observer->getCardSelector()->Add(card); Repos(); return 1; } @@ -279,10 +282,10 @@ int GuiHandSelf::receiveEventMinus(WEvent* e) if (event->card->previous == (*it)->card) { CardView* cv = *it; - CardSelectorSingleton::Instance()->Remove(cv); + observer->getCardSelector()->Remove(cv); cards.erase(it); Repos(); - trash(cv); + observer->mTrash->trash(cv); return 1; } return 1; @@ -317,7 +320,7 @@ int GuiHandOpponent::receiveEventMinus(WEvent* e) { CardView* cv = *it; cards.erase(it); - trash(cv); + observer->mTrash->trash(cv); return 1; } return 0; diff --git a/projects/mtg/src/GuiPhaseBar.cpp b/projects/mtg/src/GuiPhaseBar.cpp index c9afda40c..3ded79fcc 100644 --- a/projects/mtg/src/GuiPhaseBar.cpp +++ b/projects/mtg/src/GuiPhaseBar.cpp @@ -55,7 +55,7 @@ GuiPhaseBar::GuiPhaseBar(GameObserver* observer) : GameApp::systemError = "Error loading phasebar texture : " __FILE__; zoom = ICONSCALE; - CardSelectorSingleton::Instance()->Add(this); + observer->getCardSelector()->Add(this); } diff --git a/projects/mtg/src/GuiPlay.cpp b/projects/mtg/src/GuiPlay.cpp index 38286dca1..c4dd5f168 100644 --- a/projects/mtg/src/GuiPlay.cpp +++ b/projects/mtg/src/GuiPlay.cpp @@ -356,7 +356,7 @@ int GuiPlay::receiveEventPlus(WEvent * e) // Make sure that the card is repositioned before adding it to the CardSelector, as // the card's position is a cue for certain CardSelector variants as to what zone the card is placed in Replace(); - CardSelectorSingleton::Instance()->Add(card); + observer->getCardSelector()->Add(card); return 1; } } @@ -420,9 +420,9 @@ int GuiPlay::receiveEventMinus(WEvent * e) else if (event->card->attacker) battleField.removeAttacker(event->card); CardView* cv = *it; - CardSelectorSingleton::Instance()->Remove(cv); + observer->getCardSelector()->Remove(cv); cards.erase(it); - trash(cv); + observer->mTrash->trash(cv); Replace(); return 1; } diff --git a/projects/mtg/src/GuiStatic.cpp b/projects/mtg/src/GuiStatic.cpp index f448abc83..6ac04ef60 100644 --- a/projects/mtg/src/GuiStatic.cpp +++ b/projects/mtg/src/GuiStatic.cpp @@ -213,7 +213,7 @@ void GuiGameZone::Update(float dt) if (fabs(c->actX - c->x) < 0.01 && fabs(c->actY - c->y) < 0.01) { cards.erase(it); - trash(c); + zone->owner->getObserver()->mTrash->trash(c); return; } } @@ -275,7 +275,7 @@ int GuiGraveyard::receiveEventMinus(WEvent* e) { CardView* cv = *it; cards.erase(it); - trash(cv); + zone->owner->getObserver()->mTrash->trash(cv); return 1; } return 0; @@ -322,7 +322,7 @@ int GuiOpponentHand::receiveEventMinus(WEvent* e) { CardView* cv = *it; cards.erase(it); - trash(cv); + zone->owner->getObserver()->mTrash->trash(cv); return 1; } return 0; diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 875df8237..0d8087d69 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -19,8 +19,6 @@ SUPPORT_OBJECT_ANALYTICS(MTGCardInstance) MTGCardInstance MTGCardInstance::AnyCard = MTGCardInstance(); MTGCardInstance MTGCardInstance::NoCard = MTGCardInstance(); -MTGCardInstance MTGCardInstance::ExtraRules[] = { MTGCardInstance(), MTGCardInstance() }; - MTGCardInstance::MTGCardInstance() : CardPrimitive(), MTGCard(), Damageable(0, 0), view(NULL) { diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index b7d99c156..7192adef1 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -247,15 +247,16 @@ void MTGPlayerCards::drawFromLibrary() // so prefetch it. // if we're not in text mode, always get the thumb - if (CardSelectorSingleton::Instance()->GetDrawMode() != DrawMode::kText) + if (library->owner->getObserver()->getCardSelector()->GetDrawMode() != DrawMode::kText + && library->owner->getObserver()->getResourceManager()) { DebugTrace("Prefetching AI card going into play: " << toMove->getImageName()); - WResourceManager::Instance()->RetrieveCard(toMove, RETRIEVE_THUMB); + library->owner->getObserver()->getResourceManager()->RetrieveCard(toMove, RETRIEVE_THUMB); // also cache the large image if we're using kNormal mode - if (CardSelectorSingleton::Instance()->GetDrawMode() == DrawMode::kNormal) + if (library->owner->getObserver()->getCardSelector()->GetDrawMode() == DrawMode::kNormal) { - WResourceManager::Instance()->RetrieveCard(toMove); + library->owner->getObserver()->getResourceManager()->RetrieveCard(toMove); } } @@ -339,9 +340,9 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone { if (to == g->players[0]->game->graveyard || to == g->players[1]->game->graveyard) { - if (card->isCreature()) + if (card->isCreature() && g->getResourceManager()) { - JSample * sample = WResourceManager::Instance()->RetrieveSample("graveyard.wav"); + JSample * sample = g->getResourceManager()->RetrieveSample("graveyard.wav"); if (sample) JSoundSystem::GetInstance()->PlaySample(sample); } diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 7ef3ae98b..63514424e 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -1197,11 +1197,11 @@ int MTGAttackRule::reactToClick(MTGCardInstance * card) //Graphically select the next card that can attack if (!card->isAttacker()) { - CardSelectorSingleton::Instance()->PushLimitor(); - CardSelectorSingleton::Instance()->Limit(this, CardView::playZone); - CardSelectorSingleton::Instance()->CheckUserInput(JGE_BTN_RIGHT); - CardSelectorSingleton::Instance()->Limit(NULL, CardView::playZone); - CardSelectorSingleton::Instance()->PopLimitor(); + game->getCardSelector()->PushLimitor(); + game->getCardSelector()->Limit(this, CardView::playZone); + game->getCardSelector()->CheckUserInput(JGE_BTN_RIGHT); + game->getCardSelector()->Limit(NULL, CardView::playZone); + game->getCardSelector()->PopLimitor(); } card->toggleAttacker(); return 1; @@ -1416,11 +1416,8 @@ MTGBlockRule * MTGBlockRule::clone() const // * Momir // -int MTGMomirRule::initialized = 0; -vector MTGMomirRule::pool[20]; - MTGMomirRule::MTGMomirRule(GameObserver* observer, int _id, MTGAllCards * _collection) : -PermanentAbility(observer, _id) + PermanentAbility(observer, _id), initialized(false) { collection = _collection; if (!initialized) @@ -1565,11 +1562,8 @@ MTGMomirRule * MTGMomirRule::clone() const //less than or equal to the creature. //note this can kill your creature if the equipment contains negitive toughness -int MTGStoneHewerRule::initialized = 0; -vector MTGStoneHewerRule::pool[20]; - MTGStoneHewerRule::MTGStoneHewerRule(GameObserver* observer, int _id, MTGAllCards * _collection) : -PermanentAbility(observer, _id) + PermanentAbility(observer, _id), initialized(false) { collection = _collection; if (!initialized) diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index c611a1187..53edd2ada 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -60,21 +60,25 @@ Player::~Player() { SAFE_DELETE(manaPool); SAFE_DELETE(game); - WResourceManager::Instance()->Release(mAvatarTex); + if(mAvatarTex && observer->getResourceManager()) + observer->getResourceManager()->Release(mAvatarTex); mAvatarTex = NULL; SAFE_DELETE(mDeck); } bool Player::loadAvatar(string file, string resName) { + WResourceManager * rm = observer->getResourceManager(); + if(!rm) return false; + if (mAvatarTex) { - WResourceManager::Instance()->Release(mAvatarTex); + rm->Release(mAvatarTex); mAvatarTex = NULL; } - mAvatarTex = WResourceManager::Instance()->RetrieveTexture(file, RETRIEVE_LOCK, TEXTURE_SUB_AVATAR); + mAvatarTex = rm->RetrieveTexture(file, RETRIEVE_LOCK, TEXTURE_SUB_AVATAR); if (mAvatarTex) { - mAvatar = WResourceManager::Instance()->RetrieveQuad(file, 0, 0, 35, 50, resName, RETRIEVE_NORMAL, TEXTURE_SUB_AVATAR); + mAvatar = rm->RetrieveQuad(file, 0, 0, 35, 50, resName, RETRIEVE_NORMAL, TEXTURE_SUB_AVATAR); return true; } diff --git a/projects/mtg/src/Rules.cpp b/projects/mtg/src/Rules.cpp index 5d50ef047..0f458a77c 100644 --- a/projects/mtg/src/Rules.cpp +++ b/projects/mtg/src/Rules.cpp @@ -144,8 +144,8 @@ void Rules::addExtraRules(GameObserver* g) { Player * p = g->players[i]; //Trick so that the abilities don't die; - MTGCardInstance::ExtraRules[i].currentZone = p->game->inPlay; - MTGCardInstance::ExtraRules[i].lastController = p; + g->ExtraRules[i].currentZone = p->game->inPlay; + g->ExtraRules[i].lastController = p; for (size_t j = 0; j < initState.playerData[i].extraRules.size(); ++j) { AbilityFactory af(g); @@ -153,7 +153,7 @@ void Rules::addExtraRules(GameObserver* g) int handsize = 7; int difficultyRating = 0; int Optimizedhandcheat = options[Options::OPTIMIZE_HAND].number; - MTGAbility * a = af.parseMagicLine(initState.playerData[i].extraRules[j], id++, NULL, &MTGCardInstance::ExtraRules[i]); + MTGAbility * a = af.parseMagicLine(initState.playerData[i].extraRules[j], id++, NULL, &(g->ExtraRules[i])); if (p->playMode != Player::MODE_TEST_SUITE && g->mRules->gamemode != GAME_TYPE_MOMIR && g->mRules->gamemode != GAME_TYPE_RANDOM1 && g->mRules->gamemode != GAME_TYPE_RANDOM2 && g->mRules->gamemode != GAME_TYPE_STORY && @@ -214,7 +214,7 @@ void Rules::addExtraRules(GameObserver* g) for (size_t j = 0; j < extraRules.size(); ++j) { AbilityFactory af(g); - MTGAbility * a = af.parseMagicLine(extraRules[j], id++, NULL, &MTGCardInstance::ExtraRules[0]); + MTGAbility * a = af.parseMagicLine(extraRules[j], id++, NULL, &(g->ExtraRules[0])); if (a) { if (a->oneShot) diff --git a/projects/mtg/src/SimpleMenu.cpp b/projects/mtg/src/SimpleMenu.cpp index 536de4da0..3d9cddb77 100644 --- a/projects/mtg/src/SimpleMenu.cpp +++ b/projects/mtg/src/SimpleMenu.cpp @@ -27,8 +27,6 @@ JTexture* SimpleMenu::spadeRTex = NULL; JTexture* SimpleMenu::spadeLTex = NULL; JTexture* SimpleMenu::jewelTex = NULL; JTexture* SimpleMenu::sideTex = NULL; -WFont* SimpleMenu::titleFont = NULL; -hgeParticleSystem* SimpleMenu::stars = NULL; SimpleMenu::SimpleMenu(int id, JGuiListener* listener, int fontId, float x, float y, const char * _title, int _maxItems, bool centerHorizontal, bool centerVertical) : JGuiController(id, listener), fontId(fontId), mCenterHorizontal(centerHorizontal), mCenterVertical(centerVertical) @@ -58,14 +56,14 @@ SimpleMenu::SimpleMenu(int id, JGuiListener* listener, int fontId, float x, floa jewel.reset(NEW JQuad(jewelTex, 1, 1, 3, 3)); side = WResourceManager::Instance()->RetrieveQuad("menuside.png", 1, 1, 1, kPoleWidth, "menuside", RETRIEVE_MANAGE); - if (NULL == stars) - stars = NEW hgeParticleSystem(WResourceManager::Instance()->RetrievePSI("stars.psi", WResourceManager::Instance()->GetQuad("stars").get())); + stars = NEW hgeParticleSystem(WResourceManager::Instance()->RetrievePSI("stars.psi", WResourceManager::Instance()->GetQuad("stars").get())); stars->FireAt(mX, mY); } SimpleMenu::~SimpleMenu() { + SAFE_DELETE(stars); } void SimpleMenu::drawHorzPole(float x, float y, float width) @@ -247,6 +245,5 @@ void SimpleMenu::Close() void SimpleMenu::destroy() { SimpleMenu::jewel.reset(); - SAFE_DELETE(SimpleMenu::stars); SAFE_DELETE(SimpleMenu::jewelTex); } diff --git a/projects/mtg/src/StoryFlow.cpp b/projects/mtg/src/StoryFlow.cpp index b96ee9ef4..3194a7c74 100644 --- a/projects/mtg/src/StoryFlow.cpp +++ b/projects/mtg/src/StoryFlow.cpp @@ -303,27 +303,24 @@ StoryChoice::StoryChoice(string pageId, string text, int JGOid, float mX, float //Actually loads a duel void StoryDuel::init() { - vector players; + game = new GameObserver(); char folder[255], deckFile[255], deckFileSmall[255]; sprintf(folder, CAMPAIGNS_FOLDER"%s/%s", mParent->folder.c_str(), pageId.c_str()); sprintf(deckFile, "%s/deck.txt", folder); sprintf(deckFileSmall, "campaign_%s", mParent->folder.c_str()); - players.push_back(NEW HumanPlayer(0, deckFile, deckFileSmall, true)); - + game->loadPlayer(0, NEW HumanPlayer(game, deckFile, deckFileSmall, true)); sprintf(deckFile, "%s/opponent_deck.txt", folder); sprintf(deckFileSmall, "campaign_ennemy_%s_%s", mParent->folder.c_str(), pageId.c_str()); - players.push_back(NEW AIPlayerBaka(0, deckFile, deckFileSmall, "baka.jpg")); + game->loadPlayer(1, NEW AIPlayerBaka(game, deckFile, deckFileSmall, "baka.jpg")); string rulesFile = folder; rulesFile.append("/rules.txt"); rules = NEW Rules(bg); rules->load(rulesFile); - game = new GameObserver(players); - rules->gamemode = GAME_TYPE_STORY; game->startGame(GAME_TYPE_STORY, rules); } diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index c60b7abb4..bf3a059c3 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -15,14 +15,14 @@ using std::string; // NULL is sent in place of a MTGDeck since there is no way to create a MTGDeck without a proper deck file. // TestSuiteAI will be responsible for managing its own deck state. -TestSuiteAI::TestSuiteAI(GameObserver *observer, TestSuite * _suite, int playerId) : - AIPlayerBaka(observer, "testsuite", "testsuite", "baka.jpg", NULL) +TestSuiteAI::TestSuiteAI(TestSuiteGame *tsGame, int playerId) : + AIPlayerBaka(tsGame->observer, "testsuite", "testsuite", "baka.jpg", NULL) { SAFE_DELETE(game); //game might have been set in the parent with default values - game = _suite->buildDeck(this, playerId); + game = tsGame->buildDeck(this, playerId); game->setOwner(this); - suite = _suite; + suite = tsGame; timer = 0; playMode = MODE_TEST_SUITE; this->deckName = "Test Suite AI"; @@ -55,7 +55,7 @@ MTGCardInstance * TestSuiteAI::getCard(string action) return NULL; } -Interruptible * TestSuite::getActionByMTGId(GameObserver* observer, int mtgid) +Interruptible * TestSuiteGame::getActionByMTGId(int mtgid) { ActionStack * as = observer->mLayers->stackLayer(); Interruptible * action = NULL; @@ -121,7 +121,7 @@ int TestSuiteAI::Act(float dt) if (action == "") { //end of game - suite->assertGame(observer); + suite->assertGame(); observer->gameOver = observer->players[0]; DebugTrace("================================ END OF TEST =======================\n"); return 1; @@ -221,7 +221,7 @@ int TestSuiteAI::Act(float dt) if (mtgid) { DebugTrace("TESTSUITE CARD ID:" << mtgid); - toInterrupt = suite->getActionByMTGId(observer, mtgid); + toInterrupt = suite->getActionByMTGId(mtgid); } if (toInterrupt) @@ -277,7 +277,7 @@ void TestSuiteState::parsePlayerState(int playerId, string s) } -string TestSuite::getNextAction() +string TestSuiteGame::getNextAction() { currentAction++; if (actions.nbitems && currentAction <= actions.nbitems) @@ -287,40 +287,15 @@ string TestSuite::getNextAction() return ""; } -MTGPlayerCards * TestSuite::buildDeck(Player* player, int playerId) +void TestSuiteGame::handleResults(bool wasAI, int error) { - int list[100]; - int nbcards = 0; - MTGPlayerCards * deck = NULL; + testsuite->handleResults(wasAI, error); +}; - if(initState.players.size() > (size_t)playerId) - { - MTGGameZone * loadedPlayerZones[] = { initState.players[playerId]->game->graveyard, - initState.players[playerId]->game->library, - initState.players[playerId]->game->hand, - initState.players[playerId]->game->inPlay }; - - for (int j = 0; j < 4; j++) - { - for (size_t k = 0; k < loadedPlayerZones[j]->cards.size(); k++) - { - int cardid = loadedPlayerZones[j]->cards[k]->getId(); - list[nbcards] = cardid; - nbcards++; - } - } - deck = NEW MTGPlayerCards(player, list, nbcards); - } - else - { - deck = NEW MTGPlayerCards(); - } - - return deck; -} void TestSuite::initGame(GameObserver* g) { + observer = g; //The first test runs slowly, the other ones run faster. //This way a human can see what happens when testing a specific file, // or go faster when it comes to the whole test suite. @@ -334,64 +309,10 @@ void TestSuite::initGame(GameObserver* g) timerLimit = 3; } - DebugTrace("TESTSUITE Init Game"); - g->phaseRing->goToPhase(initState.phase, g->players[0]); - g->currentGamePhase = initState.phase; - for (int i = 0; i < 2; i++) - { - AIPlayerBaka * p = (AIPlayerBaka *) (g->players[i]); - p->forceBestAbilityUse = forceAbility; - p->life = initState.players[i]->life; - p->poisonCount = initState.players[i]->poisonCount; - stringstream stream; - stream << initState.players[i]->getRandomGenerator()->saveLoadedRandValues(stream); - p->getRandomGenerator()->loadRandValues(stream.str()); - MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay }; - MTGGameZone * loadedPlayerZones[] = { initState.players[i]->game->graveyard, - initState.players[i]->game->library, - initState.players[i]->game->hand, - initState.players[i]->game->inPlay }; - for (int j = 0; j < 4; j++) - { - MTGGameZone * zone = playerZones[j]; - for (size_t k = 0; k < loadedPlayerZones[j]->cards.size(); k++) - { - MTGCardInstance * card = Rules::getCardByMTGId(g, loadedPlayerZones[j]->cards[k]->getId()); - if (card && zone != p->game->library) - { - if (zone == p->game->inPlay) - { - MTGCardInstance * copy = p->game->putInZone(card, p->game->library, p->game->stack); - Spell * spell = NEW Spell(g, copy); - spell->resolve(); - if (!summoningSickness && (size_t)p->game->inPlay->nb_cards > k) p->game->inPlay->cards[k]->summoningSickness = 0; - delete spell; - } - else - { - if (!p->game->library->hasCard(card)) - { - LOG ("TESTUITE ERROR, CARD NOT FOUND IN LIBRARY\n"); - } - p->game->putInZone(card, p->game->library, zone); - } - } - else - { - if (!card) - { - LOG ("TESTUITE ERROR, card is NULL\n"); - } - } - } - zone->cardsSeenThisTurn.clear(); //don't consider those cards as having moved in this area during this turn - } - p->game->stack->cardsSeenThisTurn.clear(); //don't consider those cards as having moved in this area during this turn - - } - DebugTrace("TESTUITE Init Game Done !"); + TestSuiteGame::initGame(); } -int TestSuite::Log(const char * text) + +int TestSuiteGame::Log(const char * text) { ofstream file; if (JFileSystem::GetInstance()->openForWrite(file, "test/results.html", ios_base::app)) @@ -405,27 +326,29 @@ int TestSuite::Log(const char * text) return 1; } -int TestSuite::assertGame(GameObserver* g) + +void TestSuiteGame::assertGame() { + mMutex.lock(); //compare the game state with the results char result[4096]; - sprintf(result, "

%s

", files[currentfile - 1].c_str()); + sprintf(result, "

%s

", filename.c_str()); Log(result); int error = 0; bool wasAI = false; - if (g->currentGamePhase != endState.phase) + if (observer->currentGamePhase != endState.phase) { sprintf(result, "==phase problem. Expected [ %s ](%i), got [ %s ](%i)==
", Constants::MTGPhaseNames[endState.phase],endState.phase, - Constants::MTGPhaseNames[g->currentGamePhase], g->currentGamePhase); + Constants::MTGPhaseNames[observer->currentGamePhase], observer->currentGamePhase); Log(result); error++; } for (int i = 0; i < 2; i++) { - TestSuiteAI * p = (TestSuiteAI *) (g->players[i]); + TestSuiteAI * p = (TestSuiteAI *) (observer->players[i]); if (p->playMode == Player::MODE_AI) wasAI = true; if (p->life != endState.players[i]->life) @@ -484,7 +407,7 @@ int TestSuite::assertGame(GameObserver* g) MTGCardInstance* cardToCheck = (kcards.size())?endstateZones[j]->cards[k]:0; if(cardToCheck) { // Can be NULL if used "*" in the testcase. - MTGCardInstance* card = Rules::getCardByMTGId(g, cardToCheck->getId()); + MTGCardInstance* card = Rules::getCardByMTGId(observer, cardToCheck->getId()); if (card != 0 && !zone->hasCard(card)) { sprintf(result, "==Card ID not the same. Didn't find %i
", card->getId()); @@ -495,13 +418,23 @@ int TestSuite::assertGame(GameObserver* g) } } } + handleResults(wasAI, error); + + if(!error) + Log("==Test Succesful !=="); + else + Log("==Test Failed !=="); + mMutex.unlock(); +} + +void TestSuite::handleResults(bool wasAI, int error) +{ if (wasAI) { nbAITests++; if (error) { nbAIFailed++; - return 0; } } else @@ -510,14 +443,13 @@ int TestSuite::assertGame(GameObserver* g) if (error) { nbFailed++; - return 0; } } - Log("==Test Succesful !=="); - return 1; } + TestSuite::TestSuite(const char * filename) + : TestSuiteGame(this), mRules(0), mProcessing(false) { timerLimit = 0; @@ -572,26 +504,46 @@ TestSuite::TestSuite(const char * filename) file2.close(); } + SAFE_DELETE(observer); } int TestSuite::loadNext() { + endTime = JGEGetTime(); summoningSickness = 0; seed = 0; aiMaxCalls = -1; if (!nbfiles) return 0; - if (currentfile >= nbfiles) return 0; - currentfile++; - string currFilename = files[currentfile - 1]; - if (currFilename == "+pregametests") + filename = getNextFile(); + if (filename == "") { + // we let GameStateDuel delete the latest gameObserver. + mProcessing = false; + observer = 0; + return 0; + } + + if (filename == "+pregametests") { pregameTests(); return loadNext(); } - if (!load(currFilename.c_str())) + if(!mProcessing) + { // "I don't like to wait" mode + mProcessing = true; + mWorkerThread.clear(); + size_t thread_count = 1; +#ifdef QT_CONFIG + thread_count = QThread::idealThreadCount(); +#endif + for(size_t i = 0; i < (thread_count-1); i++) + mWorkerThread.push_back(boost::thread(ThreadProc, this)); + } + + cleanup(); + if (!load()) return loadNext(); else cout << "Starting test : " << files[currentfile - 1] << endl; @@ -603,8 +555,7 @@ void TestSuiteActions::cleanup() nbitems = 0; } - -void TestSuiteState::cleanup(TestSuite* suite) +void TestSuiteState::cleanup(TestSuiteGame* tsGame) { for (size_t i = 0; i < players.size(); i++) { @@ -612,36 +563,34 @@ void TestSuiteState::cleanup(TestSuite* suite) } players.clear(); - players.push_back(new TestSuiteAI(0, suite, 0)); - players.push_back(new TestSuiteAI(0, suite, 1)); + players.push_back(new TestSuiteAI(tsGame, 0)); + players.push_back(new TestSuiteAI(tsGame, 1)); } void TestSuite::cleanup() { currentAction = 0; + observer = 0; initState.cleanup(this); endState.cleanup(this); actions.cleanup(); } -int TestSuite::load(const char * _filename) + +bool TestSuiteGame::load() { summoningSickness = 0; forceAbility = false; gameType = GAME_TYPE_CLASSIC; - char filename[4096]; - sprintf(filename, "test/%s", _filename); - + std::string s; int state = -1; std::string contents; - if (JFileSystem::GetInstance()->readIntoString(filename, contents)) + if (JFileSystem::GetInstance()->readIntoString("test/"+filename, contents)) { std::stringstream stream(contents); - - cleanup(); while (std::getline(stream, s)) { if (!s.size()) continue; @@ -754,9 +703,9 @@ int TestSuite::load(const char * _filename) } else { - return 0; + return false; } - return 1; + return true; } void TestSuite::pregameTests() @@ -773,4 +722,155 @@ void TestSuite::pregameTests() if (!sb.unitTest()) nbFailed++; } } + +void TestSuite::ThreadProc(void* inParam) +{ + LOG("Entering TestSuite::ThreadProc"); + TestSuite* instance = reinterpret_cast(inParam); + if (instance) + { + string filename; + float counter = 1.0f; +// while(instance->mProcessing) + { + while((filename = instance->getNextFile()) != "") + { + TestSuiteGame theGame(instance, filename); + if(theGame.isOK) + { + theGame.observer->loadTestSuitePlayer(0, &theGame); + theGame.observer->loadTestSuitePlayer(1, &theGame); + + theGame.observer->startGame(theGame.gameType, instance->mRules); + theGame.initGame(); + + while(!theGame.observer->gameOver) + theGame.observer->Update(counter++); + } + } + + boost::this_thread::sleep(100); + } + } + LOG("Leaving TestSuite::ThreadProc"); +} + +boost::mutex TestSuiteGame::mMutex; + +TestSuiteGame::~TestSuiteGame() +{ + SAFE_DELETE(observer); +} + +TestSuiteGame::TestSuiteGame(TestSuite* testsuite) + : summoningSickness(0), forceAbility(false), gameType(GAME_TYPE_CLASSIC), timerLimit(0), + currentAction(0), observer(0), testsuite(testsuite) +{ +} + +TestSuiteGame::TestSuiteGame(TestSuite* testsuite, string _filename) + : summoningSickness(0), forceAbility(false), gameType(GAME_TYPE_CLASSIC), timerLimit(3), + currentAction(0), observer(0), testsuite(testsuite) +{ + filename = _filename; + observer = new GameObserver(); + + initState.cleanup(this); + endState.cleanup(this); + + isOK = load(); +} + +void TestSuiteGame::initGame() +{ + DebugTrace("TESTSUITE Init Game"); + observer->phaseRing->goToPhase(initState.phase, observer->players[0]); + observer->currentGamePhase = initState.phase; + for (int i = 0; i < 2; i++) + { + AIPlayerBaka * p = (AIPlayerBaka *) (observer->players[i]); + p->forceBestAbilityUse = forceAbility; + p->life = initState.players[i]->life; + p->poisonCount = initState.players[i]->poisonCount; + stringstream stream; + stream << initState.players[i]->getRandomGenerator()->saveLoadedRandValues(stream); + p->getRandomGenerator()->loadRandValues(stream.str()); + MTGGameZone * playerZones[] = { p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay }; + MTGGameZone * loadedPlayerZones[] = { initState.players[i]->game->graveyard, + initState.players[i]->game->library, + initState.players[i]->game->hand, + initState.players[i]->game->inPlay }; + for (int j = 0; j < 4; j++) + { + MTGGameZone * zone = playerZones[j]; + for (size_t k = 0; k < loadedPlayerZones[j]->cards.size(); k++) + { + MTGCardInstance * card = Rules::getCardByMTGId(observer, loadedPlayerZones[j]->cards[k]->getId()); + if (card && zone != p->game->library) + { + if (zone == p->game->inPlay) + { + MTGCardInstance * copy = p->game->putInZone(card, p->game->library, p->game->stack); + Spell * spell = NEW Spell(observer, copy); + spell->resolve(); + if (!summoningSickness && (size_t)p->game->inPlay->nb_cards > k) p->game->inPlay->cards[k]->summoningSickness = 0; + delete spell; + } + else + { + if (!p->game->library->hasCard(card)) + { + LOG ("TESTUITE ERROR, CARD NOT FOUND IN LIBRARY\n"); + } + p->game->putInZone(card, p->game->library, zone); + } + } + else + { + if (!card) + { + LOG ("TESTUITE ERROR, card is NULL\n"); + } + } + } + zone->cardsSeenThisTurn.clear(); //don't consider those cards as having moved in this area during this turn + } + p->game->stack->cardsSeenThisTurn.clear(); //don't consider those cards as having moved in this area during this turn + + } + DebugTrace("TESTUITE Init Game Done !"); +} + +MTGPlayerCards * TestSuiteGame::buildDeck(Player* player, int playerId) +{ + int list[100]; + int nbcards = 0; + MTGPlayerCards * deck = NULL; + + if(initState.players.size() > (size_t)playerId) + { + MTGGameZone * loadedPlayerZones[] = { initState.players[playerId]->game->graveyard, + initState.players[playerId]->game->library, + initState.players[playerId]->game->hand, + initState.players[playerId]->game->inPlay }; + + for (int j = 0; j < 4; j++) + { + for (size_t k = 0; k < loadedPlayerZones[j]->cards.size(); k++) + { + int cardid = loadedPlayerZones[j]->cards[k]->getId(); + list[nbcards] = cardid; + nbcards++; + } + } + deck = NEW MTGPlayerCards(player, list, nbcards); + } + else + { + deck = NEW MTGPlayerCards(); + } + + return deck; +} + #endif diff --git a/projects/mtg/src/Trash.cpp b/projects/mtg/src/Trash.cpp index 515c2e3b2..c32095833 100644 --- a/projects/mtg/src/Trash.cpp +++ b/projects/mtg/src/Trash.cpp @@ -9,15 +9,11 @@ template void TrashBin::put_out() { - for (typename std::vector::iterator it = bin.begin(); it != bin.end(); ++it) + for (typename std::vector::iterator it = bin.begin(); it != bin.end(); ++it) SAFE_DELETE(*it); bin.clear(); } -static TrashBin CardViewTrash; -static TrashBin DefenserDamagedTrash; -static TrashBin AttackerDamagedTrash; - void Trash::cleanup() { CardViewTrash.put_out(); @@ -25,15 +21,15 @@ void Trash::cleanup() AttackerDamagedTrash.put_out(); } -template<> void trash(CardView* garbage) +void Trash::trash(CardView* garbage) { CardViewTrash.bin.push_back(garbage); } -template<> void trash(DefenserDamaged* garbage) +void Trash::trash(DefenserDamaged* garbage) { DefenserDamagedTrash.bin.push_back(garbage); } -template<> void trash(AttackerDamaged* garbage) +void Trash::trash(AttackerDamaged* garbage) { AttackerDamagedTrash.bin.push_back(garbage); }