diff --git a/projects/mtg/bin/Res/test/Amugaba.txt b/projects/mtg/bin/Res/test/Amugaba.txt new file mode 100644 index 000000000..c475c1159 --- /dev/null +++ b/projects/mtg/bin/Res/test/Amugaba.txt @@ -0,0 +1,19 @@ +#text=Flying. {2}{U}, Discard a card from your hand: Return Amugaba to its owner's hand. +[INIT] +FIRSTMAIN +[PLAYER1] +hand:swamp +inplay:Amugaba +manapool:{2}{U} +[PLAYER2] +[DO] +Amugaba +Swamp +[ASSERT] +FIRSTMAIN +[PLAYER1] +hand:Amugaba +graveyard:Swamp +manapool:{0} +[PLAYER2] +[END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index 6f88a1aa4..c5c29ff89 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -18,6 +18,7 @@ generic/wither.txt #Specific Cards ######################## afflict.txt +Amugaba.txt anarchy.txt animate_dead.txt animate_dead2.txt @@ -108,4 +109,4 @@ zombie_master.txt ######################## #Momir Basic Tests ######################## -momir/keldon_warlord.txt \ No newline at end of file +momir/keldon_warlord.txt diff --git a/projects/mtg/include/AIPlayer.h b/projects/mtg/include/AIPlayer.h index 62e066bbc..7605b8169 100644 --- a/projects/mtg/include/AIPlayer.h +++ b/projects/mtg/include/AIPlayer.h @@ -55,6 +55,7 @@ class AIPlayer: public Player{ int interruptIfICan(); int chooseAttackers(); int chooseBlockers(); + int canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy); int effectBadOrGood(MTGCardInstance * card); int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0); AIStats * getStats(); diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 448d481c5..e9a755319 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -270,6 +270,45 @@ public: } }; + +//Moves Cards from a zone to another +//TODO: this looks awfully similar to the equivalent targetAbility...woudln't there be a way to merge them ? +class AZoneSelfMover:public ActivatedAbility{ + +public: + string destinationZone; + + AZoneSelfMover(int _id, MTGCardInstance * _source,string destZone, ManaCost * _cost = NULL, int _tap=0):ActivatedAbility(_id,_source,_cost,0,_tap){ + destinationZone = destZone; + } + + int resolve(){ + MTGCardInstance * _target = source; + if(_target){ + Player* p = _target->controller(); + if (p){ + MTGGameZone * fromZone = _target->getCurrentZone(); + MTGGameZone * destZone = MTGGameZone::stringToZone(destinationZone, source,_target); + //inplay is a special zone ! + for (int i=0; i < 2; i++){ + if (destZone == game->players[i]->game->inPlay){ + MTGCardInstance * copy = game->players[i]->game->putInZone(_target, fromZone, game->players[i]->game->stack); + Spell * spell = NEW Spell(copy); + + spell->resolve(); + delete spell; + return 1; + } + } + p->game->putInZone(_target,fromZone,destZone); + } + return 1; + } + return 0; + } +}; + + //Copier. TargetAbility class ACopier:public TargetAbility{ public: diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index f173b205a..7c0aecfda 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -127,6 +127,9 @@ private: int genRandomCreatureId(int convertedCost); static vector pool[20]; static int initialized; + + int textAlpha; + string text; public: int alreadyplayed; @@ -134,6 +137,7 @@ public: MTGCardInstance * genCreature(int id); int testDestroy(); void Update(float dt); + void Render(); MTGMomirRule(int _id, MTGAllCards * _collection); int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); int reactToClick(MTGCardInstance * card); diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index 1171d4cd3..8e3c9d472 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -396,6 +396,14 @@ int AIPlayer::chooseAttackers(){ return 1; } +/* Can I first strike my oponent and get away with murder ? */ +int AIPlayer::canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy){ + if (ennemy->has(Constants::FIRSTSTRIKE) || ennemy->has(Constants::DOUBLESTRIKE)) return 0; + if (!(card->has(Constants::FIRSTSTRIKE) || card->has(Constants::DOUBLESTRIKE))) return 0; + if (!card->power >= ennemy->toughness) return 0; + return 1; +} + int AIPlayer::chooseBlockers(){ map opponentsToughness; int opponentForce = getCreaturesInfo(opponent(),INFO_CREATURESPOWER); @@ -408,9 +416,10 @@ int AIPlayer::chooseBlockers(){ cd.tapped = -1; MTGCardInstance * card = NULL; GameObserver * g = GameObserver::GetInstance(); + MTGAbility * a = g->mLayers->actionLayer()->getAbility(MTGAbility::MTG_BLOCK_RULE); + while((card = cd.nextmatch(game->inPlay, card))){ - g->cardClick(card); - if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0); + g->mLayers->actionLayer()->reactToClick(a,card); int set = 0; while(!set){ if (!card->defenser){ @@ -426,8 +435,7 @@ int AIPlayer::chooseBlockers(){ opponentsToughness[attacker]-= card->power; set = 1; }else{ - g->cardClick(card); - if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0); + g->mLayers->actionLayer()->reactToClick(a,card); } } } @@ -437,25 +445,24 @@ int AIPlayer::chooseBlockers(){ if (card->defenser && opponentsToughness[card->defenser] > 0){ while (card->defenser){ - g->cardClick(card); - if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0); + g->mLayers->actionLayer()->reactToClick(a,card); } } } card = NULL; while((card = cd.nextmatch(game->inPlay, card))){ if(!card->defenser){ - g->cardClick(card); - if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0); + g->mLayers->actionLayer()->reactToClick(a,card); int set = 0; while(!set){ if (!card->defenser){ set = 1; }else{ MTGCardInstance * attacker = card->defenser; - if (opponentsToughness[attacker] <= 0 || (card->toughness <= card->defenser->power && opponentForce*2 defenser->nbOpponents()>1){ - g->cardClick(card); - if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0); + if (opponentsToughness[attacker] <= 0 || + (card->toughness <= card->defenser->power && opponentForce*2 defenser)) || + card->defenser->nbOpponents()>1){ + g->mLayers->actionLayer()->reactToClick(a,card); }else{ set = 1; } diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index 769d443b5..1d2f25348 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -429,6 +429,7 @@ void GameStateDuel::Render() } sprintf(buffer, "Player %i wins (%i)", winner, p0life ); } + mFont->SetScale(1); mFont->DrawString(buffer, 10, 150); if (unlockedQuad){ r->RenderQuad(unlockedQuad, 20, 20); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 39bd3cfb7..1844a0519 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -310,24 +310,31 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){ //MoveTo Move a card from a zone to another found = s.find("moveto("); if (found != string::npos){ - OutputDebugString("may!\n"); if (dryMode) return BAKA_EFFECT_BAD; //TODO : depends on where from, where to... - int end = s.find(")"); + int end = s.find(")",found+1); string szone = s.substr(found + 7,end - found - 7); if (tc){ //if (cost){ AZoneMover * a = NEW AZoneMover(id,card,tc,szone,cost,doTap); if (may){ game->addObserver(NEW MayAbility(id,a,card)); - OutputDebugString("may!\n"); }else{ game->addObserver(a); } // } }else{ - MTGGameZone * fromZone = target->getCurrentZone();//this is technically incorrect. The initial zone should be as described in the targetchooser - MTGGameZone * destZone = MTGGameZone::stringToZone(szone, card, target); - target->controller()->game->putInZone(target,fromZone,destZone); + if (cost){ + MTGAbility * a = NEW AZoneSelfMover(id,card,szone,cost,doTap); + if (may){ + game->addObserver(NEW MayAbility(id,a,card)); + }else{ + game->addObserver(a); + } + }else{ + MTGGameZone * fromZone = target->getCurrentZone();//this is technically incorrect. The initial zone should be as described in the targetchooser + MTGGameZone * destZone = MTGGameZone::stringToZone(szone, card, target); + target->controller()->game->putInZone(target,fromZone,destZone); + } } result++; continue; diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 07e7ac2c8..fdd035a79 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -118,6 +118,7 @@ MTGCardInstance * MTGPlayerCards::putInGraveyard(MTGCardInstance * card){ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to){ MTGCardInstance * copy = NULL; GameObserver *g = GameObserver::GetInstance(); + if (!from || !to) return card; //Error check if (copy = from->removeCard(card)){ @@ -145,6 +146,7 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone delete e; return copy; } + return card; //Error } void MTGPlayerCards::discardRandom(MTGGameZone * from){ diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 5f87de887..7cfc8b202 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -173,6 +173,7 @@ MTGMomirRule::MTGMomirRule(int _id, MTGAllCards * _collection):MTGAbility(_id, N } alreadyplayed = 0; aType=MTGAbility::MOMIR; + textAlpha = 0; } int MTGMomirRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){ @@ -211,6 +212,8 @@ int MTGMomirRule::reactToClick(MTGCardInstance * card_to_discard, int cardId){ spell->source->isToken = 1; delete spell; alreadyplayed = 1; + textAlpha = 255; + text = card->name; return 1; } @@ -238,5 +241,17 @@ void MTGMomirRule::Update(float dt){ if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_UNTAP){ alreadyplayed = 0; } + if (textAlpha){ + textAlpha -= (200*dt); + if (textAlpha <0) textAlpha = 0; + } MTGAbility::Update(dt); } + +void MTGMomirRule::Render(){ + if (!textAlpha) return; + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MENU_FONT); + mFont->SetScale(2 - (float)textAlpha/130); + mFont->SetColor(ARGB(textAlpha,255,255,255)); + mFont->DrawString(text.c_str(),SCREEN_WIDTH/2,SCREEN_HEIGHT/2,JGETEXT_CENTER); +} \ No newline at end of file