diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 0f7f8133b..9bd88df8e 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -1493,7 +1493,7 @@ subtype=Ajani [/card] [card] name=Avatar Token -auto=controllerlife/controllerlife cdaactive +auto=lifetotal/lifetotal cdaactive type=Creature subtype=Avatar power=* @@ -86572,7 +86572,7 @@ toughness=1 [/card] [card] name=Serra Avatar -auto=controllerlife/controllerlife cdaactive +auto=lifetotal/lifetotal cdaactive autograveyard=moveTo(ownerlibrary) && shuffle text=Serra Avatar's power and toughness are each equal to your life total. -- When Serra Avatar is put into a graveyard from anywhere, shuffle it into its owner's library. mana={4}{W}{W}{W} @@ -101404,8 +101404,7 @@ toughness=3 [card] name=Thopter Assembly abilities=flying -auto=@each my upkeep restriction{type(other thopter|myBattlefield)~lessthan~1}:token(Thopter,Artifact Creature,1/1,flying)*5 -auto=@each my upkeep restriction{type(other thopter|myBattlefield)~lessthan~1}:moveTo(ownerhand) +auto=@each my upkeep restriction{type(other thopter|myBattlefield)~lessthan~1}:moveTo(ownerhand) and!(token(Thopter,Artifact Creature,1/1,flying)*5)! text=Flying -- At the beginning of your upkeep, if you control no Thopters other than Thopter Assembly, return Thopter Assembly to its owner's hand and put five 1/1 colorless Thopter artifact creature tokens with flying onto the battlefield. mana={6} type=Artifact Creature @@ -102240,9 +102239,7 @@ type=Instant [card] name=Thunderbreak Regent abilities=flying -auto=@targeted(dragon|mybattlefield) from(*|opponentbattlefield):damage:3 opponent -auto=@targeted(dragon|mybattlefield) from(*|opponenthand):damage:3 opponent -auto=@targeted(dragon|mybattlefield) from(*|graveyard):damage:3 opponent +auto=@targeted(dragon|mybattlefield) from(*|opponentbattlefield,opponenthand,opponentstack,opponentgraveyard,opponentexile,opponentlibrary):damage:3 opponent text=Flying -- Whenever a Dragon you control becomes the target of a spell or ability an opponent controls, Thunderbreak Regent deals 3 damage to that player. mana={2}{R}{R} type=Creature @@ -103406,11 +103403,11 @@ power=6 toughness=4 [/card] ###The 2 cards above should stay together (Flip Card)### +#need parser from stack [card] name=Tormented Hero auto=tap -auto=@targeted(this) from(*[instant;sorcery;enchantment]|myhand,mygraveyard):life:-1 opponent -auto=@targeted(this) from(*[instant;sorcery;enchantment]|myhand,mygraveyard):life:1 controller +auto=@targeted(this) from(*|nonbattlezone):life:-1 opponent && life:1 controller text=Tormented Hero enters the battlefield tapped. -- Heroic - Whenever you cast a spell that targets Tormented Hero, each opponent loses 1 life. You gain life equal to the life lost this way. mana={B} type=Creature @@ -104162,8 +104159,7 @@ type=Land [card] name=Transcendence abilities=cantlifelose -auto=this(controllerlife > 19) winGame opponent -auto=@lifed(controller):this(controllerlife > 19) winGame opponent +auto=this(controllerlife > 19)while winGame opponent auto=@damaged(controller):life:twicethatmuch controller auto=@lifeloss(controller):life:twicethatmuch controller text=You don't lose the game for having 0 or less life. -- When you have 20 or more life, you lose the game. -- Whenever you lose life, you gain 2 life for each 1 life you lost. (Damage dealt to you causes you to lose life.) diff --git a/projects/mtg/include/CardGui.h b/projects/mtg/include/CardGui.h index 1957a5505..4ef10700b 100644 --- a/projects/mtg/include/CardGui.h +++ b/projects/mtg/include/CardGui.h @@ -33,7 +33,7 @@ protected: /* ** Tries to render the Big version of a card picture, backups to text version in case of failure */ - static void RenderBig(MTGCard * card, const Pos& pos, bool thumb = false); + static void RenderBig(MTGCard * card, const Pos& pos, bool thumb = false, bool noborder = false); static void RenderCountersBig(MTGCard * card, const Pos& pos, int drawMode = DrawMode::kNormal); static void AlternateRender(MTGCard * card, const Pos& pos); @@ -55,8 +55,8 @@ public: virtual void Render(); virtual void Update(float dt); - void DrawCard(const Pos& inPosition, int inMode = DrawMode::kNormal, bool thumb = false); - static void DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode = DrawMode::kNormal, bool thumb = false); + void DrawCard(const Pos& inPosition, int inMode = DrawMode::kNormal, bool thumb = false, bool noborder = false); + static void DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode = DrawMode::kNormal, bool thumb = false, bool noborder = false); static JQuadPtr AlternateThumbQuad(MTGCard * card); virtual ostream& toString(ostream&) const; diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 27faf0c1c..5146b4940 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -249,6 +249,10 @@ public: int copiedID; int modifiedbAbi; bool StackIsEmptyandSorcerySpeed(); + bool isTargetted(); + int cardistargetted; + bool isTargetter(); + int cardistargetter; void eventattacked(); void eventattackedAlone(); diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 24b15752a..7093c2271 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -1219,9 +1219,12 @@ void ActionStack::Render() mFont->SetColor(ARGB(255,255,255,255)); JRenderer * renderer = JRenderer::GetInstance(); - renderer->FillRoundRect(x0 + 16, y0 + 16, width + 2, height + 2, 10, ARGB(128,0,0,0)); - renderer->FillRoundRect(x0 - 5, y0, width + 2, height + 2, 10, ARGB(200,0,0,0)); - renderer->DrawRoundRect(x0 - 5, y0, width + 2, height + 2, 10, ARGB(255,255,255,255)); + //stack shadow + renderer->FillRoundRect(x0 - 7, y0+2, width + 17, height + 2, 9.0f, ARGB(128,0,0,0)); + //stack fill + renderer->FillRoundRect(x0 - 7, y0+2, width + 17, height + 2, 9.0f, ARGB(200,10,10,10)); + //stack border + renderer->DrawRoundRect(x0 - 7, y0+2, width + 17, height + 2, 9.0f, ARGB(160,240,240,240)); std::ostringstream stream; // WALDORF - changed "interrupt ?" to "Interrupt?". Don't display count down diff --git a/projects/mtg/src/CardDisplay.cpp b/projects/mtg/src/CardDisplay.cpp index 38cf35913..13c9f2fcd 100644 --- a/projects/mtg/src/CardDisplay.cpp +++ b/projects/mtg/src/CardDisplay.cpp @@ -267,7 +267,7 @@ void CardDisplay::Render() int drawMode = DrawMode::kNormal; if (observer) { - pos.actY = 150; + pos.actY = 145; if (x < (CardGui::BigWidth / 2)) pos.actX = SCREEN_WIDTH - 10 - CardGui::BigWidth / 2; drawMode = observer->getCardSelector()->GetDrawMode(); } diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index a114df329..2b57a7746 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -111,17 +111,17 @@ void CardGui::Update(float dt) PlayGuiObject::Update(dt); } -void CardGui::DrawCard(const Pos& inPosition, int inMode, bool thumb) +void CardGui::DrawCard(const Pos& inPosition, int inMode, bool thumb, bool noborder) { - DrawCard(card, inPosition, inMode, thumb); + DrawCard(card, inPosition, inMode, thumb, noborder); } -void CardGui::DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode, bool thumb) +void CardGui::DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode, bool thumb, bool noborder) { switch (inMode) { case DrawMode::kNormal: - RenderBig(inCard, inPosition, thumb); + RenderBig(inCard, inPosition, thumb, noborder); break; case DrawMode::kText: AlternateRender(inCard, inPosition); @@ -237,6 +237,30 @@ void CardGui::Render() if (quad) { quad->SetColor(ARGB(static_cast(actA),255,255,255)); + //static border + /*if(card->isTapped()) + { + //focus? + CardView* cv = dynamic_cast(card->view); + if(cv->mHasFocus) + renderer->FillRoundRect(actX - (scale * quad->mWidth / 2)-9.0f,actY - (scale * quad->mHeight / 2)+7, (scale * quad->mHeight)-0.02f, (scale * quad->mWidth)-0.02f, 1.0f,ARGB(250,20,20,20)); + else + renderer->FillRoundRect(actX - (scale * quad->mWidth / 2)-7,actY - (scale * quad->mHeight / 2)+5.5f, (scale * quad->mHeight)-0.02f, (scale * quad->mWidth)-0.02f, 1.0f,ARGB(250,20,20,20)); + } + else + { + renderer->FillRoundRect(actX - (scale * quad->mWidth / 2)-1,actY - (scale * quad->mHeight / 2)-1, (scale * quad->mWidth)-0.02f, (scale * quad->mHeight)-0.02f, 1.0f,ARGB(250,20,20,20)); + }*///the border needs animation when the card rotates...but how? + + //fake border... + JQuadPtr fakeborder; + fakeborder = game? game->getResourceManager()->GetQuad("white"):WResourceManager::Instance()->GetQuad("white"); + if(fakeborder) + { + fakeborder->SetColor(ARGB(255,15,15,15)); + renderer->RenderQuad(fakeborder.get(), actX, actY, actT, (29 * actZ + 1) / 16, 42 * actZ / 16); + } + //draw the card image renderer->RenderQuad(quad.get(), actX, actY, actT, scale, scale); } @@ -277,6 +301,40 @@ void CardGui::Render() } } + //draw border?line + if (card && card->isTargetted()) + { + if(card->isTapped()) + { + //focus? + CardView* cv = dynamic_cast(card->view); + if(cv->mHasFocus) + renderer->DrawRoundRect(actX - (scale * quad->mWidth / 2)-10,actY - (scale * quad->mHeight / 2)+6.5f, (scale * quad->mHeight)-0.02f, (scale * quad->mWidth)-0.02f, 1.8f,ARGB(250,255,0,0)); + else + renderer->DrawRoundRect(actX - (scale * quad->mWidth / 2)-8,actY - (scale * quad->mHeight / 2)+4, (scale * quad->mHeight)-0.02f, (scale * quad->mWidth)-0.02f, 1.8f,ARGB(250,255,0,0)); + } + else + { + renderer->DrawRoundRect(actX - (scale * quad->mWidth / 2)-2,actY - (scale * quad->mHeight / 2)-2, (scale * quad->mWidth)-0.02f, (scale * quad->mHeight)-0.02f, 1.8f,ARGB(250,255,0,0)); + } + } + if (card && card->isTargetter()) + { + if(card->isTapped()) + { + //focus? + CardView* cv = dynamic_cast(card->view); + if(cv->mHasFocus) + renderer->DrawRoundRect(actX - (scale * quad->mWidth / 2)-10,actY - (scale * quad->mHeight / 2)+6.5f, (scale * quad->mHeight)-0.02f, (scale * quad->mWidth)-0.02f, 1.8f,ARGB(250,0,255,0)); + else + renderer->DrawRoundRect(actX - (scale * quad->mWidth / 2)-8,actY - (scale * quad->mHeight / 2)+4, (scale * quad->mHeight)-0.02f, (scale * quad->mWidth)-0.02f, 1.8f,ARGB(250,0,255,0)); + } + else + { + renderer->DrawRoundRect(actX - (scale * quad->mWidth / 2)-2,actY - (scale * quad->mHeight / 2)-2, (scale * quad->mWidth)-0.02f, (scale * quad->mHeight)-0.02f, 1.8f,ARGB(250,0,255,0)); + } + } + //draws the numbers power/toughness if (card->isCreature()) { @@ -988,7 +1046,7 @@ void CardGui::TinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad) } //Renders a big card on screen. Defaults to the "alternate" rendering if no image is found -void CardGui::RenderBig(MTGCard* card, const Pos& pos, bool thumb) +void CardGui::RenderBig(MTGCard* card, const Pos& pos, bool thumb, bool noborder) { JRenderer * renderer = JRenderer::GetInstance(); //GameObserver * game = GameObserver::GetInstance(); @@ -1013,7 +1071,30 @@ void CardGui::RenderBig(MTGCard* card, const Pos& pos, bool thumb) } 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); + //init setname + string cardsetname = setlist[card->setId].c_str(); + if(!noborder) + { + if(cardsetname == "2ED"||cardsetname == "RV"||cardsetname == "4ED"||cardsetname == "5ED"||cardsetname == "6ED"||cardsetname == "7ED"||cardsetname == "8ED"||cardsetname == "9ED"||cardsetname == "CHR") + { + //like white border + renderer->FillRoundRect(x-92,pos.actY-128, (scale * quad->mWidth)-10, (scale * quad->mHeight)-11, 9.0f,ARGB(255,248,248,255)); + //black thin line to simulate card edge + renderer->DrawRoundRect(x-92,pos.actY-128, (scale * quad->mWidth)-10, (scale * quad->mHeight)-11, 9.0f,ARGB(150,20,20,20)); + } + else + { + //like black border + renderer->FillRoundRect(x-92,pos.actY-128, (scale * quad->mWidth)-10, (scale * quad->mHeight)-11, 9.0f,ARGB(255,10,10,10)); + //white thin line to simulate card edge + renderer->DrawRoundRect(x-92,pos.actY-128, (scale * quad->mWidth)-10, (scale * quad->mHeight)-11, 9.0f,ARGB(50,240,240,240)); + } + //render card image + renderer->RenderQuad(quad.get(), x, pos.actY, pos.actT, scale-0.02f, scale-0.02f); + } + else + renderer->RenderQuad(quad.get(), x, pos.actY, pos.actT, scale, scale); + RenderCountersBig(card, pos); return; } diff --git a/projects/mtg/src/CardSelector.cpp b/projects/mtg/src/CardSelector.cpp index ce94a404c..3a7de16a7 100644 --- a/projects/mtg/src/CardSelector.cpp +++ b/projects/mtg/src/CardSelector.cpp @@ -176,7 +176,7 @@ bool CardSelector::CheckUserInput(JButton key) return true; } Target* oldactive = active; - timer = 250; + timer = 800; int x,y; JGE* jge = observer->getInput(); if(!jge) return false; @@ -306,7 +306,7 @@ switch_active: } else { - timer = 250; + timer = 800; } return true; } diff --git a/projects/mtg/src/DeckView.cpp b/projects/mtg/src/DeckView.cpp index 682b75957..394a9322c 100644 --- a/projects/mtg/src/DeckView.cpp +++ b/projects/mtg/src/DeckView.cpp @@ -133,13 +133,13 @@ void DeckView::renderCard(int index, int alpha, bool asThumbnail) else { Pos pos = Pos(cardPosition.x, cardPosition.y, cardPosition.scale * 285 / 250, 0.0, 255); - CardGui::DrawCard(cardPosition.card, pos, asThumbnail); + CardGui::DrawCard(cardPosition.card, pos, asThumbnail, true); } } else { Pos pos = Pos(cardPosition.x, cardPosition.y, cardPosition.scale * 285 / 250, 0.0, 255); - CardGui::DrawCard(cardPosition.card, pos, DrawMode::kText, asThumbnail); + CardGui::DrawCard(cardPosition.card, pos, DrawMode::kText, asThumbnail, true); } } else @@ -147,9 +147,10 @@ void DeckView::renderCard(int index, int alpha, bool asThumbnail) int mode = !options[Options::DISABLECARDS].number ? DrawMode::kNormal : DrawMode::kText; Pos pos = Pos(cardPosition.x, cardPosition.y, cardPosition.scale * 285 / 250, 0.0, 255); - CardGui::DrawCard(cardPosition.card, pos, mode, asThumbnail); + CardGui::DrawCard(cardPosition.card, pos, mode, asThumbnail, true); } - + //the three DrawCard function above, I intentionally disabled the rendered border when in Deck Editor since the border must be dynamically resized + //we can pass variables so the DrawCard method knows what to do to the border but... there must be a better way to do it... int quadAlpha = alpha; if (!deck()->count(cardPosition.card)) quadAlpha /= 2; quadAlpha = 255 - quadAlpha; diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 0b2ac2b4e..72fcb8aca 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -578,8 +578,6 @@ void GameObserver::Update(float dt) { mLayers->actionLayer()->Update(0); } - players[0]->DeadLifeState(); - players[1]->DeadLifeState(); gameStateBasedEffects(); } oldGamePhase = mCurrentGamePhase; @@ -592,6 +590,21 @@ void GameObserver::gameStateBasedEffects() { if(getCurrentTargetChooser() && int(getCurrentTargetChooser()->getNbTargets()) == getCurrentTargetChooser()->maxtargets) getCurrentTargetChooser()->done = true; + ///////////////////////////////////// + for (int d = 0; d < 2; d++) + { + MTGGameZone * zone = players[d]->game->inPlay; + if (mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0) + { + for (int c = zone->nb_cards - 1; c >= 0; c--) + { + zone->cards[c]->cardistargetted = 0; + zone->cards[c]->cardistargetter = 0; + } + } + players[d]->DeadLifeState(); + } + //////////////////////////////////// if (mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0) return; diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 08236b48c..b1f8318f0 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -63,6 +63,8 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to modifiedbAbi = 0; LKIpower = power; LKItoughness = toughness; + cardistargetted = 0; + cardistargetter = 0; } MTGCardInstance * MTGCardInstance::createSnapShot() @@ -753,6 +755,56 @@ bool MTGCardInstance::StackIsEmptyandSorcerySpeed() return false; } +//check targetted? +bool MTGCardInstance::isTargetted() +{ + if(getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0) + { + ActionStack * stack = observer->mLayers->stackLayer(); + for (int i = stack->mObjects.size() - 1; i >= 0; i--) + { + Interruptible * current = ((Interruptible *) stack->mObjects[i]); + if ((current->type == ACTION_SPELL || current->type == ACTION_ABILITY) && current->state == NOT_RESOLVED) + { + if(current->type == ACTION_SPELL) + { + Spell * spell = (Spell *) current; + if(spell->getNextTarget() && spell->getNextTarget() == (Targetable*)this) + return true; + } + } + } + } + if(cardistargetted) + return true; + return false; +} + +//check targetter? +bool MTGCardInstance::isTargetter() +{ + if(getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0) + { + ActionStack * stack = observer->mLayers->stackLayer(); + for (int i = stack->mObjects.size() - 1; i >= 0; i--) + { + Interruptible * current = ((Interruptible *) stack->mObjects[i]); + if ((current->type == ACTION_SPELL || current->type == ACTION_ABILITY) && current->state == NOT_RESOLVED) + { + if(current->type == ACTION_SPELL) + { + Spell * spell = (Spell *) current; + if(spell && spell->source == this) + return true; + } + } + } + } + if(cardistargetter) + return true; + return false; +} + int MTGCardInstance::canBlock() { if (tapped) diff --git a/projects/mtg/src/WEvent.cpp b/projects/mtg/src/WEvent.cpp index de8165422..bba4fa8ef 100644 --- a/projects/mtg/src/WEvent.cpp +++ b/projects/mtg/src/WEvent.cpp @@ -122,6 +122,8 @@ WEventVampire::WEventVampire(MTGCardInstance * card,MTGCardInstance * source,MTG WEventTarget::WEventTarget(MTGCardInstance * card,MTGCardInstance * source) : WEventCardUpdate(card),card(card),source(source) { + card->cardistargetted = 1; + source->cardistargetter = 1; } WEventCardChangeType::WEventCardChangeType(MTGCardInstance * card, int type, bool before, bool after) :