From 2ff279fad8b5565199fa966fbef8b40941ba0b7c Mon Sep 17 00:00:00 2001 From: "jean.chalard" Date: Fri, 28 Aug 2009 13:57:12 +0000 Subject: [PATCH] J : * Order blocker interface. --- projects/mtg/bin/Res/test/order_blockers.txt | 28 ++ projects/mtg/include/CardGui.h | 34 +- projects/mtg/include/CardSelector.h | 5 + projects/mtg/include/GuiCombat.h | 14 +- projects/mtg/include/MTGCardInstance.h | 3 +- projects/mtg/include/WEvent.h | 23 +- projects/mtg/src/CardGui.cpp | 375 ++----------------- projects/mtg/src/CardSelector.cpp | 67 ++-- projects/mtg/src/DamageResolverLayer.cpp | 2 +- projects/mtg/src/DuelLayers.cpp | 4 +- projects/mtg/src/GameObserver.cpp | 2 + projects/mtg/src/GameOptions.cpp | 2 +- projects/mtg/src/GuiCombat.cpp | 160 +++++++- projects/mtg/src/MTGCardInstance.cpp | 20 +- 14 files changed, 299 insertions(+), 440 deletions(-) create mode 100644 projects/mtg/bin/Res/test/order_blockers.txt diff --git a/projects/mtg/bin/Res/test/order_blockers.txt b/projects/mtg/bin/Res/test/order_blockers.txt new file mode 100644 index 000000000..989d998c3 --- /dev/null +++ b/projects/mtg/bin/Res/test/order_blockers.txt @@ -0,0 +1,28 @@ +#Testing Random discard +[INIT] +COMBATATTACKERS +[PLAYER1] +inplay:Elite Vanguard,Rhox Pikemaster,Bog wraith +[PLAYER2] +inplay:air elemental,grizzly bears,spark elemental,drudge skeletons,vampire bats,tundra wolves,spined wurm,paladin en-vec +[DO] +Elite Vanguard +Rhox Pikemaster +Bog wraith +next +paladin en-vec +paladin en-vec +spined wurm +spined wurm +vampire bats +vampire bats +tundra wolves +tundra wolves +air elemental +air elemental +grizzly bears +grizzly bears +spark elemental +drudge skeletons +next +human diff --git a/projects/mtg/include/CardGui.h b/projects/mtg/include/CardGui.h index 063629798..b7779961f 100644 --- a/projects/mtg/include/CardGui.h +++ b/projects/mtg/include/CardGui.h @@ -25,9 +25,9 @@ struct CardGui : public PlayGuiObject { MTGCardInstance* card; CardGui(MTGCardInstance* card, float x, float y); CardGui(MTGCardInstance* card, const Pos& ref); - virtual void Render() = 0; + virtual void Render(); void RenderBig(const Pos&); - virtual void Update(float dt) = 0; + virtual void Update(float dt); static void alternateRender(MTGCard * card, const Pos& pos); virtual ostream& toString(ostream&) const; }; @@ -38,41 +38,15 @@ class CardView : public CardGui { MTGCardInstance* getCard(); // remove this when possible CardView(MTGCardInstance* card, float x, float y); CardView(MTGCardInstance* card, const Pos& ref); - virtual void Render(); + void Render(){CardGui::Render();}; void Render(JQuad* q){Pos::Render(q);}; - void RenderSelected(); - virtual void Update(float dt); virtual ostream& toString(ostream&) const; }; -class TransientCardView : public CardView { +class TransientCardView : public CardGui { public: TransientCardView(MTGCardInstance* card, float x, float y); TransientCardView(MTGCardInstance* card, const Pos& ref); - virtual void Render(); }; - -/* -class CardGui: public PlayGuiObject{ - protected: - hgeParticleSystem * mParticleSys; - int alpha; - float actX, actY; - public: - MTGCardInstance * card; - CardGui(int id, MTGCardInstance * _card, float desiredHeight, float _x=0, float _y=0, bool hasFocus = false); - virtual void Render(); - virtual void Update(float dt); - virtual ostream& toString(ostream& out) const; - - float Height(); - float Width(); - - void RenderBig(float x=-1, float y = -1, int alternate = 0); - - ~CardGui(); -}; -*/ - #endif diff --git a/projects/mtg/include/CardSelector.h b/projects/mtg/include/CardSelector.h index a4cefaff0..013e41df5 100644 --- a/projects/mtg/include/CardSelector.h +++ b/projects/mtg/include/CardSelector.h @@ -45,4 +45,9 @@ class ObjectSelector : public GuiLayer typedef ObjectSelector<> CardSelector; typedef LimitorFunctor Limitor; +struct Exp +{ + static inline bool test(CardSelector::Target*, CardSelector::Target*); +}; + #endif diff --git a/projects/mtg/include/GuiCombat.h b/projects/mtg/include/GuiCombat.h index dae91f286..f5a5a9d13 100644 --- a/projects/mtg/include/GuiCombat.h +++ b/projects/mtg/include/GuiCombat.h @@ -9,11 +9,21 @@ class GuiCombat : public GuiLayer { protected: - CardSelector* cs; + GameObserver* go; + TransientCardView* active, *activeAtk; + JQuad* ok_quad; + Pos ok; vector attackers; + TransientCardView* current; + enum { BLK, ATK, OK, NONE } cursor_pos; + + vector atkViews; + vector blkViews; + + void generateBlkViews(MTGCardInstance* card); public: - GuiCombat(CardSelector* cs); + GuiCombat(GameObserver* go); ~GuiCombat(); virtual void Update(float dt); virtual void Render(); diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index e16f1c1a9..3f93d0e17 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -69,7 +69,8 @@ class MTGCardInstance: public MTGCard, public Damageable { listblockers; int attacker; int toggleDefenser(MTGCardInstance * opponent); - int moveBlockerInRow(MTGCardInstance * blocker); + int raiseBlockerRankOrder(MTGCardInstance * blocker); + int bringBlockerToFrontOfOrder(MTGCardInstance * blocker); int toggleAttacker(); MTGCardInstance * banding; // If belongs to a band when attacking int canBlock(); diff --git a/projects/mtg/include/WEvent.h b/projects/mtg/include/WEvent.h index c8d542c52..62331f466 100644 --- a/projects/mtg/include/WEvent.h +++ b/projects/mtg/include/WEvent.h @@ -8,9 +8,9 @@ class Phase; class Targetable; class ManaPool; -class WEvent{ +class WEvent { public: - enum{ + enum { NOT_SPECIFIED = 0, CHANGE_ZONE = 1, DAMAGE = 2, @@ -21,7 +21,7 @@ public: virtual ~WEvent() {}; }; -struct WEventZoneChange: public WEvent{ +struct WEventZoneChange : public WEvent { MTGCardInstance * card; MTGGameZone * from; MTGGameZone * to; @@ -30,12 +30,12 @@ struct WEventZoneChange: public WEvent{ }; -struct WEventDamage: public WEvent{ +struct WEventDamage : public WEvent { Damage * damage; WEventDamage(Damage * damage); }; -struct WEventPhaseChange: public WEvent{ +struct WEventPhaseChange : public WEvent { Phase * from; Phase * to; WEventPhaseChange(Phase * from, Phase * to); @@ -43,13 +43,13 @@ struct WEventPhaseChange: public WEvent{ //Abstract class of event when a card's status changes -struct WEventCardUpdate: public WEvent{ +struct WEventCardUpdate : public WEvent { MTGCardInstance * card; WEventCardUpdate(MTGCardInstance * card); }; //Event when a card is tapped/untapped -struct WEventCardTap: public WEventCardUpdate{ +struct WEventCardTap : public WEventCardUpdate { bool before; bool after; WEventCardTap(MTGCardInstance * card, bool before, bool after); @@ -58,7 +58,7 @@ struct WEventCardTap: public WEventCardUpdate{ //Event when a card's "attacker" status changes //before:Player/Planeswalker that card was attacking previously //after: Player/Planeswalker that card is attacking now -struct WEventCreatureAttacker: public WEventCardUpdate{ +struct WEventCreatureAttacker : public WEventCardUpdate { Targetable * before; Targetable * after; WEventCreatureAttacker(MTGCardInstance * card, Targetable * from, Targetable * to); @@ -67,7 +67,7 @@ struct WEventCreatureAttacker: public WEventCardUpdate{ //Event when a card's "defenser" status changes //before : attacker that card was blocking previously //after: attacker that card is blocking now -struct WEventCreatureBlocker: public WEventCardUpdate{ +struct WEventCreatureBlocker : public WEventCardUpdate { MTGCardInstance * before; MTGCardInstance * after; WEventCreatureBlocker(MTGCardInstance * card,MTGCardInstance * from,MTGCardInstance * to); @@ -76,11 +76,14 @@ struct WEventCreatureBlocker: public WEventCardUpdate{ //Event when a blocker is reordered //exchangeWith: exchange card's position with exchangeWith's position //attacker:both card and exchangeWith *should* be in attacker's "blockers" list. -struct WEventCreatureBlockerRank: public WEventCardUpdate{ +struct WEventCreatureBlockerRank : public WEventCardUpdate { MTGCardInstance * exchangeWith; MTGCardInstance * attacker; WEventCreatureBlockerRank(MTGCardInstance * card,MTGCardInstance * exchangeWith, MTGCardInstance * attacker); +}; +//Event when blockers are assigned and need to be reordered +struct WEventBlockersAssigned : public WEvent { }; //Event when a mana is engaged diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index 139b97df2..f6e563943 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -24,13 +24,13 @@ CardView::CardView(MTGCardInstance* card, const Pos& ref) : CardGui(card, ref) { card->view = this; } -void CardView::Update(float dt) +void CardGui::Update(float dt) { PlayGuiObject::Update(dt); } -void CardView::Render() +void CardGui::Render() { JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MAIN_FONT); @@ -72,14 +72,14 @@ void CardView::Render() JQuad* q; // Draw the "unknown" card model switch(color) - { - case Constants::MTG_COLOR_GREEN: q = GameApp::CommonRes->GetQuad("green_thumb"); break; - case Constants::MTG_COLOR_BLUE : q = GameApp::CommonRes->GetQuad("blue_thumb"); break; - case Constants::MTG_COLOR_RED : q = GameApp::CommonRes->GetQuad("red_thumb"); break; - case Constants::MTG_COLOR_BLACK: q = GameApp::CommonRes->GetQuad("black_thumb"); break; - case Constants::MTG_COLOR_WHITE: q = GameApp::CommonRes->GetQuad("white_thumb"); break; - default: q = GameApp::CommonRes->GetQuad("black_thumb"); break; - } + { + case Constants::MTG_COLOR_GREEN: q = GameApp::CommonRes->GetQuad("green_thumb"); break; + case Constants::MTG_COLOR_BLUE : q = GameApp::CommonRes->GetQuad("blue_thumb"); break; + case Constants::MTG_COLOR_RED : q = GameApp::CommonRes->GetQuad("red_thumb"); break; + case Constants::MTG_COLOR_BLACK: q = GameApp::CommonRes->GetQuad("black_thumb"); break; + case Constants::MTG_COLOR_WHITE: q = GameApp::CommonRes->GetQuad("white_thumb"); break; + default: q = GameApp::CommonRes->GetQuad("black_thumb"); break; + } q->SetColor(ARGB(static_cast(actA),255,255,255)); renderer->RenderQuad(q, actX, actY, actT, scale, scale); } @@ -164,36 +164,36 @@ void CardGui::alternateRender(MTGCard * card, const Pos& pos){ float yOffset = -112; while ((h = manacost->getHybridCost(j))) { - float scale = pos.actZ * 0.05 * cosf(2*M_PI*((float)t)/256.0); - - if (scale < 0) - { - renderer->RenderQuad(manaIcons[h->color1], pos.actX + (-12 * j + 75 + 3 * sinf(2*M_PI*((float)t)/256.0))*pos.actZ, pos.actY + (yOffset + 3 * cosf(2*M_PI*((float)(t-35))/256.0))*pos.actZ, 0, 0.4 + scale, 0.4 + scale); - renderer->RenderQuad(manaIcons[h->color2], pos.actX + (-12 * j + 75 + 3 * sinf(2*M_PI*((float)v)/256.0))*pos.actZ, pos.actY + (yOffset + 3 * cosf(2*M_PI*((float)(v-35))/256.0))*pos.actZ, 0, 0.4 - scale, 0.4 - scale); - } - else - { - renderer->RenderQuad(manaIcons[h->color2], pos.actX + (- 12 * j + 75 + 3 * sinf(2*M_PI*((float)v)/256.0))*pos.actZ, pos.actY + (yOffset + 3 * cosf(2*M_PI*((float)(v-35))/256.0))*pos.actZ, 0, 0.4 - scale, 0.4 - scale); - renderer->RenderQuad(manaIcons[h->color1], pos.actX + (- 12 * j + 75 + 3 * sinf(2*M_PI*((float)t)/256.0))*pos.actZ, pos.actY + (yOffset + 3 * cosf(2*M_PI*((float)(t-35))/256.0))*pos.actZ, 0, 0.4 + scale, 0.4 + scale); - } - ++j; + float scale = pos.actZ * 0.05 * cosf(2*M_PI*((float)t)/256.0); + + if (scale < 0) + { + renderer->RenderQuad(manaIcons[h->color1], pos.actX + (-12 * j + 75 + 3 * sinf(2*M_PI*((float)t)/256.0))*pos.actZ, pos.actY + (yOffset + 3 * cosf(2*M_PI*((float)(t-35))/256.0))*pos.actZ, 0, 0.4 + scale, 0.4 + scale); + renderer->RenderQuad(manaIcons[h->color2], pos.actX + (-12 * j + 75 + 3 * sinf(2*M_PI*((float)v)/256.0))*pos.actZ, pos.actY + (yOffset + 3 * cosf(2*M_PI*((float)(v-35))/256.0))*pos.actZ, 0, 0.4 - scale, 0.4 - scale); + } + else + { + renderer->RenderQuad(manaIcons[h->color2], pos.actX + (- 12 * j + 75 + 3 * sinf(2*M_PI*((float)v)/256.0))*pos.actZ, pos.actY + (yOffset + 3 * cosf(2*M_PI*((float)(v-35))/256.0))*pos.actZ, 0, 0.4 - scale, 0.4 - scale); + renderer->RenderQuad(manaIcons[h->color1], pos.actX + (- 12 * j + 75 + 3 * sinf(2*M_PI*((float)t)/256.0))*pos.actZ, pos.actY + (yOffset + 3 * cosf(2*M_PI*((float)(t-35))/256.0))*pos.actZ, 0, 0.4 + scale, 0.4 + scale); + } + ++j; } for (int i = Constants::MTG_NB_COLORS - 2; i >= 1; --i) { - for (int cost = manacost->getCost(i); cost > 0; --cost) - { - renderer->RenderQuad(manaIcons[i], pos.actX + (-12*j + 75)*pos.actZ, pos.actY + (yOffset)*pos.actZ, 0, 0.4 * pos.actZ, 0.4 * pos.actZ); - ++j; - } + for (int cost = manacost->getCost(i); cost > 0; --cost) + { + renderer->RenderQuad(manaIcons[i], pos.actX + (-12*j + 75)*pos.actZ, pos.actY + (yOffset)*pos.actZ, 0, 0.4 * pos.actZ, 0.4 * pos.actZ); + ++j; + } } // Colorless mana if (int cost = manacost->getCost(0)) { - char buffer[10]; - sprintf(buffer, "%d", cost); - renderer->RenderQuad(manaIcons[0], pos.actX + (- 12*j + 75)*pos.actZ, pos.actY +(yOffset)*pos.actZ, 0, 0.4 * pos.actZ, 0.4 * pos.actZ); - float w = font->GetStringWidth(buffer); - font->DrawString(buffer, pos.actX +(- 12*j + 76 - w/2)*pos.actZ, pos.actY + (yOffset - 5)*pos.actZ); + char buffer[10]; + sprintf(buffer, "%d", cost); + renderer->RenderQuad(manaIcons[0], pos.actX + (- 12*j + 75)*pos.actZ, pos.actY +(yOffset)*pos.actZ, 0, 0.4 * pos.actZ, 0.4 * pos.actZ); + float w = font->GetStringWidth(buffer); + font->DrawString(buffer, pos.actX +(- 12*j + 76 - w/2)*pos.actZ, pos.actY + (yOffset - 5)*pos.actZ); } } @@ -202,8 +202,8 @@ void CardGui::alternateRender(MTGCard * card, const Pos& pos){ string s = ""; for (int i = card->nb_types - 1; i > 0; --i) { - s += _(Subtypes::subtypesList->find(card->types[i])); - s += " - "; + s += _(Subtypes::subtypesList->find(card->types[i])); + s += " - "; } s += _(Subtypes::subtypesList->find(card->types[0])); font->DrawString(s.c_str(), pos.actX + (22 - BigWidth / 2)*pos.actZ, pos.actY + (49 - BigHeight / 2)*pos.actZ); @@ -240,311 +240,14 @@ void CardGui::RenderBig(const Pos& pos){ MTGCardInstance* CardView::getCard() { return card; } -TransientCardView::TransientCardView(MTGCardInstance* card, float x, float y) : CardView(card, x, y){} -TransientCardView::TransientCardView(MTGCardInstance* card, const Pos& ref) : CardView(card, ref.actX, ref.actY) {}; -void TransientCardView::Render() -{ - CardView::Render(); -} - - -/* -void CardGui::alternateRender(MTGCard * card, JQuad ** manaIcons, float x, float y, float rotation, float scale){ - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MAGIC_FONT); - float backup = mFont->GetScale(); - JQuad * mIcons[7]; - if (!manaIcons){ - mIcons[Constants::MTG_COLOR_ARTIFACT] = GameApp::CommonRes->GetQuad("c_artifact"); - mIcons[Constants::MTG_COLOR_LAND] = GameApp::CommonRes->GetQuad("c_land"); - mIcons[Constants::MTG_COLOR_WHITE] = GameApp::CommonRes->GetQuad("c_white"); - mIcons[Constants::MTG_COLOR_RED] = GameApp::CommonRes->GetQuad("c_red"); - mIcons[Constants::MTG_COLOR_BLACK] = GameApp::CommonRes->GetQuad("c_black"); - mIcons[Constants::MTG_COLOR_BLUE] = GameApp::CommonRes->GetQuad("c_blue"); - mIcons[Constants::MTG_COLOR_GREEN] = GameApp::CommonRes->GetQuad("c_green"); - for (int i=0; i < 7; i++){ - mIcons[i]->SetHotSpot(16,16); - } - manaIcons = mIcons; - } - Vector2D v; - Vector2D points[4]; - PIXEL_TYPE bgcolor = ARGB(255,128,128,128); - PIXEL_TYPE bgcolor2 = ARGB(255,80,80,80); - char buf[25]; - int width = 200; - int height = 285; - - JRenderer * renderer = JRenderer::GetInstance(); - mFont->SetRotation(rotation); - mFont->SetScale(scale); - int color = card->getColor(); - - ManaCost * manacost = card->getManaCost(); - int nbicons = 0; - ManaCostHybrid * h; - - unsigned int j = 0; - while ((h = manacost->getHybridCost(j))){ - for (int i = 0; i < 2; i++){ - int color = h->color1; - int value = h->value1; - if (i) { - color = h->color2; - value = h->value2; - } - v.x = (width/2 - 24 - 16*nbicons + 8*i)*scale; - v.y = ((-height/2) + 16 + 8*i) * scale; - v.Rotate(rotation); - if (color == 0){ - sprintf(buf,"%i",value); - mFont->SetColor(ARGB(255,255,255,255)); - mFont->DrawString(buf,x+v.x,y+v.y); - }else{ - renderer->RenderQuad(manaIcons[color],x+v.x,y+v.y,rotation,0.4*scale, 0.4*scale); - } - } - nbicons++; - j++; - } - - for (int i = 1; i < Constants::MTG_NB_COLORS - 1; i++){ - - int cost = manacost->getCost(i); - for (int j=0; j < cost; j++){ - v.x = (width/2 - 20 - 16*nbicons)*scale; - v.y = ((-height/2) + 20) * scale; - v.Rotate(rotation); - renderer->RenderQuad(manaIcons[i],x+v.x,y+v.y,rotation,0.5*scale, 0.5*scale); - nbicons++; - } - } - int cost = manacost->getCost(0); - if (cost !=0){ - v.x = (width/2 - 20 - 16*nbicons)*scale; - v.y = ((-height/2) + 14) * scale; - v.Rotate(rotation); - sprintf(buf,"%i",cost); - mFont->SetColor(ARGB(255,255,255,255)); - mFont->DrawString(buf,x+v.x,y+v.y); - } - - - for (int i = card->nb_types-1; i>=0; i--){ - v.x = ((-width/2)+10) * scale; - v.y = (height/2-20 - 12 * i) * scale; - v.Rotate(rotation); - string s = Subtypes::subtypesList->find(card->types[i]); - mFont->DrawString(_(s).c_str(),x+v.x,y+v.y); - } - - mFont->SetScale(backup); -} - - -CardGui::CardGui(int id, MTGCardInstance * _card, float desiredHeight, float x, float y, bool hasFocus): PlayGuiObject(id, desiredHeight, x, y, hasFocus){ - LOG("==Creating NEW CardGui Object. CardName:"); - LOG(_card->getName()); - - actX = x; - actY = y; - - card = _card; - type = GUI_CARD; - - alpha = 255; - mParticleSys = NULL; - - if (card->hasColor(Constants::MTG_COLOR_RED)){ - mParticleSys = GameApp::Particles[3]; - }else if (card->hasColor(Constants::MTG_COLOR_BLUE)){ - mParticleSys = GameApp::Particles[1]; - }else if (card->hasColor(Constants::MTG_COLOR_GREEN)){ - mParticleSys = GameApp::Particles[2]; - }else if (card->hasColor(Constants::MTG_COLOR_BLACK)){ - mParticleSys = GameApp::Particles[4]; - }else if (card->hasColor(Constants::MTG_COLOR_WHITE)){ - mParticleSys = GameApp::Particles[0]; - }else{ - mParticleSys = GameApp::Particles[5]; - } - - LOG("==CardGui Object Creation Succesfull"); -} - - -void CardGui::Update(float dt){ - alpha = 255; - - if (card->changedZoneRecently > 0) alpha = 255.f - 255.f * card->changedZoneRecently; - if (mParticleSys && card->changedZoneRecently == 1.f){ - mParticleSys->MoveTo(actX + 15, actY + 2 * mHeight / 3); - mParticleSys->Fire(); - } - if (card->changedZoneRecently){ - if (mParticleSys) mParticleSys->Update(dt); - card->changedZoneRecently-= (5 *dt); - if (card->changedZoneRecently == 0) card->changedZoneRecently-= dt;//must not become zero atm - if (card->changedZoneRecently < 0){ - if (mParticleSys) mParticleSys->Stop(); - } - if (card->changedZoneRecently < -3){ - card->changedZoneRecently = 0; - mParticleSys = NULL; - } - } - - actX += 10 * dt * (x - actX); - actY += 10 * dt * (y - actY); - - PlayGuiObject::Update(dt); -} - - - if (alternate){ - MTGCard * mtgcard = card->model; - CardGui::alternateRender(mtgcard, NULL, xpos + 90 , ypos + 130, 0.0f,0.9f); - if (quad){ - float scale = 250 / quad->mHeight; - quad->SetColor(ARGB(40,255,255,255)); - renderer->RenderQuad(quad,xpos,ypos,0,scale,scale); - } - } -} - -void CardGui::Render(){ - - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MAIN_FONT); - - JRenderer * renderer = JRenderer::GetInstance(); - JQuad * quad = card->getThumb(); -#if defined (WIN32) || defined (LINUX) - //This shouldn't be done for the PSP. Basically it forces the system to load - // The big image if it cannot find the thumbnail. That's great for image quality on a PC, - // But it kills the performance for those who don't have thumbnails on the PSP - if (!quad || quad->mHeight * 2 < mHeight){ - JQuad * quad2 = card->getQuad(); - if (quad2) - quad = quad2; - } -#endif - float tap = (float)(card->isTapped()); - float rotation = M_PI_2 * tap; - float mScale = mHeight / 64; - float myW = 45 * mScale; - float myH = 60 * mScale; - GameObserver * game = GameObserver::GetInstance(); - TargetChooser * tc = NULL; - if (game) tc = game->getCurrentTargetChooser(); - float myX = actX + (32 * tap * mScale); - float myY = actY + (20 * tap * mScale); - if (quad){ - mScale = mHeight / quad->mHeight; - myH = mHeight; - myW = quad->mWidth * mScale; - myX = actX + (quad->mHeight/2 * tap * mScale); - myY = actY + (quad->mWidth/2 * tap * mScale); - } - - if (mHeight-defaultHeight){ - if (card->isTapped()) - renderer->FillRect(myX + 1 * (mHeight - defaultHeight) - myH, myY + 1 * (mHeight - defaultHeight), myH, myW, ARGB(128,0,0,0)); - else - renderer->FillRect(myX + 1 * (mHeight - defaultHeight), myY + 1 * (mHeight-defaultHeight), myW, myH, ARGB(128,0,0,0)); - } - - if(quad){ - quad->SetColor(ARGB(alpha, 255, 255, 255)); - - if (tc && !tc->canTarget(card)) quad->SetColor(ARGB(alpha, 50, 50, 50)); - renderer->RenderQuad(quad, myX, myY ,rotation, mScale, mScale); - quad->SetColor(ARGB(alpha, 255, 255, 255)); - }else{ - int color = card->getColor(); - - char buffer[200]; - sprintf(buffer, "%s",card->getName()); - mFont->SetColor(ARGB(255,Constants::_r[color],Constants::_g[color],Constants::_b[color])); - - JQuad * mIcon = NULL; - if (card->hasSubtype("plains")){ - mIcon = GameApp::CommonRes->GetQuad("c_white"); - }else if(card->hasSubtype("swamp")){ - mIcon = GameApp::CommonRes->GetQuad("c_black"); - }else if(card->hasSubtype("forest")){ - mIcon = GameApp::CommonRes->GetQuad("c_green"); - }else if(card->hasSubtype("mountain")){ - mIcon = GameApp::CommonRes->GetQuad("c_red"); - }else if(card->hasSubtype("island")){ - mIcon = GameApp::CommonRes->GetQuad("c_blue"); - } - if (mIcon) mIcon->SetHotSpot(16,16); - if (card->isTapped()){ - renderer->FillRect(myX - myH, myY, myH, myW, ARGB(255,Constants::_r[color]/2+50,Constants::_g[color]/2+50,Constants::_b[color]/2+50)); - renderer->DrawRect(myX - myH, myY, myH, myW, ARGB(255,Constants::_r[color],Constants::_g[color],Constants::_b[color])); - mFont->SetScale(DEFAULT_MAIN_FONT_SCALE * 0.8 * mScale); - mFont->DrawString(buffer, myX - (myH) + 4, myY + 1); - if (mIcon) renderer->RenderQuad(mIcon, myX - myH / 2,myY + myW / 2, M_PI_2, mScale, mScale); - if (tc && !tc->canTarget(card)) - renderer->FillRect(myX - myH, myY, myH, myW, ARGB(200,0,0,0)); - }else{ - renderer->FillRect(myX, myY , myW, myH, ARGB(255,Constants::_r[color]/2+50,Constants::_g[color]/2+50,Constants::_b[color]/2+50)); - renderer->DrawRect(myX, myY , myW, myH, ARGB(255,Constants::_r[color],Constants::_g[color],Constants::_b[color])); - mFont->SetScale(DEFAULT_MAIN_FONT_SCALE * 0.5 * mScale); - mFont->DrawString(buffer, myX + 4, myY + 1); - if (mIcon) renderer->RenderQuad(mIcon,myX + myW/2, myY + myH / 2, 0, mScale, mScale); - if (tc && !tc->canTarget(card)) - renderer->FillRect(myX, myY, myW, myH, ARGB(200,0,0,0)); - } - mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); - } - - if (tc && tc->alreadyHasTarget(card)){ - if (card->isTapped()) - renderer->FillRect(myX - myH, myY, myH, myW, ARGB(128,255,0,0)); - else - renderer->FillRect(myX, myY, myW, myH, ARGB(128,255,0,0)); - } - - if (card->isCreature()){ - mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); - char buffer[200]; - sprintf(buffer, "%i/%i",card->power,card->life); - renderer->FillRect(actX + 2, actY + mHeight - 12, 25, 12, ARGB(128,0,0,0)); - mFont->SetColor(ARGB(255,255,255,255)); - mFont->DrawString(buffer, actX + 4, actY + mHeight - 10); - } - - if (mParticleSys && card->changedZoneRecently > 0){ - renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE); - mParticleSys->Render(); - // set normal blending - renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); - } - - PlayGuiObject::Render(); -} - -float CardGui::Height() -{ - return card->getQuad()->mHeight; -} -float CardGui::Width() -{ - return card->getQuad()->mWidth; -} - -CardGui::~CardGui(){ - LOG("==Destroying CardGui object"); - LOG(this->card->getName()); - LOG("==CardGui object destruction Successful"); -} -*/ +TransientCardView::TransientCardView(MTGCardInstance* card, float x, float y) : CardGui(card, x, y){} +TransientCardView::TransientCardView(MTGCardInstance* card, const Pos& ref) : CardGui(card, ref) {}; ostream& CardView::toString(ostream& out) const { return (CardGui::toString(out) << " : CardView ::: card : " << card - << "; actX,actY : " << actX << "," << actY << "; t : " << t - << " ; actT : " << actT << " ; quad : " << quad); + << "; actX,actY : " << actX << "," << actY << "; t : " << t + << " ; actT : " << actT << " ; quad : " << quad); } ostream& CardGui::toString(ostream& out) const { diff --git a/projects/mtg/src/CardSelector.cpp b/projects/mtg/src/CardSelector.cpp index 52a09f79d..47350f73b 100644 --- a/projects/mtg/src/CardSelector.cpp +++ b/projects/mtg/src/CardSelector.cpp @@ -3,35 +3,22 @@ #include "../include/CardGui.h" #include "../include/CardSelector.h" #include "../include/GuiHand.h" +#include "Closest.cpp" using std::cout; -#define closest(src, expr) \ - { \ - float curdist = 1000000.0f; /* This is bigger than any possible distance */ \ - for (vector::iterator it = cards.begin(); it != cards.end(); ++it) \ - { \ - if (!(expr)) continue; \ - if ((*it)->actA < 32) continue; \ - if ((NULL != limitor) && (!limitor->select(*it))) continue; \ - if (active) \ - { \ - float dist = ((*it)->x - active->x) * ((*it)->x - active->x) + \ - ((*it)->y - active->y) * ((*it)->y - active->y); \ - if (dist < curdist) \ - { \ - curdist = dist; \ - card = *it; \ - } \ - } \ - else \ - card = *it; \ - } \ -{ CardView* c = dynamic_cast(active); if (c) c->zoom = 1.0; } \ -active = card; \ -{ CardView* c = dynamic_cast(active); if (c) c->zoom = 1.4; } \ -} - +struct Left : public Exp { static inline bool test(CardSelector::Target* ref, CardSelector::Target* test) + { return ref->x - test->x > fabs(ref->y - test->y); } }; +struct Right : public Exp { static inline bool test(CardSelector::Target* ref, CardSelector::Target* test) + { return test->x - ref->x > fabs(ref->y - test->y); } }; +struct Up : public Exp { static inline bool test(CardSelector::Target* ref, CardSelector::Target* test) + { return ref->y - test->y > fabs(ref->x - test->x); } }; +struct Down : public Exp { static inline bool test(CardSelector::Target* ref, CardSelector::Target* test) + { return test->y - ref->y > fabs(ref->x - test->x); } }; +struct Diff : public Exp { static inline bool test(CardSelector::Target* ref, CardSelector::Target* test) + { return ref != test; } }; +struct True : public Exp { static inline bool test(CardSelector::Target* ref, CardSelector::Target* test) + { return true; } }; template<> CardSelector::ObjectSelector(DuelLayers* duel) : active(NULL), showBig(true), duel(duel), limitor(NULL), bigpos(300, 150, 1.0, 0.0, 220) {} @@ -58,7 +45,7 @@ void CardSelector::Remove(CardSelector::Target* card) if (active == *it) { CardView* c = dynamic_cast(active); if (c) c->zoom = 1.0; - closest(active, active != (*it)); + active = closest(cards, limitor, active); c = dynamic_cast(active); if (c) c->zoom = 1.4; } if (active == *it) active = NULL; @@ -83,35 +70,23 @@ bool CardSelector::CheckUserInput(u32 key) return true; } Target* oldactive = active; - Target* card = active; switch (key) { case PSP_CTRL_CIRCLE: GameObserver::GetInstance()->ButtonPressed(active); + return true; break; case PSP_CTRL_LEFT: - closest(active, ( - active->x - (*it)->x > fabs(active->y - (*it)->y) - )); - if (active != oldactive) { oldactive->Leaving(key); active->Entering(); } + active = closest(cards, limitor, active); break; case PSP_CTRL_RIGHT: - closest(active, ( - (*it)->x - active->x > fabs(active->y - (*it)->y) - )); - if (active != oldactive) { oldactive->Leaving(key); active->Entering(); } + active = closest(cards, limitor, active); break; case PSP_CTRL_UP: - closest(active, ( - active->y - (*it)->y > fabs(active->x - (*it)->x) - )); - if (active != oldactive) { oldactive->Leaving(key); active->Entering(); } + active = closest(cards, limitor, active); break; case PSP_CTRL_DOWN: - closest(active, ( - (*it)->y - active->y > fabs(active->x - (*it)->x) - )); - if (active != oldactive) { oldactive->Leaving(key); active->Entering(); } + active = closest(cards, limitor, active); break; case PSP_CTRL_LTRIGGER: showBig = !showBig; @@ -119,6 +94,7 @@ bool CardSelector::CheckUserInput(u32 key) default: return false; } + if (active != oldactive) { oldactive->Leaving(key); active->Entering(); } return true; } @@ -153,8 +129,7 @@ void CardSelector::Limit(LimitorFunctor* limitor) this->limitor = limitor; if (limitor && !limitor->select(active)) { - Target* card = NULL; - closest(active, true); + active = closest(cards, limitor, active); if (limitor && !limitor->select(active)) active = NULL; } } diff --git a/projects/mtg/src/DamageResolverLayer.cpp b/projects/mtg/src/DamageResolverLayer.cpp index 11fcec5c8..c8400d6c3 100644 --- a/projects/mtg/src/DamageResolverLayer.cpp +++ b/projects/mtg/src/DamageResolverLayer.cpp @@ -359,7 +359,7 @@ bool DamageResolverLayer::blockersOrderingDone(){ bool DamageResolverLayer::clickReorderBlocker(MTGCardInstance * blocker){ if (!blocker->defenser) return false; MTGCardInstance * attacker = blocker->defenser; - attacker->moveBlockerInRow(blocker); + attacker->raiseBlockerRankOrder(blocker); list::iterator it; return true; } diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index 5c9d047fb..e1680726a 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -30,7 +30,7 @@ void DuelLayers::init(){ Add(NEW GuiMana()); Add(stack = NEW ActionStack(go)); - Add(combat = NEW GuiCombat(cs)); + Add(combat = NEW GuiCombat(go)); Add(action); Add(cs); Add(hand = NEW GuiHandSelf(cs, go->players[0]->game->hand)); @@ -49,7 +49,7 @@ void DuelLayers::CheckUserInput(int isAI){ if ((!isAI) && (0 != key)) { if (stack->CheckUserInput(key)) break; - // if (combat->CheckUserInput(key)) break; + if (combat->CheckUserInput(key)) break; if (action->CheckUserInput(key)) break; if (hand->CheckUserInput(key)) break; if (cs->CheckUserInput(key)) break; diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index c203f7a0c..4e56436ac 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -88,6 +88,7 @@ void GameObserver::nextGamePhase(){ Phase * cPhaseOld = phaseRing->getCurrentPhase(); if (!blockersSorted && cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS){ blockersAssigned = 1; + receiveEvent(NEW WEventBlockersAssigned()); /* if (!mLayers->combatLayer()->autoOrderBlockers()){ OutputDebugString("Player has To choose ordering!"); @@ -155,6 +156,7 @@ void GameObserver::userRequestNextGamePhase(){ Phase * cPhaseOld = phaseRing->getCurrentPhase(); if (!blockersSorted && cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS){ blockersAssigned = 1; + receiveEvent(NEW WEventBlockersAssigned()); /* if (!mLayers->combatLayer()->autoOrderBlockers()){ OutputDebugString("Player has To choose ordering!"); diff --git a/projects/mtg/src/GameOptions.cpp b/projects/mtg/src/GameOptions.cpp index 6114176ca..a28dfa700 100644 --- a/projects/mtg/src/GameOptions.cpp +++ b/projects/mtg/src/GameOptions.cpp @@ -397,4 +397,4 @@ string GameSettings::keypadFinish(){ void GameSettings::keypadShutdown(){ SAFE_DELETE(keypad); -} \ No newline at end of file +} diff --git a/projects/mtg/src/GuiCombat.cpp b/projects/mtg/src/GuiCombat.cpp index 069ebefba..71ce9d6e5 100644 --- a/projects/mtg/src/GuiCombat.cpp +++ b/projects/mtg/src/GuiCombat.cpp @@ -1,9 +1,26 @@ #include "../include/config.h" #include "../include/GameApp.h" #include "../include/GuiCombat.h" +#include "Closest.cpp" -GuiCombat::GuiCombat(CardSelector* cs) : GuiLayer(), cs(cs) +static const float MARGIN = 70; + + +struct Left : public Exp { static inline bool test(CardSelector::Target* ref, CardSelector::Target* test) + { return ref->y == test->y && ref->x > test->x; } }; +struct Right : public Exp { static inline bool test(CardSelector::Target* ref, CardSelector::Target* test) + { return ref->y == test->y && ref->x < test->x; } }; + + +GuiCombat::GuiCombat(GameObserver* go) : GuiLayer(), go(go), active(false), ok(SCREEN_WIDTH - MARGIN, 210, 1, 0, 255), cursor_pos(NONE) { + if (!GameApp::CommonRes->GetTexture("Ok.png")) + { + GameApp::CommonRes->CreateTexture("Ok.png"); + GameApp::CommonRes->CreateQuad("OK", "Ok.png", 0, 0, 56, 45); + } + ok_quad = GameApp::CommonRes->GetQuad("OK"); + ok_quad->SetHotSpot(28, 22); } GuiCombat::~GuiCombat() @@ -12,15 +29,112 @@ GuiCombat::~GuiCombat() void GuiCombat::Update(float dt) { + if (NONE != cursor_pos) + { + for (vector::iterator it = atkViews.begin(); it != atkViews.end(); ++it) + (*it)->Update(dt); + for (vector::iterator it = blkViews.begin(); it != blkViews.end(); ++it) + (*it)->Update(dt); + ok.Update(dt); + } +} + +void GuiCombat::generateBlkViews(MTGCardInstance* card) +{ + for (vector::iterator it = blkViews.begin(); it != blkViews.end(); ++it) + SAFE_DELETE(*it); + blkViews.clear(); + if (card && card->blockers.size() > 0) + { + float space = (SCREEN_WIDTH - 2*MARGIN) / card->blockers.size(); + float pos = MARGIN; + for (list::iterator it = card->blockers.begin(); it != card->blockers.end(); ++it) + { + TransientCardView* t = NEW TransientCardView(*it, 20, 60); + blkViews.push_back(t); + t->x = pos; t->y = 60; + t->zoom = 2.2; t->t = 0; + pos += space; + } + } } bool GuiCombat::CheckUserInput(u32 key) { + if (NONE == cursor_pos) return false; + TransientCardView* oldActive = active; + switch (key) + { + case PSP_CTRL_CIRCLE: + if (BLK == cursor_pos) + activeAtk->card->raiseBlockerRankOrder(active->card); + else if (OK == cursor_pos) { cursor_pos = NONE; go->userRequestNextGamePhase(); }; + break; + case PSP_CTRL_UP: + if (ATK == cursor_pos) + { + activeAtk = active; + active = blkViews.front(); + active->zoom = 2.7; + cursor_pos = BLK; + } + return true; + case PSP_CTRL_DOWN: + if (BLK == cursor_pos) + { + oldActive->zoom = 2.2; + active = activeAtk; + cursor_pos = ATK; + } + return true; + case PSP_CTRL_LEFT: + switch (cursor_pos) + { + case NONE : break; + case OK : active = atkViews.back(); cursor_pos = ATK; break; + case ATK : active = closest(atkViews, NULL, active); break; + case BLK : active = closest(blkViews, NULL, active); break; + } + break; + case PSP_CTRL_RIGHT: + switch (cursor_pos) + { + case NONE : + case OK : break; + case BLK : active = closest(blkViews, NULL, active); break; + case ATK : active = closest(atkViews, NULL, active); + if (active == oldActive) { active = NULL; cursor_pos = OK; } + break; + } + break; + case PSP_CTRL_SQUARE: + case PSP_CTRL_RTRIGGER: + active = NULL; cursor_pos = OK; + break; + } + if (oldActive != active) + { + if (oldActive) oldActive->zoom = 2.2; + if (active) active->zoom = 2.7; + if (ATK == cursor_pos) generateBlkViews(active->card); + } + if (OK == cursor_pos) ok.zoom = 1.5; else ok.zoom = 1.0; return true; } void GuiCombat::Render() { + if (NONE == cursor_pos) return; + JRenderer* renderer = JRenderer::GetInstance(); + renderer->FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, ARGB(200,0,0,0)); + + for (vector::iterator it = atkViews.begin(); it != atkViews.end(); ++it) + (*it)->Render(); + for (vector::iterator it = blkViews.begin(); it != blkViews.end(); ++it) + (*it)->Render(); + ok.Render(ok_quad); + + renderer->DrawLine(0, SCREEN_HEIGHT / 2 + 10, SCREEN_WIDTH, SCREEN_HEIGHT / 2 + 10, ARGB(255, 255, 64, 0)); } int GuiCombat::receiveEventPlus(WEvent* e) @@ -28,19 +142,25 @@ int GuiCombat::receiveEventPlus(WEvent* e) if (WEventCreatureAttacker* event = dynamic_cast(e)) { if (NULL == event->after) return 0; - cout << "Attacker : " << event->card->name << event->before << " -> " << event->after << endl; + cout << "Attacker : " << event->card->name << " " << event->before << " -> " << event->after << endl; attackers.push_back(event->card); return 1; } else if (WEventCreatureBlocker* event = dynamic_cast(e)) { + cout << "Blocker : " << event->card->name << " " << event->before << " -> " << event->after << endl; if (NULL == event->after) return 0; - cout << "Blocker : " << event->card->name << event->before << " -> " << event->after << endl; return 1; } else if (WEventCreatureBlockerRank* event = dynamic_cast(e)) { - cout << "Order : " << event->card->name << event->exchangeWith << " -> " << event->attacker << endl; + cout << "Order : " << event->card->name << " -> " << event->exchangeWith->name << endl; + vector::iterator it1, it2; + for (it1 = blkViews.begin(); it1 != blkViews.end(); ++it1) if ((*it1)->card == event->card) break; if (blkViews.end() == it1) return 1; + for (it2 = blkViews.begin(); it2 != blkViews.end(); ++it2) if ((*it2)->card == event->exchangeWith) break; if (blkViews.end() == it2) return 1; + float x = (*it1)->x; + (*it1)->x = (*it2)->x; + (*it2)->x = x; return 1; } return 0; @@ -51,10 +171,36 @@ int GuiCombat::receiveEventMinus(WEvent* e) if (WEventCreatureAttacker* event = dynamic_cast(e)) { if (NULL == event->before) return 0; - vector::iterator it = find(attackers.begin(), attackers.end(), event->card); - if (it != attackers.end()) - attackers.erase(it); + for (vector::iterator it = attackers.begin(); it != attackers.end(); ++it) + if (*it == event->card) + { + attackers.erase(it); + return 1; + } return 1; } + else if (WEventBlockersAssigned* event = dynamic_cast(e)) + { + if (active) return 0; // Why do I take this event twice >.> + unsigned size = 0; + for (vector::iterator it = attackers.begin(); it != attackers.end(); ++it) + if (1 < (*it)->blockers.size()) ++size; + if (0 == size) return 1; + float space = (SCREEN_WIDTH - 2*MARGIN) / size; + float pos = MARGIN; + for (vector::iterator it = attackers.begin(); it != attackers.end(); ++it) + if (1 < (*it)->blockers.size()) + { + TransientCardView* t = NEW TransientCardView(*it, *(*it)->view); + atkViews.push_back(t); + t->x = pos; t->y = 210; + t->zoom = 2.2; t->t = 0; + pos += space; + } + active = *atkViews.begin(); + active->zoom = 2.7; + generateBlkViews(active->card); + cursor_pos = ATK; + } return 0; } diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 523350dd4..9cd44e0b0 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -466,19 +466,31 @@ MTGCardInstance * MTGCardInstance::getNextDefenser(MTGCardInstance * previous){ return NULL; } -int MTGCardInstance::moveBlockerInRow(MTGCardInstance * blocker){ +int MTGCardInstance::raiseBlockerRankOrder(MTGCardInstance * blocker){ list::iterator it1 = find(blockers.begin(), blockers.end(), blocker); list::iterator it2 = it1; - if (it2 == blockers.end()) it2 = blockers.begin(); else ++it2; - if (it2 == blockers.end()) it2 = blockers.begin(); + if (blockers.begin() == it2) ++it2; else --it2; std::iter_swap(it1,it2); - WEvent* e = NEW WEventCreatureBlockerRank(blocker,*it2,this); + WEvent* e = NEW WEventCreatureBlockerRank(*it1,*it2,this); GameObserver::GetInstance()->receiveEvent(e); //delete(e); return 1; } +int MTGCardInstance::bringBlockerToFrontOfOrder(MTGCardInstance * blocker){ + list::iterator it1 = find(blockers.begin(), blockers.end(), blocker); + list::iterator it2 = blockers.begin(); + if (it2 != it1) + { + std::iter_swap(it1,it2); + WEvent* e = NEW WEventCreatureBlockerRank(blocker,*it2,this); + GameObserver::GetInstance()->receiveEvent(e); + //delete(e); + } + return 1; +} + //Returns opponents to this card for this turn. This * should * take into account banding MTGCardInstance * MTGCardInstance::getNextOpponent(MTGCardInstance * previous){ GameObserver * game = GameObserver::GetInstance();