diff --git a/projects/mtg/bin/Res/graphics/counters/default.png b/projects/mtg/bin/Res/graphics/counters/default.png new file mode 100644 index 000000000..094bc5500 Binary files /dev/null and b/projects/mtg/bin/Res/graphics/counters/default.png differ diff --git a/projects/mtg/bin/Res/graphics/counters/quest.png b/projects/mtg/bin/Res/graphics/counters/quest.png new file mode 100644 index 000000000..78c7fdd13 Binary files /dev/null and b/projects/mtg/bin/Res/graphics/counters/quest.png differ diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 891e84610..014c3990f 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -2484,7 +2484,7 @@ public: string sourcename = ((MTGCardInstance*)source)->name; tokenText.append(") source: "); tokenText.append( sourcename); - myToken->text = tokenText; + myToken->setText(tokenText); } setTokenOwner(); tokenReciever->game->temp->addCard(myToken); diff --git a/projects/mtg/include/CardGui.h b/projects/mtg/include/CardGui.h index 5bfbfc1c1..099b22a02 100644 --- a/projects/mtg/include/CardGui.h +++ b/projects/mtg/include/CardGui.h @@ -33,7 +33,7 @@ protected: */ static void RenderBig(MTGCard * card, const Pos& pos); - void RenderCountersBig(const Pos& pos); + static void RenderCountersBig(MTGCard * card, const Pos& pos, int drawMode = DrawMode::kNormal); static void AlternateRender(MTGCard * card, const Pos& pos); static void TinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad); diff --git a/projects/mtg/include/CardPrimitive.h b/projects/mtg/include/CardPrimitive.h index eca14715e..028d0196b 100644 --- a/projects/mtg/include/CardPrimitive.h +++ b/projects/mtg/include/CardPrimitive.h @@ -26,12 +26,15 @@ class CardPrimitive : public InstanceCounter #endif { +private: + string text; + vector formattedText; + protected: string lcname; ManaCost manaCost; public: - string text; string name; int init(); @@ -67,7 +70,7 @@ public: int has(int ability); void setText(const string& value); - const string& getText(); + const vector& getFormattedText(); void addMagicText(string value); void addMagicText(string value, string zone); diff --git a/projects/mtg/include/Counters.h b/projects/mtg/include/Counters.h index a2365b3ee..a4d9b04ae 100644 --- a/projects/mtg/include/Counters.h +++ b/projects/mtg/include/Counters.h @@ -28,7 +28,7 @@ class Counters { public: int mCount; - Counter * counters[10]; + vectorcounters; MTGCardInstance * target; Counters(MTGCardInstance * _target); ~Counters(); diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index 047383398..ced1bc257 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -451,11 +451,11 @@ int AIAction::getEfficiency() efficiency = 90; } - if(_target->counters && _target->counters->counters && _target->counters->hasCounter(cc->power,cc->toughness) && _target->counters->hasCounter(cc->power,cc->toughness)->nb > 15) + if(_target->counters && _target->counters->hasCounter(cc->power,cc->toughness) && _target->counters->hasCounter(cc->power,cc->toughness)->nb > 15) { efficiency = _target->counters->hasCounter(cc->power,cc->toughness)->nb; } - if(cc->maxNb && _target->counters && _target->counters->counters && _target->counters->hasCounter(cc->power,cc->toughness)->nb >= cc->maxNb) + if(cc->maxNb && _target->counters && _target->counters->hasCounter(cc->power,cc->toughness)->nb >= cc->maxNb) efficiency = 0; } } diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 078de790d..aeaf43785 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -2601,10 +2601,9 @@ int ATransformer::addToGame() int ATransformer::reapplyCountersBonus(MTGCardInstance * rtarget,bool powerapplied,bool toughnessapplied) { - if(!rtarget->counters) + if(!rtarget->counters || !rtarget->counters->counters.size()) return 0; - Counter * c = NULL; - c = rtarget->counters->counters[0]; + Counter * c = rtarget->counters->counters[0]; int rNewPower = 0; int rNewToughness = 0; for (int t = 0; t < rtarget->counters->mCount; t++) diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index e67c3d241..88484a2fe 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -34,17 +34,6 @@ namespace return cosf(2 * M_PI * (value - 35) / 256.0f); } - void FormatText(std::string inText, std::vector& outFormattedText) - { - std::string::size_type found = inText.find_first_of("{}"); - while (found != string::npos) - { - inText[found] = '/'; - found = inText.find_first_of("{}", found + 1); - } - WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAGIC_FONT); - mFont->FormatText(inText, outFormattedText); - } } CardGui::CardGui(MTGCardInstance* card, float x, float y) @@ -119,10 +108,6 @@ void CardGui::Update(float dt) void CardGui::DrawCard(const Pos& inPosition, int inMode) { DrawCard(card, inPosition, inMode); - if (inMode != DrawMode::kHidden) - { - RenderCountersBig(inPosition); - } } void CardGui::DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode) @@ -253,6 +238,7 @@ void CardGui::Render() mFont->SetScale(1); } } + if (tc && !tc->canTarget(card)) { if (!shadow) @@ -394,8 +380,7 @@ void CardGui::AlternateRender(MTGCard * card, const Pos& pos) { font->SetScale(kWidthScaleFactor * pos.actZ); - std::vector txt; - FormatText(card->data->getText(), txt); + std::vector txt = card->data->getFormattedText(); unsigned i = 0; unsigned h = neofont ? 14 : 11; @@ -549,6 +534,8 @@ void CardGui::AlternateRender(MTGCard * card, const Pos& pos) } font->SetScale(backup_scale); + + RenderCountersBig(card, pos, DrawMode::kText); } void CardGui::TinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad) @@ -605,8 +592,7 @@ void CardGui::TinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad) renderer->RenderQuad(q.get(), x, pos.actY, pos.actT, scale, scale); } - std::vector txt; - FormatText(card->data->getText(), txt); + std::vector txt = card->data->getFormattedText(); size_t nbTextLines = txt.size(); //Render the image on top of that @@ -783,6 +769,8 @@ void CardGui::TinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad) } font->SetScale(backup_scale); + + RenderCountersBig(card, pos); } //Renders a big card on screen. Defaults to the "alternate" rendering if no image is found @@ -802,6 +790,7 @@ void CardGui::RenderBig(MTGCard* card, const Pos& pos) quad->SetColor(ARGB(255,255,255,255)); float scale = pos.actZ * 250.f / quad->mHeight; renderer->RenderQuad(quad.get(), x, pos.actY, pos.actT, scale, scale); + RenderCountersBig(card, pos); return; } @@ -811,47 +800,114 @@ void CardGui::RenderBig(MTGCard* card, const Pos& pos) AlternateRender(card, pos); } -void CardGui::RenderCountersBig(const Pos& pos) +void CardGui::RenderCountersBig(MTGCard * mtgcard, const Pos& pos, int drawMode) { - // Write Named Counters - if (card->counters && card->counters->mCount > 0) - { - WFont * font = WResourceManager::Instance()->GetWFont(Fonts::MAGIC_FONT); - font->SetColor(ARGB((int)pos.actA, 0, 0, 0)); - font->SetScale(kWidthScaleFactor * pos.actZ); + MTGCardInstance * card = dynamic_cast (mtgcard); + if (!card) + return; - std::vector txt; - FormatText(card->data->getText(), txt); - unsigned i = txt.size() + 1; - Counter * c = NULL; - for (int t = 0; t < card->counters->mCount; t++, i++) + if (!card->counters) + return; + if (!card->counters->mCount) + return; + + // Write Named Counters + WFont * font = WResourceManager::Instance()->GetWFont(Fonts::MAGIC_FONT); + font->SetColor(ARGB((int)pos.actA, 0, 0, 0)); + font->SetScale(kWidthScaleFactor * pos.actZ); + + unsigned i = 0; + if (drawMode == DrawMode::kText) + { + std::vector txt = card->data->getFormattedText(); + i = txt.size() + 1; + } + + for (size_t t = 0; t < card->counters->counters.size(); t++) + { + Counter * c = card->counters->counters[t]; + + if (!c || c->nb <= 0) + continue; + + char buf[512]; + bool renderText = true; + string gfx = ""; + //TODO cache the gfx fetch results? + if (c->name.size()) { - if (c) + if (c->nb < 6) //we only render a counter's specific quad if there are 5 counters of this type or less. Otherwise we will use the generic one { - c = card->counters->getNext(c); - } - else - { - c = card->counters->counters[0]; - } - if (c != NULL && c->nb > 0) - { - char buf[512]; - if (c->name != "") + string gfxRelativeName = "counters/"; + gfxRelativeName.append(c->name); + gfxRelativeName.append(".png"); + gfx = WResourceManager::Instance()->graphicsFile(gfxRelativeName); + if (fileExists(gfx.c_str())) { - std::string s = c->name; - s[0] = toupper(s[0]); - sprintf(buf, _("%s counters: %i").c_str(), s.c_str(), c->nb); + renderText = false; + } + else + { + gfx = ""; + } + } + + if (renderText) + { + std::string s = c->name; + s[0] = toupper(s[0]); + sprintf(buf, _("%s: %i").c_str(), s.c_str(), c->nb); + } + } + else + { + sprintf(buf, _("%s%i/%s%i").c_str(), ((c->power > 0) ? "+": ""), c->power * c->nb, ((c->toughness > 0) ? "+": ""),c->toughness* c->nb); + } + + if (!gfx.size()) + { + gfx = WResourceManager::Instance()->graphicsFile("counters/default.png"); + if (!fileExists(gfx.c_str())) + gfx = ""; + } + + float x = pos.actX + (22 - BigWidth / 2) * pos.actZ; + float y = pos.actY + (-BigHeight / 2 + 80 + 11 * i + 21 * t) * pos.actZ; + if (y > pos.actY + 105) + { + y = (-BigHeight / 2 + 80 + 11 * i) * pos.actZ + (y - 105 - 21); + x += (BigWidth / 2) * pos.actZ; + } + + if (gfx.size()) + { + JQuadPtr q = WResourceManager::Instance()->RetrieveTempQuad(gfx); + + if (q.get() && q->mTex) + { + float scale = 20.f / q->mHeight; + if (renderText) + { + float scaleX = (font->GetStringWidth(buf) + 20) / q->mWidth; + JRenderer::GetInstance()->RenderQuad(q.get(), x, y, 0, scaleX, scale); } else { - sprintf(buf, _("%i/%i counters: %i").c_str(), c->power, c->toughness, c->nb); + for (int j = 0; j < c->nb; ++j) + { + JRenderer::GetInstance()->RenderQuad(q.get(), x + (scale * q->mWidth * j), y, 0, scale, scale); + } } - font->DrawString(buf, pos.actX + (22 - BigWidth / 2) * pos.actZ, pos.actY + (-BigHeight / 2 + 80 + 11 * i) - * pos.actZ); } } + + if (renderText) + { + font->SetColor(ARGB(255,0,0,0)); + font->DrawString(buf, x + 5, y + 5); + } } + } MTGCardInstance* CardView::getCard() diff --git a/projects/mtg/src/CardPrimitive.cpp b/projects/mtg/src/CardPrimitive.cpp index c32e12bb0..920320ec2 100644 --- a/projects/mtg/src/CardPrimitive.cpp +++ b/projects/mtg/src/CardPrimitive.cpp @@ -246,10 +246,32 @@ void CardPrimitive::setText(const string& value) text = value; } -const string& CardPrimitive::getText() +/* This alters the card structure, but this is intentional for performance and +* space purpose: The only time we get the card text is to render it +* on the screen, in a formatted way. +* Formatting the string every frame is not efficient, especially since we always display it the same way +* Formatting all strings at startup is inefficient too. +* Instead, we format when requested, but only once, and cache the result. +* To avoid memory to blow up, in exchange of the cached result, we erase the original string +*/ +const vector& CardPrimitive::getFormattedText() { - return text; -} + if (!text.size()) + return formattedText; + + std::string::size_type found = text.find_first_of("{}"); + while (found != string::npos) + { + text[found] = '/'; + found = text.find_first_of("{}", found + 1); + } + WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAGIC_FONT); + mFont->FormatText(text, formattedText); + + text = ""; + + return formattedText; +}; void CardPrimitive::addMagicText(string value) { diff --git a/projects/mtg/src/Counters.cpp b/projects/mtg/src/Counters.cpp index 722bdb265..41a752c40 100644 --- a/projects/mtg/src/Counters.cpp +++ b/projects/mtg/src/Counters.cpp @@ -92,7 +92,7 @@ int Counters::addCounter(const char * _name, int _power, int _toughness) } } Counter * counter = NEW Counter(target, _name, _power, _toughness); - counters[mCount] = counter; + counters.push_back(counter); counter->added(); mCount++; return mCount; diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 48a1c1e85..43234ffaa 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -64,7 +64,7 @@ void MTGCardInstance::copy(MTGCardInstance * card) manaCost.copy(data->getManaCost()); - text = data->text; + setText(""); //The text is retrieved from the data anyways setName(data->name); power = data->power; diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index ad0b19318..528b696fc 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -1049,7 +1049,6 @@ void MTGDeck::printDetailedDeckText(std::ofstream& file ) MTGSetInfo *setInfo = setlist.getInfo(card->setId); string setName = setInfo->id; string cardName = card->data->getName(); - string description = card->data->getText(); currentCard << "#" << nbCards << " x " << cardName << " (" << setName << "), "; diff --git a/projects/mtg/template.vcxproj.filters b/projects/mtg/template.vcxproj.filters index 84cb0a519..b1c074b11 100644 --- a/projects/mtg/template.vcxproj.filters +++ b/projects/mtg/template.vcxproj.filters @@ -289,12 +289,6 @@ src - - inc - - - inc - src @@ -313,6 +307,12 @@ src + + src + + + src +