diff --git a/projects/mtg/bin/Res/sets/CFX/todo.dat b/projects/mtg/bin/Res/sets/CFX/todo.dat index 1f0075276..0ab0120c1 100644 --- a/projects/mtg/bin/Res/sets/CFX/todo.dat +++ b/projects/mtg/bin/Res/sets/CFX/todo.dat @@ -709,17 +709,7 @@ type=Sorcery mana={3}{U}{U} [/card] -[card] -text=Toxic Iguanar has deathtouch as long as you control a green permanent. (Whenever it deals damage to a creature, destroy that creature.) -id=170956 -name=Toxic Iguanar -rarity=C -type=Creature -mana={R} -power=1 -subtype=Lizard -toughness=1 -[/card] + [card] text=Counter target spell. Basic landcycling {1}{U} ({1}{U}, Discard this card: Search your library for a basic land card, reveal it, and put it into your hand. Then shuffle your library.) id=179508 diff --git a/projects/mtg/bin/Res/test/belligerent_hatchling.txt b/projects/mtg/bin/Res/test/belligerent_hatchling.txt index 1acbdd51e..fde6b94d0 100644 --- a/projects/mtg/bin/Res/test/belligerent_hatchling.txt +++ b/projects/mtg/bin/Res/test/belligerent_hatchling.txt @@ -17,9 +17,7 @@ belligerent hatchling next #blockers next -#first strike -next -#damage +#first strike damage next #end of combat [ASSERT] diff --git a/projects/mtg/bin/Res/test/benalish_knight.txt b/projects/mtg/bin/Res/test/benalish_knight.txt index 218568d18..2e73ab814 100644 --- a/projects/mtg/bin/Res/test/benalish_knight.txt +++ b/projects/mtg/bin/Res/test/benalish_knight.txt @@ -16,9 +16,7 @@ swamp benalish knight benalish knight next -#first strike -next -#damage +#first strike damage next #end [ASSERT] diff --git a/projects/mtg/bin/Res/test/generic/first_strike.txt b/projects/mtg/bin/Res/test/generic/first_strike.txt index 2212f9ced..640a97b2f 100644 --- a/projects/mtg/bin/Res/test/generic/first_strike.txt +++ b/projects/mtg/bin/Res/test/generic/first_strike.txt @@ -11,8 +11,6 @@ next 1250 next next -next -1370 [ASSERT] COMBATEND [PLAYER1] diff --git a/projects/mtg/bin/Res/test/generic/first_strike2.txt b/projects/mtg/bin/Res/test/generic/first_strike2.txt index 6c399f02b..ef150f56a 100644 --- a/projects/mtg/bin/Res/test/generic/first_strike2.txt +++ b/projects/mtg/bin/Res/test/generic/first_strike2.txt @@ -10,8 +10,11 @@ white knight next fire elemental next +#combat damage first strike next -fire elemental +#combat damage +next +#ocombat end [ASSERT] COMBATEND [PLAYER1] diff --git a/projects/mtg/bin/Res/test/generic/first_strike3.txt b/projects/mtg/bin/Res/test/generic/first_strike3.txt index 96110bb75..6ad1e40ef 100644 --- a/projects/mtg/bin/Res/test/generic/first_strike3.txt +++ b/projects/mtg/bin/Res/test/generic/first_strike3.txt @@ -13,7 +13,7 @@ next 1365 next next -1370 +next [ASSERT] COMBATEND [PLAYER1] diff --git a/projects/mtg/bin/Res/test/generic/phases.txt b/projects/mtg/bin/Res/test/generic/phases.txt index dcb40afc3..73ed5676b 100644 --- a/projects/mtg/bin/Res/test/generic/phases.txt +++ b/projects/mtg/bin/Res/test/generic/phases.txt @@ -9,10 +9,6 @@ next next #attackers next -#blockers -next -#damage -next #combat end [ASSERT] COMBATEND diff --git a/projects/mtg/bin/Res/test/goblin_balloon_brigade2.txt b/projects/mtg/bin/Res/test/goblin_balloon_brigade2.txt index b8f0e6311..e2c29e22e 100644 --- a/projects/mtg/bin/Res/test/goblin_balloon_brigade2.txt +++ b/projects/mtg/bin/Res/test/goblin_balloon_brigade2.txt @@ -8,30 +8,7 @@ life:20 inplay:1302 [DO] next -#untap 2 -next -#upkeep 2 -next -#draw 2 -next -#main 2 -next -#combatbegin 2 -next -#attackers 2 -next -#blockers 2 -next -#combatdamage 2 -next -#endofcombat 2 -next -#main phase II 2 -next -#eot 2 -next -#cleanup2 -next +eot #untap next #upkeep diff --git a/projects/mtg/bin/Res/test/harpoon_sniper.txt b/projects/mtg/bin/Res/test/harpoon_sniper.txt index 899f2c296..55631f9ff 100644 --- a/projects/mtg/bin/Res/test/harpoon_sniper.txt +++ b/projects/mtg/bin/Res/test/harpoon_sniper.txt @@ -14,9 +14,7 @@ harpoon sniper choice 1 grizzly bears next -#damage -next -#combat end +#combat end (no combat damage because no attacking creatures) [ASSERT] COMBATEND [PLAYER1] diff --git a/projects/mtg/bin/Res/test/keldon_warlord.txt b/projects/mtg/bin/Res/test/keldon_warlord.txt index fa5534e83..ee37d720a 100644 --- a/projects/mtg/bin/Res/test/keldon_warlord.txt +++ b/projects/mtg/bin/Res/test/keldon_warlord.txt @@ -33,23 +33,7 @@ next 1393 1229 1308 -next -#combatbegin 2 -next -#combatattackers 2 -next -#combatblockers 2 -next -#combatdamage 2 -next -#endofcombat 2 -next -#main phase II 2 -next -#eot 2 -next -#cleanup 2 -next +eot #untap next #upkeep diff --git a/projects/mtg/bin/Res/test/kraken_eye2.txt b/projects/mtg/bin/Res/test/kraken_eye2.txt index 8824f2068..250f15f5a 100644 --- a/projects/mtg/bin/Res/test/kraken_eye2.txt +++ b/projects/mtg/bin/Res/test/kraken_eye2.txt @@ -14,10 +14,6 @@ next next #attack next -#blockers -next -#dmage -next #end next #secondmain diff --git a/projects/mtg/bin/Res/test/paralysis.txt b/projects/mtg/bin/Res/test/paralysis.txt index ee04be5af..5ae5c63df 100644 --- a/projects/mtg/bin/Res/test/paralysis.txt +++ b/projects/mtg/bin/Res/test/paralysis.txt @@ -28,10 +28,6 @@ next #attackers 2 1250 next -#blockers 2 -next -#combatdamage 2 -next #endofcombat 2 1250 [ASSERT] diff --git a/projects/mtg/bin/Res/test/stasis.txt b/projects/mtg/bin/Res/test/stasis.txt index f68abe33c..0f2a623f2 100644 --- a/projects/mtg/bin/Res/test/stasis.txt +++ b/projects/mtg/bin/Res/test/stasis.txt @@ -19,10 +19,6 @@ next #attackers 1250 next -#blockers -next -#damages -next #combat end [ASSERT] COMBATEND diff --git a/projects/mtg/bin/Res/test/steelclad_serpent1.txt b/projects/mtg/bin/Res/test/steelclad_serpent1.txt index 9669bb9a4..edbd52456 100644 --- a/projects/mtg/bin/Res/test/steelclad_serpent1.txt +++ b/projects/mtg/bin/Res/test/steelclad_serpent1.txt @@ -7,8 +7,6 @@ inplay:Steelclad Serpent [DO] Steelclad Serpent next -next -next [ASSERT] COMBATEND [PLAYER1] diff --git a/projects/mtg/bin/Res/test/telekinetic_sliver.txt b/projects/mtg/bin/Res/test/telekinetic_sliver.txt index 5b8f7bf66..55a2e36e5 100644 --- a/projects/mtg/bin/Res/test/telekinetic_sliver.txt +++ b/projects/mtg/bin/Res/test/telekinetic_sliver.txt @@ -14,10 +14,6 @@ next #attackers grizzly bears next -#blockers -next -#damage -next #combat ends [ASSERT] COMBATEND diff --git a/projects/mtg/bin/Res/test/white_knight1.txt b/projects/mtg/bin/Res/test/white_knight1.txt index e1d9fce65..48ee93b1b 100644 --- a/projects/mtg/bin/Res/test/white_knight1.txt +++ b/projects/mtg/bin/Res/test/white_knight1.txt @@ -14,7 +14,7 @@ next 1370 next next -1370 +next [ASSERT] COMBATEND [PLAYER1] diff --git a/projects/mtg/include/ActionStack.h b/projects/mtg/include/ActionStack.h index 57a7e77b9..20f286f88 100644 --- a/projects/mtg/include/ActionStack.h +++ b/projects/mtg/include/ActionStack.h @@ -66,6 +66,7 @@ class Interruptible: public PlayGuiObject, public Targetable{ class NextGamePhase: public Interruptible { public: int resolve(); + bool extraDamagePhase(); void Render(); virtual ostream& toString(ostream& out) const; NextGamePhase(int id); diff --git a/projects/mtg/include/DuelLayers.h b/projects/mtg/include/DuelLayers.h index 6f8f11f60..bf327c1b9 100644 --- a/projects/mtg/include/DuelLayers.h +++ b/projects/mtg/include/DuelLayers.h @@ -30,6 +30,7 @@ public: ActionLayer * actionLayer(); ActionStack * stackLayer(); + GuiCombat * combatLayer(); void init(); virtual void Update(float dt, Player * player); void CheckUserInput(int isAI); diff --git a/projects/mtg/include/GuiCombat.h b/projects/mtg/include/GuiCombat.h index a9a268b3f..3b45a1d64 100644 --- a/projects/mtg/include/GuiCombat.h +++ b/projects/mtg/include/GuiCombat.h @@ -31,6 +31,7 @@ class GuiCombat : public GuiLayer ~GuiCombat(); virtual void Update(float dt); virtual void Render(); + bool clickOK(); virtual bool CheckUserInput(u32 key); virtual int receiveEventPlus(WEvent* e); virtual int receiveEventMinus(WEvent* e); diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index a4dc31f02..d06bdfeec 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -27,7 +27,7 @@ class MTGAttackRule:public MTGAbility{ virtual ostream& toString(ostream& out) const; MTGAttackRule(int _id); const char * getMenuText(){return "Attacker";} - void Update(float dt); + int receiveEvent(WEvent * event); virtual MTGAttackRule * clone() const; }; diff --git a/projects/mtg/include/PhaseRing.h b/projects/mtg/include/PhaseRing.h index 101909958..670ab10b0 100644 --- a/projects/mtg/include/PhaseRing.h +++ b/projects/mtg/include/PhaseRing.h @@ -19,6 +19,8 @@ class Phase{ }; class PhaseRing{ +private: + static bool extraDamagePhase(int id); public: list ring; list::iterator current; @@ -30,6 +32,8 @@ class PhaseRing{ int addPhase(Phase * phase); int addPhaseBefore(int id, Player* player,int after_id, Player * after_player, int allOccurences = 1); int removePhase (int id, Player * player, int allOccurences = 1); + static const char * phaseName(int id); + }; #endif diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index feb457502..220498d9b 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -497,8 +497,9 @@ int AIPlayer::chooseBlockers(){ int AIPlayer::orderBlockers(){ GameObserver * g = GameObserver::GetInstance(); - if (BLOCKERS == g->combatStep && g->currentPlayer==this) + if (ORDER == g->combatStep && g->currentPlayer==this) { + OutputDebugString("AIPLAYER: order blockers\n"); g->userRequestNextGamePhase(); //TODO clever rank of blockers return 1; } @@ -747,7 +748,6 @@ int AIPlayerBaka::Act(float dt){ } initTimer(); if (combatDamages()){ - OutputDebugString("Damages and NOTHING ELSE\n"); return 0; } interruptIfICan(); diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 92ca81cc0..b2310a14f 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -12,25 +12,30 @@ #include "../include/TargetChooser.h" #include "../include/CardGui.h" #include "../include/Translate.h" - /* NextGamePhase requested by user */ int NextGamePhase::resolve(){ - GameObserver::GetInstance()->userRequestNextGamePhase(); + GameObserver::GetInstance()->nextGamePhase(); return 1; } + + void NextGamePhase::Render(){ - int nextPhase = (GameObserver::GetInstance()->getCurrentGamePhase() + 1) % Constants::MTG_PHASE_CLEANUP; + GameObserver * g = GameObserver::GetInstance(); + int nextPhase = (g->getCurrentGamePhase() + 1) % Constants::MTG_PHASE_CLEANUP; + JLBFont * mFont = resources.GetJLBFont(Constants::MAIN_FONT); mFont->SetBase(0); mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); char buffer[200]; int playerId = 1; - if (GameObserver::GetInstance()->currentActionPlayer == GameObserver::GetInstance()->players[1]) playerId = 2; - sprintf(buffer, "%s %i : -> %s", _("Player").c_str(), playerId, _(Constants::MTGPhaseNames[nextPhase]).c_str()); + if (g->currentActionPlayer == GameObserver::GetInstance()->players[1]) playerId = 2; + + sprintf(buffer, "%s %i : -> %s", _("Player").c_str(), playerId, _(PhaseRing::phaseName(nextPhase)).c_str()); + mFont->DrawString(buffer, x + 30 , y, JGETEXT_LEFT); } diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index da5beba19..81dd88915 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -71,6 +71,10 @@ ActionStack * DuelLayers::stackLayer(){ return stack; } +GuiCombat * DuelLayers::combatLayer(){ + return combat; +} + ActionLayer * DuelLayers::actionLayer(){ return action; } diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 7278029ae..4b63d10fc 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -81,11 +81,28 @@ void GameObserver::nextPlayer(){ combatStep = BLOCKERS; } void GameObserver::nextGamePhase(){ + Phase * cPhaseOld = phaseRing->getCurrentPhase(); + if (cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE) + if (FIRST_STRIKE == combatStep || END_FIRST_STRIKE == combatStep || DAMAGE == combatStep) { + nextCombatStep(); return; + } + if (cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS) + if (BLOCKERS == combatStep) { nextCombatStep(); return; } + phaseRing->forward(); + + //Go directly to end of combat if no attackers + if (cPhaseOld->id == Constants::MTG_PHASE_COMBATATTACKERS && !(currentPlayer->game->inPlay->getNextAttacker(NULL))){ + phaseRing->forward(); + phaseRing->forward(); + } + Phase * cPhase = phaseRing->getCurrentPhase(); currentGamePhase = cPhase->id; + if (Constants::MTG_PHASE_COMBATDAMAGE == currentGamePhase) nextCombatStep(); + if (currentPlayer != cPhase->player) nextPlayer(); @@ -152,11 +169,16 @@ void GameObserver::userRequestNextGamePhase(){ if (mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED)) return; if (getCurrentTargetChooser()) return; Phase * cPhaseOld = phaseRing->getCurrentPhase(); - if (cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE) - if (FIRST_STRIKE == combatStep || END_FIRST_STRIKE == combatStep || DAMAGE == combatStep) { nextCombatStep(); return; } - if (cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS) - if (BLOCKERS == combatStep) { nextCombatStep(); return; } - nextGamePhase(); + + + if ((cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == ORDER) || + cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE || + opponent()->isAI() || + options[GameOptions::phaseInterrupts[currentGamePhase]].number) + mLayers->stackLayer()->AddNextGamePhase(); + else + nextGamePhase(); + } int GameObserver::forceShuffleLibraries(){ diff --git a/projects/mtg/src/GuiCombat.cpp b/projects/mtg/src/GuiCombat.cpp index f325299a3..72ce61aa3 100644 --- a/projects/mtg/src/GuiCombat.cpp +++ b/projects/mtg/src/GuiCombat.cpp @@ -81,7 +81,7 @@ void GuiCombat::validateDamage() switch (step) { case FIRST_STRIKE : resolve(); go->nextCombatStep(); break; - case DAMAGE : resolve(); go->userRequestNextGamePhase(); break; + case DAMAGE : resolve(); go->nextGamePhase(); break; default: cout << "COMBAT : Cannot validate damage in this phase" << endl; break; } } @@ -117,6 +117,19 @@ void GuiCombat::removeOne(DefenserDamaged* blocker, CombatStep step) if (!(*it)->hasLethalDamage()) { (*it)->addDamage(1, activeAtk); break; } } +bool GuiCombat::clickOK(){ + switch (step) + { + case BLOCKERS : assert(false); return false; // that should not happen + case ORDER : go->nextGamePhase(); return true; + case FIRST_STRIKE : return false; + case DAMAGE : validateDamage(); return true; + case END_FIRST_STRIKE : return false; + case END_DAMAGE : return false; // nothing; + } + return false; +} + bool GuiCombat::CheckUserInput(u32 key) { if (NONE == cursor_pos) return false; @@ -147,15 +160,7 @@ bool GuiCombat::CheckUserInput(u32 key) } else if (OK == cursor_pos) { - switch (step) - { - case BLOCKERS : assert(false); break; // that should not happen - case ORDER : go->userRequestNextGamePhase(); break; - case FIRST_STRIKE : - case DAMAGE : validateDamage(); break; - case END_FIRST_STRIKE : - case END_DAMAGE : break; // nothing; - } + clickOK(); } break; case PSP_CTRL_TRIANGLE: @@ -297,9 +302,13 @@ int GuiCombat::resolve() // Returns the number of damage objects dealt this turn for (vector::iterator d = (*it)->damages.begin(); d != (*it)->damages.end(); ++d) stack->Add(NEW Damage(*d)); } - go->mLayers->stackLayer()->Add(stack); int v = stack->mCount; - if (v > 0) go->mLayers->stackLayer()->resolve(); // This will delete the damage stack which will in turn delete the Damage it contains + if (v > 0){ + go->mLayers->stackLayer()->Add(stack); + go->mLayers->stackLayer()->resolve(); // This will delete the damage stack which will in turn delete the Damage it contains + }else{ + SAFE_DELETE(stack); + } return v; } @@ -434,7 +443,7 @@ int GuiCombat::receiveEventMinus(WEvent* e) step = ORDER; } else - go->userRequestNextGamePhase(); + go->nextGamePhase(); return 1; } case FIRST_STRIKE: @@ -449,12 +458,15 @@ int GuiCombat::receiveEventMinus(WEvent* e) autoaffectDamage(*attacker, FIRST_STRIKE); if (0 == resolve()) go->nextCombatStep(); - else - go->mLayers->stackLayer()->AddNextGamePhase(); + //else go->mLayers->stackLayer()->AddNextGamePhase(); //uncomment to add "interrupt" offer after first strike, rather than giving priority to current player return 1; case DAMAGE: DAMAGE: step = event->step; - if (!go->currentPlayer->displayStack()) { resolve(); go->userRequestNextGamePhase(); return 1; } + if (!go->currentPlayer->displayStack()) { + //resolve(); + go->nextGamePhase(); + return 1; + } for (inner_iterator attacker = attackers.begin(); attacker != attackers.end(); ++attacker) autoaffectDamage(*attacker, step); for (inner_iterator it = attackers.begin(); it != attackers.end(); ++it) @@ -474,7 +486,8 @@ int GuiCombat::receiveEventMinus(WEvent* e) return 1; case END_DAMAGE: step = END_DAMAGE; - if (resolve()) go->userRequestNextGamePhase(); + if (0 == resolve()) + go->nextGamePhase(); return 1; } return 0; diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index eae3f673e..8f267c3bc 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -103,16 +103,19 @@ int MTGAttackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){ return 0; } -void MTGAttackRule::Update(float dt){ - if (currentPhase != newPhase && currentPhase == Constants::MTG_PHASE_COMBATATTACKERS){ - Player * p = game->currentPlayer; - MTGGameZone * z = p->game->inPlay; - for (int i= 0; i < z->nb_cards; i++){ - MTGCardInstance * card = z->cards[i]; - if (!card->isAttacker() && card->has(Constants::MUSTATTACK)) reactToClick(card); +int MTGAttackRule::receiveEvent(WEvent *e){ + if (WEventPhaseChange* event = dynamic_cast(e)) { + if (Constants::MTG_PHASE_COMBATATTACKERS == event->from->id) { + Player * p = game->currentPlayer; + MTGGameZone * z = p->game->inPlay; + for (int i= 0; i < z->nb_cards; i++){ + MTGCardInstance * card = z->cards[i]; + if (!card->isAttacker() && card->has(Constants::MUSTATTACK)) reactToClick(card); + } + return 1; } } - MTGAbility::Update(dt); + return 0; } int MTGAttackRule::reactToClick(MTGCardInstance * card){ diff --git a/projects/mtg/src/PhaseRing.cpp b/projects/mtg/src/PhaseRing.cpp index b4d628a77..336803aa4 100644 --- a/projects/mtg/src/PhaseRing.cpp +++ b/projects/mtg/src/PhaseRing.cpp @@ -24,6 +24,26 @@ PhaseRing::~PhaseRing(){ } } +//This needs to be controlled either by GameObserver or PhaseRing in the future +bool PhaseRing::extraDamagePhase(int id){ + GameObserver * g = GameObserver::GetInstance(); + if (id != Constants::MTG_PHASE_COMBATEND) return false; + if (g->combatStep != END_FIRST_STRIKE) return false; + MTGGameZone * z = g->currentPlayer->game->inPlay; + for (int i= 0; i < z->nb_cards; ++i){ + MTGCardInstance * card = z->cards[i]; + if (card->isAttacker() && !(card->has(Constants::FIRSTSTRIKE) || card->has(Constants::DOUBLESTRIKE))) return true; + } + return false; +} + +const char * PhaseRing::phaseName(int id){ + if (extraDamagePhase(id)) return "Combat Damage (2)"; + return Constants::MTGPhaseNames[id]; +} + + + Phase * PhaseRing::getCurrentPhase(){ if (current == ring.end()){ current = ring.begin(); diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index 4dd789165..2de1e95e9 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -3,6 +3,7 @@ #include "../include/MTGAbility.h" #include "../include/MTGRules.h" #include "../include/ActionLayer.h" +#include "../include/GuiCombat.h" #include using std::string; @@ -100,8 +101,11 @@ int TestSuiteAI::Act(float dt){ humanMode = 1; return 1; } - else if (action.compare("next")==0) - g->userRequestNextGamePhase(); + else if (action.compare("next")==0){ + GuiCombat * gc = g->mLayers->combatLayer(); + if (ORDER == g->combatStep || DAMAGE == g->combatStep) gc->clickOK(); + else g->userRequestNextGamePhase(); + } else if (action.compare("yes")==0) g->mLayers->stackLayer()->setIsInterrupting(this); else if (action.compare("endinterruption")==0)