diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index 462369819..cf6f70409 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -138,6 +138,7 @@ lord_of_the_pit2.txt master_of_etherium.txt millstone.txt #mind_rot.txt +mobile_fort.txt nantuko_husk.txt necrogenesis.txt Nevinyrrals_Disk.txt diff --git a/projects/mtg/bin/Res/test/manual/README.txt b/projects/mtg/bin/Res/test/manual/README.txt new file mode 100644 index 000000000..52f5b5624 --- /dev/null +++ b/projects/mtg/bin/Res/test/manual/README.txt @@ -0,0 +1,2 @@ +In this folder, we put tests that are not supposed to be 100% automated. +you switch the control of each Test suite player to Human or AI, to monitor the behavior of the game given a specific starting state \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/manual/attackers.txt b/projects/mtg/bin/Res/test/manual/attackers.txt new file mode 100644 index 000000000..237de0be1 --- /dev/null +++ b/projects/mtg/bin/Res/test/manual/attackers.txt @@ -0,0 +1,11 @@ +#Scenario: simple attack with grizzly bears +[INIT] +FIRSTMAIN +[PLAYER1] +inplay:grizzly bears +[PLAYER2] +[DO] +human +next +[ASSERT] +[END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/manual/control.txt b/projects/mtg/bin/Res/test/manual/control.txt new file mode 100644 index 000000000..40c903c12 --- /dev/null +++ b/projects/mtg/bin/Res/test/manual/control.txt @@ -0,0 +1,12 @@ +#Scenario: control magic on a creature: it gets duplicated ??? +[INIT] +FIRSTMAIN +[PLAYER1] +hand:control magic +manapool:{2}{U}{U} +[PLAYER2] +inplay:air elemental +[DO] +human +[ASSERT] +[END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/manual/first_strike.txt b/projects/mtg/bin/Res/test/manual/first_strike.txt new file mode 100644 index 000000000..7809af4aa --- /dev/null +++ b/projects/mtg/bin/Res/test/manual/first_strike.txt @@ -0,0 +1,11 @@ +#Scenario: simple attack with white knight +[INIT] +FIRSTMAIN +[PLAYER1] +inplay:white knight +[PLAYER2] +[DO] +human +next +[ASSERT] +[END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/manual/first_strike2.txt b/projects/mtg/bin/Res/test/manual/first_strike2.txt new file mode 100644 index 000000000..33d4491b3 --- /dev/null +++ b/projects/mtg/bin/Res/test/manual/first_strike2.txt @@ -0,0 +1,13 @@ +#Scenario: simple attack with white knight + grizzly bears +#Attack with both. +#There should be a request for interruption between the two damage assignation steps, so that users can cast spells +[INIT] +COMBATATTACKERS +[PLAYER1] +inplay:white knight,grizzly bears +[PLAYER2] +[DO] +human +next +[ASSERT] +[END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/manual/m10_blockers.txt b/projects/mtg/bin/Res/test/manual/m10_blockers.txt new file mode 100644 index 000000000..10237822e --- /dev/null +++ b/projects/mtg/bin/Res/test/manual/m10_blockers.txt @@ -0,0 +1,23 @@ +#New blockers reordering rule +[INIT] +COMBATATTACKERS +[PLAYER1] +inplay:Puppeteer +[PLAYER2] +inplay:raging goblin,Drudge Skeletons +[DO] +Puppeteer +next +#blockers +raging goblin +Drudge Skeletons +next +human +[ASSERT] +COMBATEND +[PLAYER1] +graveyard:Puppeteer +[PLAYER2] +graveyard:Drudge Skeletons +inplay:raging goblin +[END] diff --git a/projects/mtg/bin/Res/test/manual/p2_attacks.txt b/projects/mtg/bin/Res/test/manual/p2_attacks.txt new file mode 100644 index 000000000..a17fde553 --- /dev/null +++ b/projects/mtg/bin/Res/test/manual/p2_attacks.txt @@ -0,0 +1,16 @@ +#Bug: AI player 2 attacks: no damage is dealt +#This is a test switching both players to AI mode, it IS NOT SUPPOSED TO Succeed, just for testers to visually confirm stuff +[INIT] +SECONDMAIN +[PLAYER1] +inplay:dancing scimitar +[PLAYER2] +inplay:cloud sprite,briarberry cohort,white knight +[DO] +ai +ai +[ASSERT] +COMBATEND +[PLAYER1] +[PLAYER2] +[END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/mobile_fort.txt b/projects/mtg/bin/Res/test/mobile_fort.txt new file mode 100644 index 000000000..ef89fe90d --- /dev/null +++ b/projects/mtg/bin/Res/test/mobile_fort.txt @@ -0,0 +1,27 @@ +#Bug: Mobile Fort doesn't get +3/-1 +[INIT] +FIRSTMAIN +[PLAYER1] +inplay:mobile fort +manapool:{3} +[PLAYER2] +[DO] +mobile fort +next +#beign +next +#attackers +mobile fort +next +#blockers +next +#damage +next +#combatend +[ASSERT] +COMBATEND +[PLAYER1] +inplay:mobile fort +[PLAYER2] +life:17 +[END] \ No newline at end of file diff --git a/projects/mtg/include/AIPlayer.h b/projects/mtg/include/AIPlayer.h index 5ff7f0904..925e9f457 100644 --- a/projects/mtg/include/AIPlayer.h +++ b/projects/mtg/include/AIPlayer.h @@ -70,6 +70,7 @@ class AIPlayer: public Player{ virtual MTGCardInstance * chooseCard(TargetChooser * tc, MTGCardInstance * source, int random = 0); virtual int chooseTarget(TargetChooser * tc = NULL); virtual int Act(float dt); + virtual int affectCombatDamages(CombatStep); int isAI(){return 1;}; int canHandleCost(MTGAbility * ability); int selectAbility(); diff --git a/projects/mtg/include/GuiCombat.h b/projects/mtg/include/GuiCombat.h index 227c66398..df28692c0 100644 --- a/projects/mtg/include/GuiCombat.h +++ b/projects/mtg/include/GuiCombat.h @@ -15,18 +15,20 @@ class GuiCombat : public GuiLayer AttackerDamaged* activeAtk; static JTexture* ok_tex; Pos ok, enemy_avatar; - vector attackers; DamagerDamaged* current; enum { BLK, ATK, OK, NONE } cursor_pos; CombatStep step; void validateDamage(); void addOne(DefenserDamaged* blocker, CombatStep); void removeOne(DefenserDamaged* blocker, CombatStep); - void autoaffectDamage(AttackerDamaged* attacker, CombatStep); void remaskBlkViews(AttackerDamaged* before, AttackerDamaged* after); int resolve(); public: + + vector attackers; + void autoaffectDamage(AttackerDamaged* attacker, CombatStep); + GuiCombat(GameObserver* go); ~GuiCombat(); virtual void Update(float dt); diff --git a/projects/mtg/include/TestSuiteAI.h b/projects/mtg/include/TestSuiteAI.h index 9a423fd2d..92fd75248 100644 --- a/projects/mtg/include/TestSuiteAI.h +++ b/projects/mtg/include/TestSuiteAI.h @@ -76,14 +76,14 @@ class TestSuite{ }; -class TestSuiteAI:public AIPlayer{ +class TestSuiteAI:public AIPlayerBaka{ public: TestSuite * suite; float timer; - int humanMode; + int playMode; TestSuiteAI(TestSuite * suite, int playerId); virtual int Act(float dt); - virtual int displayStack(){return 1;} + virtual int displayStack(); }; diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index 52d873c65..815d1874d 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -4,6 +4,7 @@ #include "../include/AIStats.h" #include "../include/AllAbilities.h" #include "../include/ExtraCost.h" +#include "../include/GuiCombat.h" const char * const MTG_LAND_TEXTS[] = {"artifact","forest","island","mountain","swamp","plains","other lands"}; @@ -250,13 +251,12 @@ int AIPlayer::selectAbility(){ } if (ranking.size()){ - OutputDebugString("We have a winrar\n"); AIAction * a = ranking.begin()->first; int chance = 1 + rand() % 100; if (getEfficiency(a) < chance){ a = NULL; }else{ -OutputDebugString("We REALLY have a winner\n"); + OutputDebugString("AIPlayer:Using Activated ability\n"); tapLandsForMana(pMana, a->ability->cost); clickstream.push(a); } @@ -507,8 +507,15 @@ int AIPlayer::orderBlockers(){ return 0; } +int AIPlayer::affectCombatDamages(CombatStep step){ + GameObserver * g = GameObserver::GetInstance(); + GuiCombat * gc = g->mLayers->combatLayer(); + for (vector::iterator attacker = gc->attackers.begin(); attacker != gc->attackers.end(); ++attacker) + gc->autoaffectDamage(*attacker, step); + return 1; +} - +//TODO: Deprecate combatDamages int AIPlayer::combatDamages(){ //int result = 0; GameObserver * gameObs = GameObserver::GetInstance(); @@ -736,7 +743,6 @@ int AIPlayerBaka::Act(float dt){ GameObserver * g = GameObserver::GetInstance(); if (!(g->currentlyActing() == this)){ - OutputDebugString("Cannot interrupt\n"); return 0; } diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index fdd7dc421..7cf14fad4 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -26,7 +26,8 @@ enum ENUM_DUEL_STATE DUEL_STATE_CANCEL, DUEL_STATE_PLAY, DUEL_STATE_BACK_TO_MAIN_MENU, - DUEL_STATE_MENU + DUEL_STATE_MENU, + DUEL_STATE_ERROR }; enum ENUM_DUEL_MENUS @@ -275,7 +276,11 @@ void GameStateDuel::Update(float dt) sprintf(buf, "nb cards in player2's graveyard : %i\n",mPlayers[1]->game->graveyard->nb_cards); LOG(buf); }else{ - mGamePhase = DUEL_STATE_END; + if (!game){ + mGamePhase = DUEL_STATE_ERROR; + }else{ + mGamePhase = DUEL_STATE_END; + } } } #endif @@ -402,6 +407,13 @@ void GameStateDuel::Render() credits->Render(); break; } + case DUEL_STATE_ERROR: + { + JRenderer * r = JRenderer::GetInstance(); + r->ClearScreen(ARGB(200,0,0,0)); + mFont->DrawString(_("AN ERROR OCCURED, CHECK FILE NAMES").c_str(),0,SCREEN_HEIGHT/2); + break; + } case DUEL_STATE_CHOOSE_DECK1: case DUEL_STATE_CHOOSE_DECK1_TO_2: case DUEL_STATE_CHOOSE_DECK2: diff --git a/projects/mtg/src/GuiCombat.cpp b/projects/mtg/src/GuiCombat.cpp index cbc618835..3e61bc4b4 100644 --- a/projects/mtg/src/GuiCombat.cpp +++ b/projects/mtg/src/GuiCombat.cpp @@ -2,6 +2,7 @@ #include "../include/config.h" #include "../include/GameApp.h" #include "../include/GuiCombat.h" +#include "../include/AIPlayer.h" #include "Closest.cpp" static const float MARGIN = 70; @@ -469,7 +470,7 @@ int GuiCombat::receiveEventMinus(WEvent* e) case DAMAGE: DAMAGE: step = event->step; if (!go->currentPlayer->displayStack()) { - //resolve(); + ((AIPlayer *)go->currentPlayer)->affectCombatDamages(step); go->nextGamePhase(); return 1; } diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index 3506a8e74..25e155673 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -8,16 +8,18 @@ #include using std::string; -TestSuiteAI::TestSuiteAI(TestSuite * _suite, int playerId):AIPlayer(_suite->buildDeck(playerId),"testsuite", "testsuite"){ + +enum ENUM_PLAY_MODE + { + MODE_TEST_SUITE, + MODE_HUMAN, + MODE_AI, + }; + +TestSuiteAI::TestSuiteAI(TestSuite * _suite, int playerId):AIPlayerBaka(_suite->buildDeck(playerId),"testsuite", "testsuite","baka.jpg"){ suite = _suite; timer = 0; - humanMode = 0; - - mAvatarTex = resources.RetrieveTexture("baka.jpg",RETRIEVE_VRAM,TEXTURE_SUB_AVATAR); - if(mAvatarTex) - mAvatar = resources.RetrieveQuad("baka.jpg", 0, 0, 35, 50,"bakaAvatar",RETRIEVE_VRAM,TEXTURE_SUB_AVATAR); - else - mAvatar = NULL; + playMode = MODE_TEST_SUITE; } @@ -58,11 +60,16 @@ Interruptible * TestSuite::getActionByMTGId(int mtgid){ return NULL; } +int TestSuiteAI::displayStack(){ + if (playMode == MODE_AI) return 0; + return 1; +} int TestSuiteAI::Act(float dt){ GameObserver * g = GameObserver::GetInstance(); g->gameOver = NULL; // Prevent draw rule from losing the game - if (humanMode){ + if (playMode == MODE_AI) return AIPlayerBaka::Act(dt); + if (playMode == MODE_HUMAN){ g->mLayers->CheckUserInput(0); return 1; } @@ -101,7 +108,12 @@ int TestSuiteAI::Act(float dt){ } else if (action.compare("human")==0){ OutputDebugString("TESTSUITE You have control"); - humanMode = 1; + playMode = MODE_HUMAN; + return 1; + } + else if (action.compare("ai")==0){ + OutputDebugString("TESTSUITE Switching to AI"); + playMode = MODE_AI; return 1; } else if (action.compare("next")==0){