refactor Legendary Rule

This commit is contained in:
Anthony Calosa
2017-02-01 09:49:36 +08:00
parent c0afb3b95e
commit 7b0fdcd721
6 changed files with 72 additions and 70 deletions

View File

@@ -10,6 +10,7 @@ inplay:22897
[DO]
106525
choice 0
106525
[ASSERT]
FIRSTMAIN
[PLAYER1]

View File

@@ -250,6 +250,7 @@ public:
int getCurrentToughness();
int LKIpower;
int LKItoughness;
int countDuplicateCardNames();
void cdaPT(int p = 0, int t = 0);
bool isCDA;
void switchPT(bool apply = false);

View File

@@ -423,19 +423,19 @@ public:
};
/*
* Rule 420.5e (Legend Rule)
* If two or more legendary permanents with the same name are in play, all are put into their
* owners' graveyards. This is called the "legend rule." If only one of those permanents is
* legendary, this rule doesn't apply.
* 704.5k If a player controls two or more legendary permanents with the same name,
* that player chooses one of them, and the rest are put into their owners graveyards.
* This is called the legend rule.
*/
class MTGLegendRule: public ListMaintainerAbility
class MTGLegendRule: public PermanentAbility
{
public:
TargetChooser * tcL;
MTGAbility * Legendrule;
MTGAbility * LegendruleAbility;
MTGAbility * LegendruleGeneric;
MTGLegendRule(GameObserver* observer, int _id);
int canBeInList(MTGCardInstance * card);
int added(MTGCardInstance * card);
int removed(MTGCardInstance * card);
int testDestroy();
int receiveEvent(WEvent * event);
virtual ostream& toString(ostream& out) const;
virtual MTGLegendRule * clone() const;
};

View File

@@ -79,6 +79,11 @@ struct WEventDamageStackResolved : public WEvent {
WEventDamageStackResolved();
};
struct WEventGameStateBasedChecked : public WEvent {
WEventGameStateBasedChecked();
};
struct WEventPhasePreChange : public WEvent {
Phase * from;
Phase * to;

View File

@@ -828,6 +828,22 @@ int MTGCardInstance::getCurrentToughness()
return toughness;
}
int MTGCardInstance::countDuplicateCardNames()
{
int count = 0;
if(observer)
{
int nb_cards = controller()->game->battlefield->nb_cards;
for(int x = 0; x < nb_cards; x++)
{
if(controller()->game->battlefield->cards[x]->name == this->name)
count+=1;
}
}
return count;
}
//check stack
bool MTGCardInstance::StackIsEmptyandSorcerySpeed()
{

View File

@@ -3205,76 +3205,55 @@ MTGTokensCleanup * MTGTokensCleanup::clone() const
/* Legend Rule */
MTGLegendRule::MTGLegendRule(GameObserver* observer, int _id) :
ListMaintainerAbility(observer, _id)
PermanentAbility(observer, _id)
{
tcL = NULL;
Legendrule = NULL;
LegendruleAbility = NULL;
LegendruleGeneric = NULL;
}
;
int MTGLegendRule::canBeInList(MTGCardInstance * card)
int MTGLegendRule::receiveEvent(WEvent * event)
{
if(card->isPhased)
return 0;
if (card->hasType(Subtypes::TYPE_LEGENDARY) && card->controller()->game->inPlay->hasCard(card))
WEventGameStateBasedChecked * e = dynamic_cast<WEventGameStateBasedChecked*> (event);
if (e)
{
if(card->has(Constants::NOLEGEND)||card->controller()->opponent()->inPlay()->hasAbility(Constants::NOLEGENDRULE)||card->controller()->inPlay()->hasAbility(Constants::NOLEGENDRULE))
return 0;
else
return 1;
}
return 0;
}
int MTGLegendRule::added(MTGCardInstance * card)
{
map<MTGCardInstance *, bool>::iterator it;
int destroy = 0;
vector<MTGCardInstance*>oldCards;
for (it = cards.begin(); it != cards.end(); it++)
{
MTGCardInstance * comparison = (*it).first;
if (comparison != card && comparison->controller() == card->controller() && !(comparison->getName().compare(card->getName())))
for (int i = 0; i < 2; i++)
{
oldCards.push_back(comparison);
destroy = 1;
MTGGameZone * zone = game->players[i]->game->inPlay;
for (int k = zone->nb_cards - 1; k >= 0; k--)
{
MTGCardInstance * card = zone->cards[k];
if (card && card->hasType(Subtypes::TYPE_LEGENDARY) && !card->isPhased)
{
if(card->has(Constants::NOLEGEND)||card->controller()->opponent()->inPlay()->hasAbility(Constants::NOLEGENDRULE)||card->controller()->inPlay()->hasAbility(Constants::NOLEGENDRULE))
;
else
if(card->countDuplicateCardNames() > 1)
{
vector<MTGAbility*>selection;
TargetChooserFactory tfL(game);
tcL = tfL.createTargetChooser("*[share!name!]|mybattlefield",card->clone());
tcL->targetter = NULL;
tcL->maxtargets = card->countDuplicateCardNames()-1;
Legendrule = NEW AAMover(game, game->mLayers->actionLayer()->getMaxId(), card, NULL,"ownergraveyard","Put in Graveyard");
Legendrule->oneShot = true;
Legendrule->canBeInterrupted = false;
LegendruleAbility = NEW GenericTargetAbility(game, "","",game->mLayers->actionLayer()->getMaxId(), card,tcL, Legendrule->clone());
LegendruleAbility->oneShot = true;
LegendruleAbility->canBeInterrupted = false;
LegendruleGeneric = NEW GenericAddToGame(game, game->mLayers->actionLayer()->getMaxId(), card,NULL,LegendruleAbility->clone());
LegendruleGeneric->oneShot = true;
selection.push_back(LegendruleGeneric->clone());
MTGAbility * menuChoice = NEW MenuAbility(game, game->mLayers->actionLayer()->getMaxId(), card, card,true,selection,card->controller(),"Legendary Rule");
menuChoice->addToGame();
return 1;
}
}
}
}
}
if (game->mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0)
destroy = 0;
if (game->mLayers->actionLayer()->menuObject)
destroy = 0;
if (game->getCurrentTargetChooser() || game->mLayers->actionLayer()->isWaitingForAnswer())
destroy = 0;
if(destroy)
{
vector<MTGAbility*>selection;
MultiAbility * multi = NEW MultiAbility(game, game->mLayers->actionLayer()->getMaxId(), card, card, NULL);
for(unsigned int i = 0;i < oldCards.size();i++)
{
AAMover *a = NEW AAMover(game, game->mLayers->actionLayer()->getMaxId(), card, oldCards[i],"ownergraveyard","Keep New");
a->oneShot = true;
multi->Add(a);
}
multi->oneShot = 1;
MTGAbility * a1 = multi;
selection.push_back(a1);
AAMover *b = NEW AAMover(game, game->mLayers->actionLayer()->getMaxId(), card, card,"ownergraveyard","Keep Old");
b->oneShot = true;
MTGAbility * b1 = b;
selection.push_back(b1);
MTGAbility * menuChoice = NEW MenuAbility(game, game->mLayers->actionLayer()->getMaxId(), card, card,true,selection,card->controller(),"Legendary Rule");
menuChoice->addToGame();
}
return 1;
}
int MTGLegendRule::removed(MTGCardInstance *)
{
return 0;
}
int MTGLegendRule::testDestroy()
{
return 0;
}