diff --git a/JGE/src/main.cpp b/JGE/src/main.cpp index e75266b47..bfa810582 100644 --- a/JGE/src/main.cpp +++ b/JGE/src/main.cpp @@ -28,7 +28,7 @@ #ifdef DEVHOOK PSP_MODULE_INFO(JGEApp_Title, 0, 1, 1); - PSP_MAIN_THREAD_ATTR(0); + PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); PSP_HEAP_SIZE_KB(-256); #else diff --git a/projects/mtg/include/ActionLayer.h b/projects/mtg/include/ActionLayer.h index 7cfdb97dc..4ffbf1dc5 100644 --- a/projects/mtg/include/ActionLayer.h +++ b/projects/mtg/include/ActionLayer.h @@ -26,7 +26,7 @@ class ActionLayer: public GuiLayer, public JGuiListener{ virtual void Update(float dt); int unstoppableRenderInProgress(); bool CheckUserInput(u32 key); - ActionLayer(){ menuObject = NULL; abilitiesMenu = NULL; stuffHappened = 0;}; + ActionLayer(); ~ActionLayer(); int cancelCurrentAction(); ActionElement * isWaitingForAnswer(); @@ -42,9 +42,12 @@ class ActionLayer: public GuiLayer, public JGuiListener{ void ButtonPressed(int controllerid, int controlid); void doReactTo(int menuIndex); TargetChooser * getCurrentTargetChooser(); + void setCurrentWaitingAction(ActionElement * ae); MTGAbility * getAbility(int type); int moveToGarbage(ActionElement * e); int cleanGarbage(); +protected: + ActionElement * currentWaitingAction; }; diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 23a98b05c..90d8764e7 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -579,11 +579,11 @@ public: while (s.size()){ unsigned int found = s.find(" "); if (found != string::npos){ - int id = Subtypes::subtypesList->Add(s.substr(0,found)); + int id = Subtypes::subtypesList->find(s.substr(0,found)); types.push_back(id); s = s.substr(found+1); }else{ - int id = Subtypes::subtypesList->Add(s); + int id = Subtypes::subtypesList->find(s); types.push_back(id); s = ""; } @@ -1502,7 +1502,7 @@ class AConvertLandToCreatures:public ListMaintainerAbility{ int type; int power, toughness; AConvertLandToCreatures(int _id, MTGCardInstance * _source, const char * _type, int _power = 1, int _toughness = 1):ListMaintainerAbility(_id, _source),power(_power),toughness(_toughness){ - type = Subtypes::subtypesList->Add(_type); + type = Subtypes::subtypesList->find(_type); } @@ -2054,11 +2054,11 @@ public: while (s.size()){ unsigned int found = s.find(" "); if (found != string::npos){ - int id = Subtypes::subtypesList->Add(s.substr(0,found)); + int id = Subtypes::subtypesList->find(s.substr(0,found)); types.push_back(id); s = s.substr(found+1); }else{ - int id = Subtypes::subtypesList->Add(s); + int id = Subtypes::subtypesList->find(s); types.push_back(id); s = ""; } @@ -2243,7 +2243,7 @@ class AAnkhOfMishra: public ListMaintainerAbility{ } int canBeInList(MTGCardInstance * card){ - if (card->hasType("land") && game->isInPlay(card)) return 1; + if (card->hasType(Subtypes::TYPE_LAND) && game->isInPlay(card)) return 1; return 0; } @@ -2541,7 +2541,7 @@ class ADingusEgg: public ListMaintainerAbility{ } int canBeInList(MTGCardInstance * card){ - if (card->hasType("land") && game->isInPlay(card)) return 1; + if (card->hasType(Subtypes::TYPE_LAND) && game->isInPlay(card)) return 1; return 0; } @@ -2581,9 +2581,12 @@ class ADisruptingScepter:public TargetAbility{ void Update(float dt){ if (game->opponent()->isAI()){ if(waitingForAnswer){ - MTGCardInstance * card = ((AIPlayer *)game->opponent())->chooseCard(tc, source); - if (card) tc->toggleTarget(card); - if (!card || tc->targetsReadyCheck() == TARGET_OK) waitingForAnswer = 0; + MTGCardInstance * card = ((AIPlayer *)game->opponent())->chooseCard(tc, source); + if (card) tc->toggleTarget(card); + if (!card || tc->targetsReadyCheck() == TARGET_OK) { + waitingForAnswer = 0; + game->mLayers->actionLayer()->setCurrentWaitingAction(NULL); + } } TargetAbility::Update(dt); }else{ @@ -3138,7 +3141,7 @@ class AKudzu: public TargetAbility{ int testDestroy(){ int stillLandsInPlay = 0; for (int i = 0; i < 2; i++){ - if (game->players[i]->game->inPlay->hasType("land")) stillLandsInPlay = 1; + if (game->players[i]->game->inPlay->hasType("Land")) stillLandsInPlay = 1; } if (!stillLandsInPlay){ source->controller()->game->putInGraveyard(source); @@ -4051,7 +4054,7 @@ class AAngelicChorus: public ListMaintainerAbility{ } int canBeInList(MTGCardInstance * card){ - if (card->hasType("creature") && game->isInPlay(card)) return 1; + if (card->hasType(Subtypes::TYPE_CREATURE) && game->isInPlay(card)) return 1; return 0; } diff --git a/projects/mtg/include/GameApp.h b/projects/mtg/include/GameApp.h index dc437a8f2..76925e582 100644 --- a/projects/mtg/include/GameApp.h +++ b/projects/mtg/include/GameApp.h @@ -50,6 +50,10 @@ class GameApp: public JApp { private: +#ifdef DEBUG + int nbUpdates; + float totalFPS; +#endif bool mShowDebugInfo; int mScreenShotCount; diff --git a/projects/mtg/include/GameStateShop.h b/projects/mtg/include/GameStateShop.h index 407a8573e..61fab540b 100644 --- a/projects/mtg/include/GameStateShop.h +++ b/projects/mtg/include/GameStateShop.h @@ -21,8 +21,6 @@ class GameStateShop: public GameState, public JGuiListener ShopItems * shop; JLBFont * menuFont; JLBFont * itemFont; - JQuad * mBg; - JTexture * bgTexture; JTexture * altThumb[8]; JQuad * mBack; SimpleMenu * menu; diff --git a/projects/mtg/include/MTGCard.h b/projects/mtg/include/MTGCard.h index 49e481ab5..3aecc062d 100644 --- a/projects/mtg/include/MTGCard.h +++ b/projects/mtg/include/MTGCard.h @@ -29,6 +29,7 @@ class MTGCard { char image_name[MTGCARD_NAME_SIZE]; vector ftdText; int init(); + string lcname; public: string text; @@ -77,6 +78,7 @@ class MTGCard { void setName(string value); const string getName() const; + const string getLCName() const; void addType(char * type_text); void addType(int id); diff --git a/projects/mtg/include/Subtypes.h b/projects/mtg/include/Subtypes.h index 00470ba60..5c9d23459 100644 --- a/projects/mtg/include/Subtypes.h +++ b/projects/mtg/include/Subtypes.h @@ -4,22 +4,31 @@ #include #include -using std::string; -using std::map; +#include +using namespace std; + class Subtypes{ +public: + enum { + TYPE_CREATURE = 1, + TYPE_ENCHANTMENT = 2, + TYPE_SORCERY = 3, + TYPE_INSTANT = 4, + TYPE_LAND = 5, + TYPE_ARTIFACT = 6, + }; + + protected: map values; - map valuesById; - int nb_items; + vector valuesById; public: static Subtypes * subtypesList; Subtypes(); - int Add(const char * subtype); - int find(const char * subtype); - int Add(string subtype); - int find(string subtype); - string find(int id); + int find(const char * subtype, bool forceAdd = true); + int find(string subtype, bool forceAdd = true); + string find(unsigned int id); }; diff --git a/projects/mtg/include/WCachedResource.h b/projects/mtg/include/WCachedResource.h index 2d0e616b4..e7726146b 100644 --- a/projects/mtg/include/WCachedResource.h +++ b/projects/mtg/include/WCachedResource.h @@ -41,7 +41,8 @@ public: virtual ~WCachedResource() {}; - virtual void Refresh(string filename)=0; //Basically calls Attempt(filename) and remaps in situ. + string mFilename; + virtual void Refresh()=0; //Basically calls Attempt(filename) and remaps in situ. virtual bool Attempt(string filename, int submode, int & error)=0; //Returns true if we've loaded our data and isGood(). }; @@ -65,7 +66,7 @@ public: WCachedTexture(); ~WCachedTexture(); - void Refresh(string filename); + void Refresh(); unsigned long size(); bool isGood(); bool isLocked(); @@ -98,7 +99,7 @@ public: void Nullify(); void Trash(); - void Refresh(string filename); + void Refresh(); unsigned long size(); bool isGood(); @@ -121,7 +122,7 @@ public: bool compare(JSample * s) {return (s == sample);}; unsigned long size(); bool isGood(); - void Refresh(string filename); + void Refresh(); bool Attempt(string filename, int submode, int & error); JSample * Actual(); //Return this sample. diff --git a/projects/mtg/include/WResourceManager.h b/projects/mtg/include/WResourceManager.h index d1c6fef4c..580266aa6 100644 --- a/projects/mtg/include/WResourceManager.h +++ b/projects/mtg/include/WResourceManager.h @@ -13,6 +13,10 @@ #define TEXTURES_CACHE_MINSIZE 2000000 // Minimum size of the cache on the PSP. The program should complain if the cache ever gets smaller than this #define OPERATIONAL_SIZE 5000000 // Size required by Wagic for operational stuff. 3MB is not enough. The cache will usually try to take (Total Ram - Operational size) #define MIN_LINEAR_RAM 1000000 + +#define THUMBNAILS_OFFSET 100000000 +#define OTHERS_OFFSET 2000000000 + //Hard Limits. #define MAX_CACHE_OBJECTS 300 #define MAX_CACHE_ATTEMPTS 10 @@ -70,9 +74,9 @@ public: WCache(); ~WCache(); - cacheItem* Retrieve(string filename, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL); //Primary interface function. + cacheItem* Retrieve(int id, string filename, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL); //Primary interface function. bool Release(cacheActual* actual); //Releases an item, and deletes it if unlocked. - bool RemoveMiss(string id=""); //Removes a cache miss. + bool RemoveMiss(int id=0); //Removes a cache miss. bool RemoveOldest(); //Remove oldest unlocked item. bool Cleanup(); //Repeats RemoveOldest() until cache fits in size limits void Clear(); //Removes everything cached. Not lock safe, does not remove managed items. @@ -86,14 +90,14 @@ protected: bool RemoveItem(cacheItem * item, bool force = true); //Removes an item, deleting it. if(force), ignores locks / permanent bool UnlinkCache(cacheItem * item); //Removes an item from our cache, does not delete it. Use with care. bool Delete(cacheItem * item); //SAFE_DELETE and garbage collect. If maxCached == 0, nullify first. (This means you have to free that cacheActual later!) - cacheItem* Get(string id, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL); //Subordinate to Retrieve. + cacheItem* Get(int id, string filename, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL); //Subordinate to Retrieve. cacheItem* AttemptNew(string filename, int submode); //Attempts a new cache item, progressively clearing cache if it fails. - string makeID(string filename, int submode); //Makes an ID appropriate to the submode. - string makeFilename(string id, int submode); //Makes a filename from an ID. + int makeID(int id, string filename, int submode); //Makes an ID appropriate to the submode. - map cache; - map managed; //Cache can be arbitrarily large, so managed items are seperate. + map ids; + map cache; + map managed; //Cache can be arbitrarily large, so managed items are seperate. unsigned long totalSize; unsigned long cacheSize; @@ -104,8 +108,10 @@ protected: unsigned int cacheItems; int mError; + }; + struct WManagedQuad { WCachedTexture * texture; string resname; @@ -121,7 +127,7 @@ public: JQuad * RetrieveCard(MTGCard * card, int style = RETRIEVE_NORMAL,int submode = CACHE_NORMAL); JSample * RetrieveSample(string filename, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL); JTexture * RetrieveTexture(string filename, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL); - JQuad * RetrieveQuad(string filename, float offX=0.0f, float offY=0.0f, float width=0.0f, float height=0.0f, string resname="", int style = RETRIEVE_LOCK, int submode = CACHE_NORMAL); + JQuad * RetrieveQuad(string filename, float offX=0.0f, float offY=0.0f, float width=0.0f, float height=0.0f, string resname="", int style = RETRIEVE_LOCK, int submode = CACHE_NORMAL, int id = 0); JQuad * RetrieveTempQuad(string filename); hgeParticleSystemInfo * RetrievePSI(string filename, JQuad * texture, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL); int RetrieveError(); diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index d72d4110d..5eb15494b 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -599,7 +599,7 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty cd.setType(type); card = NULL; while((card = cd.nextmatch(game->hand, card))){ - if (card->hasType("land") && !this->canPutLandsIntoPlay) continue; + if (card->hasType(Subtypes::TYPE_LAND) && !this->canPutLandsIntoPlay) continue; if (card->has(Constants::LEGENDARY) && game->inPlay->findByName(card->name)) continue; int currentCost = card->getManaCost()->getConvertedCost(); int hasX = card->getManaCost()->hasX(); diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index 50ed44c4d..8f3b17565 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -3,6 +3,7 @@ #include "../include/GameObserver.h" #include "../include/Targetable.h" #include "../include/WEvent.h" +#include MTGAbility* ActionLayer::getAbility(int type){ for (int i = 1; i < mCount; i++){ @@ -17,6 +18,7 @@ MTGAbility* ActionLayer::getAbility(int type){ int ActionLayer::moveToGarbage(ActionElement * e){ int i = getIndexOf(e); if (i != -1){ + if (isWaitingForAnswer() == e) setCurrentWaitingAction(NULL); e->destroy(); mObjects.erase(mObjects.begin()+i); mCount--; @@ -125,13 +127,19 @@ void ActionLayer::Render (){ } - +void ActionLayer::setCurrentWaitingAction(ActionElement * ae){ + assert(!ae || !currentWaitingAction); + currentWaitingAction = ae; +} TargetChooser * ActionLayer::getCurrentTargetChooser(){ - for (int i=0;iwaitingForAnswer) return currentAction->tc; } + return NULL;*/ + if (currentWaitingAction && currentWaitingAction->waitingForAnswer) + return currentWaitingAction->tc; return NULL; } @@ -139,14 +147,13 @@ int ActionLayer::cancelCurrentAction(){ ActionElement * ae = isWaitingForAnswer(); if (!ae) return 0; ae->waitingForAnswer = 0; //TODO MOVE THIS IS ActionElement + setCurrentWaitingAction(NULL); return 1; } ActionElement * ActionLayer::isWaitingForAnswer(){ - for (int i=0;iwaitingForAnswer) return currentAction; - } + if (currentWaitingAction && currentWaitingAction->waitingForAnswer) + return currentWaitingAction; return NULL; } @@ -182,12 +189,8 @@ int ActionLayer::isReactingToTargetClick(Targetable * card){ int ActionLayer::reactToTargetClick(Targetable * card){ int result = 0; - for (int i=0;iwaitingForAnswer){ - return reactToTargetClick(currentAction,card); - } - } + ActionElement * ae = isWaitingForAnswer(); + if (ae) return reactToTargetClick(ae,card); for (int i=0;iisReactingToClick(card); @@ -214,12 +216,8 @@ int ActionLayer::isReactingToClick(MTGCardInstance * card){ int ActionLayer::reactToClick(MTGCardInstance * card){ int result = 0; - for (int i=0;iwaitingForAnswer){ - return reactToClick(currentAction,card); - } - } + ActionElement * ae = isWaitingForAnswer(); + if (ae) return reactToClick(ae,card); for (int i=0;iAdd(value); + int id = Subtypes::subtypesList->find(value); addType(-id); } @@ -30,12 +30,12 @@ MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card){ found = 0; if (types[i] >= 0){ - if (card->hasSubtype(types[i]) || (Subtypes::subtypesList->find(card->name) == types[i])){ + if (card->hasSubtype(types[i]) || (Subtypes::subtypesList->find(card->getLCName(),false) == types[i])){ found = 1; break; } }else{ - if (!card->hasSubtype(-types[i]) && (Subtypes::subtypesList->find(card->name) != -types[i])){ + if (!card->hasSubtype(-types[i]) && (Subtypes::subtypesList->find(card->getLCName(), false) != -types[i])){ found = 1; break; } @@ -67,11 +67,11 @@ MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card){ MTGCardInstance * match = card; for (int i = 0; i< nb_types; i++){ if (types[i] >= 0){ - if (!card->hasSubtype(types[i]) && !(Subtypes::subtypesList->find(card->name) == types[i])){ + if (!card->hasSubtype(types[i]) && !(Subtypes::subtypesList->find(card->getLCName(),false) == types[i])){ match = NULL; } }else{ - if(card->hasSubtype(-types[i]) || (Subtypes::subtypesList->find(card->name) == -types[i])){ + if(card->hasSubtype(-types[i]) || (Subtypes::subtypesList->find(card->getLCName(),false) == -types[i])){ match = NULL; } } diff --git a/projects/mtg/src/GameApp.cpp b/projects/mtg/src/GameApp.cpp index 088fd5edd..1cf56eba2 100644 --- a/projects/mtg/src/GameApp.cpp +++ b/projects/mtg/src/GameApp.cpp @@ -32,6 +32,11 @@ GameState::GameState(GameApp* parent): mParent(parent) GameApp::GameApp(): JApp() { +#ifdef DEBUG + nbUpdates = 0; + totalFPS = 0; +#endif + mScreenShotCount = 0; for (int i=0; i < MAX_STATE ; i++) @@ -286,6 +291,20 @@ void GameApp::Render() resources.DebugRender(); #endif +#ifdef DEBUG + JGE* mEngine = JGE::GetInstance(); + float fps = mEngine->GetFPS(); + totalFPS += fps; + nbUpdates+=1; + JLBFont * mFont= resources.GetJLBFont("simon"); + char buf[512]; + sprintf(buf, "avg:%f - %f fps",totalFPS/nbUpdates, fps); + if (mFont) { + mFont->SetColor(ARGB(255,255,255,255)); + mFont->DrawString(buf,1,1); + } +#endif + } void GameApp::SetNextState(int state) diff --git a/projects/mtg/src/GameStateShop.cpp b/projects/mtg/src/GameStateShop.cpp index 9814272df..b961d88e1 100644 --- a/projects/mtg/src/GameStateShop.cpp +++ b/projects/mtg/src/GameStateShop.cpp @@ -29,8 +29,6 @@ void GameStateShop::Start() mStage = STAGE_SHOP_SHOP; - - bgTexture = resources.RetrieveTexture("shop.jpg",RETRIEVE_LOCK); //alternateRender doesn't lock, so lock our thumbnails for hgeDistort. altThumb[0] = resources.RetrieveTexture("artifact_thumb.jpg", RETRIEVE_LOCK); @@ -42,7 +40,7 @@ void GameStateShop::Start() altThumb[6] = resources.RetrieveTexture("land_thumb.jpg", RETRIEVE_LOCK); altThumb[7] = resources.RetrieveTexture("gold_thumb.jpg", RETRIEVE_LOCK); - mBg = resources.RetrieveQuad("shop.jpg"); + mBack = resources.GetQuad("back"); menuFont = resources.GetJLBFont(Constants::MENU_FONT); @@ -125,7 +123,6 @@ void GameStateShop::load(){ void GameStateShop::End() { JRenderer::GetInstance()->EnableVSync(false); - resources.Release(bgTexture); //Release alternate thumbnails. for(int i=0;i<8;i++){ @@ -169,6 +166,7 @@ void GameStateShop::Render() //Erase JRenderer * r = JRenderer::GetInstance(); r->ClearScreen(ARGB(0,0,0,0)); + JQuad * mBg = resources.RetrieveQuad("shop.jpg"); if (mBg) r->RenderQuad(mBg,0,0); if (shop) diff --git a/projects/mtg/src/GuiFrame.cpp b/projects/mtg/src/GuiFrame.cpp index 5d980adb9..cbd10d450 100644 --- a/projects/mtg/src/GuiFrame.cpp +++ b/projects/mtg/src/GuiFrame.cpp @@ -32,8 +32,10 @@ GuiFrame::GuiFrame() step = 0.0; - gold2->SetColor(ARGB(127, 255, 255, 255)); - gold2->SetHFlip(true); + if (gold2){ + gold2->SetColor(ARGB(127, 255, 255, 255)); + gold2->SetHFlip(true); + } } GuiFrame::~GuiFrame() diff --git a/projects/mtg/src/GuiPlay.cpp b/projects/mtg/src/GuiPlay.cpp index d98427bd9..d0901f4e1 100644 --- a/projects/mtg/src/GuiPlay.cpp +++ b/projects/mtg/src/GuiPlay.cpp @@ -64,7 +64,6 @@ void GuiPlay::VertStack::Enstack(CardView* card) card->x = x + baseX; card->y = y + baseY; y += 12; if (++count == total-1 && y == 12) y += 12; - cerr << card->card->name << " " << card->x << "x" << card->y << " : " << nextX() << endl; } void GuiPlay::VertStack::Render(CardView* card, iterator begin, iterator end) diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index f54812e69..7dc6eb70a 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -186,7 +186,6 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG MTGCardInstance * target = card->target; if (!target) target = card; - TriggeredAbility * trigger = NULL; trigger = parseTrigger(s,id,spell,card,target); //Dirty way to remove the trigger text (could get in the way) @@ -1180,7 +1179,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ MTGInPlay * inplay = player->game->inPlay; for (int i = 0; i < inplay->nb_cards; i++){ MTGCardInstance * current = inplay->cards[i]; - if (current->hasType("land")) current->tap(); + if (current->hasType(Subtypes::TYPE_LAND)) current->tap(); } player->getManaPool()->init(); } @@ -1560,7 +1559,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ Damageable * target = spell->getNextDamageableTarget(); for (int j = card->controller()->game->inPlay->nb_cards-1; j >=0 ; --j){ MTGCardInstance * current = card->controller()->game->inPlay->cards[j]; - if (current->hasType("Creature")){ + if (current->hasType(Subtypes::TYPE_CREATURE)){ card->controller()->game->putInGraveyard(current); damage+= current->power; } @@ -1822,6 +1821,7 @@ void TargetAbility::Update(float dt){ JGE * mEngine = JGE::GetInstance(); if (waitingForAnswer){ if(mEngine->GetButtonClick(PSP_CTRL_CROSS)){ + game->mLayers->actionLayer()->setCurrentWaitingAction(NULL); waitingForAnswer = 0; }else if(tc->targetsReadyCheck() == TARGET_OK_FULL){ //waitingForAnswer = 0; @@ -1835,6 +1835,7 @@ int TargetAbility::reactToTargetClick(Targetable * object){ if (waitingForAnswer){ if (tc->toggleTarget(object) == TARGET_OK_FULL){ waitingForAnswer = 0; + game->mLayers->actionLayer()->setCurrentWaitingAction(NULL); return ActivatedAbility::reactToClick(source); } return 1; @@ -1847,18 +1848,23 @@ int TargetAbility::reactToClick(MTGCardInstance * card){ if (!waitingForAnswer) { if (isReactingToClick(card)){ waitingForAnswer = 1; + game->mLayers->actionLayer()->setCurrentWaitingAction(this); tc->initTargets(); return 1; } }else{ if (card == source && (tc->targetsReadyCheck() == TARGET_OK || tc->targetsReadyCheck() == TARGET_OK_FULL)){ waitingForAnswer = 0; + game->mLayers->actionLayer()->setCurrentWaitingAction(NULL); return ActivatedAbility::reactToClick(source); }else{ if (tc->toggleTarget(card) == TARGET_OK_FULL){ int result = ActivatedAbility::reactToClick(source); - if (result) waitingForAnswer = 0; + if (result) { + waitingForAnswer = 0; + game->mLayers->actionLayer()->setCurrentWaitingAction(NULL); + } return result; } return 1; @@ -2198,7 +2204,7 @@ AManaProducer::AManaProducer(int id, MTGCardInstance * card, ManaCost * _output, int AManaProducer::isReactingToClick(MTGCardInstance * _card, ManaCost * mana){ int result = 0; if (!mana) mana = game->currentlyActing()->getManaPool(); - if (_card == source && (!tap || !source->isTapped()) && game->currentlyActing()->game->inPlay->hasCard(source) && (source->hasType("land") || !tap || !source->hasSummoningSickness()) ){ + if (_card == source && (!tap || !source->isTapped()) && game->currentlyActing()->game->inPlay->hasCard(source) && (source->hasType(Subtypes::TYPE_LAND) || !tap || !source->hasSummoningSickness()) ){ if (!cost || mana->canAfford(cost)) result = 1; } return result; diff --git a/projects/mtg/src/MTGCard.cpp b/projects/mtg/src/MTGCard.cpp index f3ca94cc8..26f6e522f 100644 --- a/projects/mtg/src/MTGCard.cpp +++ b/projects/mtg/src/MTGCard.cpp @@ -45,7 +45,7 @@ MTGCard::MTGCard(MTGCard * source){ manaCost.copy(source->getManaCost()); text = source->text; - name = source->name; + setName(source->name); strcpy(image_name, source->image_name); rarity = source->rarity; @@ -120,10 +120,10 @@ const vector& MTGCard::formattedText() bool MTGCard::isCreature(){ - return hasSubtype("creature"); + return hasSubtype(Subtypes::TYPE_CREATURE); } bool MTGCard::isLand(){ - return hasSubtype("land"); + return hasSubtype(Subtypes::TYPE_LAND); } bool MTGCard::isSpell(){ return (!isCreature() && !isLand()); @@ -217,7 +217,7 @@ void MTGCard::addType(char * _type_text){ } void MTGCard::setSubtype( string value){ - int id = Subtypes::subtypesList->Add(value); + int id = Subtypes::subtypesList->find(value); addType(id); } @@ -232,7 +232,7 @@ void MTGCard::addType(int id){ //If removeAll is true, removes all occurences of this type, otherwise only removes the first occurence int MTGCard::removeType(string value, int removeAll){ - int id = Subtypes::subtypesList->Add(value); + int id = Subtypes::subtypesList->find(value); return removeType(id, removeAll); } @@ -271,15 +271,22 @@ void MTGCard::addMagicText(string value){ void MTGCard::setName( string value){ name = value; + lcname = value; + std::transform( lcname.begin(), lcname.end(),lcname.begin(),::tolower ); //This is a bug fix for plague rats and the "foreach ability" //Right now we add names as types, so that they get recognized - if (value.at(value.length()-1) == 's') Subtypes::subtypesList->Add(value); + if (lcname.at(value.length()-1) == 's') Subtypes::subtypesList->find(lcname); } const string MTGCard::getName() const{ return name; } +const string MTGCard::getLCName() const{ + return lcname; +} + + ManaCost* MTGCard::getManaCost(){ return &manaCost; @@ -299,18 +306,18 @@ bool MTGCard::hasSubtype(int _subtype){ } bool MTGCard::hasType(const char * _type){ - int id = Subtypes::subtypesList->Add(_type); + int id = Subtypes::subtypesList->find(_type); return hasType(id); } bool MTGCard::hasSubtype(const char * _subtype){ - int id = Subtypes::subtypesList->Add(_subtype); + int id = Subtypes::subtypesList->find(_subtype); return hasType(id); } bool MTGCard::hasSubtype(string _subtype){ - int id = Subtypes::subtypesList->Add(_subtype); + int id = Subtypes::subtypesList->find(_subtype); return hasType(id); } diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 27b20c544..aee2b54c3 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -53,7 +53,7 @@ void MTGCardInstance::copy(MTGCardInstance * card){ manaCost.copy(source->getManaCost()); text = source->text; - name = source->name; + setName(source->name); power = source->power; toughness = source->toughness; @@ -130,11 +130,11 @@ void MTGCardInstance::setType(const char * type_text){ } void MTGCardInstance::setSubtype(string value){ - int id = Subtypes::subtypesList->Add(value); + int id = Subtypes::subtypesList->find(value); addType(id); } int MTGCardInstance::removeType(string value,int removeAll){ - int id = Subtypes::subtypesList->Add(value); + int id = Subtypes::subtypesList->find(value); return removeType(id,removeAll); } diff --git a/projects/mtg/src/Subtypes.cpp b/projects/mtg/src/Subtypes.cpp index 00e0e3124..ab62de54f 100644 --- a/projects/mtg/src/Subtypes.cpp +++ b/projects/mtg/src/Subtypes.cpp @@ -6,42 +6,34 @@ Subtypes * Subtypes::subtypesList = NEW Subtypes(); - Subtypes::Subtypes(){ - nb_items = 100; + //Add the more common types, so that they can be accessed through ints + //these should be added in the same order as the enum defined in subtypes.h!!! + find("Creature"); + find("Enchantment"); + find("Sorcery"); + find("Instant"); + find("Land"); + find("Artifact"); } -int Subtypes::Add(string value){ - int result = find(value); - if (result) return result; - std::transform( value.begin(), value.end(), value.begin(), ::tolower ); - nb_items++; - values[value] = nb_items; - valuesById[nb_items] = value; - return nb_items; -} - -int Subtypes::Add(const char * subtype){ - string value = subtype; - return Add(value); - -} - -int Subtypes::find(string value){ - std::transform( value.begin(), value.end(), value.begin(), ::tolower ); +int Subtypes::find(string value, bool forceAdd){ + if (value[0]>=97 && value[0]<=122) value[0]-=32; //Poor man's camelcase. We assume strings we get are either Camelcased or lowercase map::iterator it = values.find(value); if (it != values.end()) return it->second; - return 0; + if (!forceAdd) return 0; + int id = (int)(valuesById.size() + 1); + values[value] = id; + valuesById.push_back(value); + return id; } -int Subtypes::find(const char * subtype){ +int Subtypes::find(const char * subtype, bool forceAdd){ string value = subtype; return (find(value)); - } -string Subtypes::find(int id){ - map::iterator it=valuesById.find(id);; - if (it != valuesById.end()) return it->second; - return ""; +string Subtypes::find(unsigned int id){ + if (valuesById.size() < id || !id) return ""; + return valuesById[id - 1]; } diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 6d8054c60..d45d6bca4 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -176,7 +176,7 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta typeName = typeName.substr(0,found); } //X targets allowed ? - if (typeName.at(typeName.length()-1) == 's' && !Subtypes::subtypesList->find(typeName) && typeName.compare("this")!=0){ + if (typeName.at(typeName.length()-1) == 's' && !Subtypes::subtypesList->find(typeName,false) && typeName.compare("this")!=0){ typeName = typeName.substr(0,typeName.length()-1); maxtargets = -1; } @@ -358,7 +358,7 @@ bool CardTargetChooser::canTarget(Targetable * target ){ Choose anything that has a given list of types **/ TypeTargetChooser::TypeTargetChooser(const char * _type, MTGCardInstance * card, int _maxtargets,bool other):TargetZoneChooser(card, _maxtargets,other){ - int id = Subtypes::subtypesList->Add(_type); + int id = Subtypes::subtypesList->find(_type); nbtypes = 0; addType(id); int default_zones[] = {MTGGameZone::MY_BATTLEFIELD, MTGGameZone::OPPONENT_BATTLEFIELD}; @@ -366,7 +366,7 @@ TypeTargetChooser::TypeTargetChooser(const char * _type, MTGCardInstance * card, } TypeTargetChooser::TypeTargetChooser(const char * _type, int * _zones, int nbzones, MTGCardInstance * card, int _maxtargets,bool other):TargetZoneChooser(card, _maxtargets,other){ - int id = Subtypes::subtypesList->Add(_type); + int id = Subtypes::subtypesList->find(_type); nbtypes = 0; addType(id); if (nbzones == 0){ @@ -378,7 +378,7 @@ TypeTargetChooser::TypeTargetChooser(const char * _type, int * _zones, int nbzon } void TypeTargetChooser::addType(const char * _type){ - int id = Subtypes::subtypesList->Add(_type); + int id = Subtypes::subtypesList->find(_type); addType(id); } @@ -393,7 +393,7 @@ bool TypeTargetChooser::canTarget(Targetable * target){ MTGCardInstance * card = (MTGCardInstance *) target; for (int i= 0; i < nbtypes; i++){ if (card->hasSubtype(types[i])) return true; - if (Subtypes::subtypesList->find(card->name) == types[i]) return true; + if (Subtypes::subtypesList->find(card->getLCName()) == types[i]) return true; } return false; }else if (target->typeAsTarget() == TARGET_STACKACTION){ diff --git a/projects/mtg/src/WCachedResource.cpp b/projects/mtg/src/WCachedResource.cpp index 700403ee0..4881798d8 100644 --- a/projects/mtg/src/WCachedResource.cpp +++ b/projects/mtg/src/WCachedResource.cpp @@ -227,12 +227,12 @@ bool WCachedTexture::isGood(){ return (texture != NULL); } -void WCachedTexture::Refresh(string filename){ +void WCachedTexture::Refresh(){ int error = 0; JTexture* old = texture; texture = NULL; - if(!Attempt(filename,loadedMode, error)) + if(!Attempt(mFilename,loadedMode, error)) SAFE_DELETE(texture); if(!texture) @@ -247,6 +247,7 @@ void WCachedTexture::Refresh(string filename){ } bool WCachedTexture::Attempt(string filename, int submode, int & error){ + mFilename = filename; int format = TEXTURE_FORMAT; loadedMode = submode; string realname; @@ -366,7 +367,7 @@ bool WCachedSample::isGood(){ return true; } -void WCachedSample::Refresh(string filename){ +void WCachedSample::Refresh(){ return; } @@ -403,11 +404,11 @@ unsigned long WCachedParticles::size(){ } //Only effects future particle systems, of course. -void WCachedParticles::Refresh(string filename){ +void WCachedParticles::Refresh(){ hgeParticleSystemInfo * old = particles; int error = 0; - Attempt(filename,loadedMode,error); + Attempt(mFilename,loadedMode,error); if(isGood()) SAFE_DELETE(old); diff --git a/projects/mtg/src/WResourceManager.cpp b/projects/mtg/src/WResourceManager.cpp index 0a7012a57..fab18f057 100644 --- a/projects/mtg/src/WResourceManager.cpp +++ b/projects/mtg/src/WResourceManager.cpp @@ -10,6 +10,8 @@ #include "../include/WResourceManager.h" +int idCounter = OTHERS_OFFSET; + WResourceManager resources; unsigned int vTime = 0; int WResourceManager::RetrieveError(){ @@ -196,11 +198,11 @@ JQuad * WResourceManager::RetrieveCard(MTGCard * card, int style, int submode){ submode = submode | TEXTURE_SUB_CARD; - string filename = card->getSetName(); filename += "/"; filename += card->getImageName(); - JQuad * jq = RetrieveQuad(filename,0,0,0,0,"",style,submode|TEXTURE_SUB_5551); + int id = card->getMTGId(); + JQuad * jq = RetrieveQuad(filename,0,0,0,0, "",style,submode|TEXTURE_SUB_5551,id); lastError = textureWCache.mError; if(jq){ jq->SetHotSpot(jq->mTex->mWidth / 2, jq->mTex->mHeight / 2); @@ -224,7 +226,7 @@ int WResourceManager::CreateQuad(const string &quadName, const string &textureNa return pos; } - WCachedTexture * jtex = textureWCache.Retrieve(textureName,RETRIEVE_MANAGE); + WCachedTexture * jtex = textureWCache.Retrieve(0,textureName,RETRIEVE_MANAGE); lastError = textureWCache.mError; //Somehow, jtex wasn't promoted. @@ -275,7 +277,7 @@ JQuad * WResourceManager::RetrieveTempQuad(string filename){ return RetrieveQuad(filename,0,0,0,0,"temporary",RETRIEVE_NORMAL); } -JQuad * WResourceManager::RetrieveQuad(string filename, float offX, float offY, float width, float height, string resname, int style, int submode){ +JQuad * WResourceManager::RetrieveQuad(string filename, float offX, float offY, float width, float height, string resname, int style, int submode, int id){ JQuad * jq = NULL; //Lookup managed resources, but only with a real resname. @@ -298,9 +300,9 @@ JQuad * WResourceManager::RetrieveQuad(string filename, float offX, float offY, //No quad, but we have a managed texture for this! WCachedTexture * jtex = NULL; if(style == RETRIEVE_MANAGE || style == RETRIEVE_EXISTING) - jtex = textureWCache.Retrieve(filename,style,submode); + jtex = textureWCache.Retrieve(id,filename,style,submode); else - jtex = textureWCache.Retrieve(filename,RETRIEVE_NORMAL,submode); + jtex = textureWCache.Retrieve(id, filename,RETRIEVE_NORMAL,submode); lastError = textureWCache.mError; @@ -345,7 +347,7 @@ void WResourceManager::Release(JQuad * quad){ if(!quad) return; - map::iterator it; + map::iterator it; for(it = textureWCache.cache.begin();it!=textureWCache.cache.end();it++){ if(it->second && it->second->ReleaseQuad(quad)) break; @@ -395,7 +397,7 @@ JTexture * WResourceManager::RetrieveTexture(string filename, int style, int sub style = RETRIEVE_NORMAL; } - res = textureWCache.Retrieve(filename,style,submode); + res = textureWCache.Retrieve(0,filename,style,submode); lastError = textureWCache.mError; if(res){ //a non-null result will always be good. @@ -448,7 +450,7 @@ JTexture* WResourceManager::GetTexture(const string &textureName){ } JTexture* WResourceManager::GetTexture(int id){ - map::iterator it; + map::iterator it; JTexture *jtex = NULL; if(id == INVALID_ID) @@ -470,7 +472,7 @@ hgeParticleSystemInfo * WResourceManager::RetrievePSI(string filename, JQuad * t if(!texture) return NULL; - WCachedParticles * res = psiWCache.Retrieve(filename,style,submode); + WCachedParticles * res = psiWCache.Retrieve(0,filename,style,submode); lastError = psiWCache.mError; if(res) //A non-null result will always be good. @@ -485,7 +487,7 @@ hgeParticleSystemInfo * WResourceManager::RetrievePSI(string filename, JQuad * t JSample * WResourceManager::RetrieveSample(string filename, int style, int submode){ WCachedSample * tc = NULL; - tc = sampleWCache.Retrieve(filename,style,submode); + tc = sampleWCache.Retrieve(0,filename,style,submode); lastError = sampleWCache.mError; //Sample exists! Get it. @@ -870,9 +872,9 @@ void WResourceManager::Refresh(){ //WCache template bool WCache::RemoveOldest(){ - typename map ::iterator oldest = cache.end(); + typename map ::iterator oldest = cache.end(); - for(typename map::iterator it = cache.begin();it!=cache.end();it++){ + for(typename map::iterator it = cache.begin();it!=cache.end();it++){ if(it->second && !it->second->isLocked() && (oldest == cache.end() || it->second->lastTime < oldest->second->lastTime)) oldest = it; @@ -889,7 +891,7 @@ bool WCache::RemoveOldest(){ } template void WCache::Clear(){ - typename map::iterator it, next; + typename map::iterator it, next; for(it = cache.begin(); it != cache.end();it=next){ next = it; @@ -910,7 +912,7 @@ void WCache::Clear(){ template void WCache::ClearUnlocked(){ - typename map::iterator it, next; + typename map::iterator it, next; for(it = cache.begin(); it != cache.end();it=next){ next = it; @@ -928,7 +930,7 @@ void WCache::ClearUnlocked(){ template void WCache::ClearMisses(){ - typename map::iterator it, next; + typename map::iterator it, next; for(it = cache.begin(); it != cache.end();it=next){ next = it; @@ -995,14 +997,14 @@ cacheItem* WCache::AttemptNew(string filename, int submo } template -cacheItem * WCache::Retrieve(string filename, int style, int submode){ +cacheItem * WCache::Retrieve(int id, string filename, int style, int submode){ //Check cache. cacheItem * tc = NULL; if(style == RETRIEVE_EXISTING || style == RETRIEVE_RESOURCE) - tc = Get(filename,style,submode|CACHE_EXISTING); + tc = Get(id,filename,style,submode|CACHE_EXISTING); else - tc = Get(filename,style,submode); + tc = Get(id, filename,style,submode); //Retrieve resource only works on permanent items. if(style == RETRIEVE_RESOURCE && tc && !tc->isPermanent()){ @@ -1021,7 +1023,7 @@ cacheItem * WCache::Retrieve(string filename, int style, UnlinkCache(tc); //Post it in managed resources. - managed[makeID(filename,submode)] = tc; + managed[makeID(id,filename,submode)] = tc; tc->deadbolt(); } break; @@ -1040,34 +1042,35 @@ cacheItem * WCache::Retrieve(string filename, int style, //Record managed failure. Cache failure is recorded in Get(). if(style == RETRIEVE_MANAGE || style == RETRIEVE_RESOURCE) - managed[makeID(filename,submode)] = NULL; + managed[makeID(id,filename,submode)] = NULL; return NULL; } template -string WCache::makeID(string id, int submode){ - string lookup = id; +int WCache::makeID(int id, string filename, int submode){ + int mId = id; + if (!mId) { + mId = ids[filename]; + if (!mId){ + mId = idCounter++; + ids[filename] = mId; + } + } //To differentiate between cached thumbnails and the real thing. - if(submode & TEXTURE_SUB_THUMB) - lookup.insert(0,"T"); - - return lookup; + if(submode & TEXTURE_SUB_THUMB){ + if (mId < 0) + mId-=THUMBNAILS_OFFSET; + else + mId+=THUMBNAILS_OFFSET; + } + return mId; } template -string WCache::makeFilename(string id, int submode){ - //To differentiate between cached thumbnails and the real thing. - if(submode & TEXTURE_SUB_THUMB) - return id.substr(1); - - return id; -} - -template -cacheItem * WCache::Get(string id, int style, int submode){ - typename map::iterator it; - string lookup = makeID(id,submode); +cacheItem * WCache::Get(int id, string filename, int style, int submode){ + typename map::iterator it; + int lookup = makeID(id,filename, submode); //Check for managed resources first. Always it = managed.find(lookup); @@ -1101,7 +1104,7 @@ cacheItem * WCache::Get(string id, int style, int submod } //Space in cache, make new texture - cacheItem * item = AttemptNew(id,submode); + cacheItem * item = AttemptNew(filename,submode); if(style == RETRIEVE_MANAGE){ managed[lookup] = item; //Record a hit or miss. @@ -1130,17 +1133,17 @@ cacheItem * WCache::Get(string id, int style, int submod template void WCache::Refresh(){ - typename map::iterator it; + typename map::iterator it; ClearUnlocked(); for(it = cache.begin();it!=cache.end();it++){ if(it->second){ - it->second->Refresh(makeFilename(it->first,it->second->loadedMode)); + it->second->Refresh(); } } for(it = managed.begin();it!=managed.end();it++){ if(it->second){ - it->second->Refresh(makeFilename(it->first,it->second->loadedMode)); + it->second->Refresh(); } } } @@ -1159,7 +1162,7 @@ WCache::WCache(){ template WCache::~WCache(){ - typename map::iterator it; + typename map::iterator it; //Delete from cache & managed for(it=cache.begin();it!=cache.end();it++){ @@ -1196,13 +1199,13 @@ unsigned int WCache::Flatten(){ unsigned int youngest = 65535; unsigned int oldest = 0; - for (typename map::iterator it = cache.begin(); it != cache.end(); ++it){ + for (typename map::iterator it = cache.begin(); it != cache.end(); ++it){ if(!it->second) continue; if(it->second->lastTime < youngest) youngest = it->second->lastTime; if(it->second->lastTime > oldest) oldest = it->second->lastTime; } - for (typename map::iterator it = cache.begin(); it != cache.end(); ++it){ + for (typename map::iterator it = cache.begin(); it != cache.end(); ++it){ if(!it->second) continue; it->second->lastTime -= youngest; } @@ -1211,11 +1214,11 @@ unsigned int WCache::Flatten(){ } template -bool WCache::RemoveMiss(string id){ - typename map::iterator it = cache.end(); +bool WCache::RemoveMiss(int id){ + typename map::iterator it = cache.end(); for(it = cache.begin();it!=cache.end();it++){ - if((id == "" || it->first == id) && it->second == NULL) + if((id == 0 || it->first == id) && it->second == NULL) break; } @@ -1230,7 +1233,7 @@ bool WCache::RemoveMiss(string id){ template bool WCache::RemoveItem(cacheItem * item, bool force){ - typename map::iterator it; + typename map::iterator it; if(item == NULL) return false; //Use RemoveMiss to remove cache misses, not this. @@ -1250,7 +1253,7 @@ bool WCache::RemoveItem(cacheItem * item, bool force){ template bool WCache::UnlinkCache(cacheItem * item){ - typename map::iterator it = cache.end(); + typename map::iterator it = cache.end(); if(item == NULL) return false; //Use RemoveMiss to remove cache misses, not this. @@ -1298,7 +1301,7 @@ bool WCache::Release(cacheActual* actual){ if(!actual) return false; - typename map::iterator it; + typename map::iterator it; for(it=cache.begin();it!=cache.end();it++){ if(it->second && it->second->compare(actual)) break;