fixed a bug with lords not removing altercost correctly when the source is phased.

added 
cantbeblockerof(this)<--this = the card who owns the ability.
cantbeblockerof(targetchooser) <--the target cant block anything targetable by this targetchooser.
spin engine and similar will use cantbeblockerof(this).
others were done with a workaround, which i hope will be updated soon.
This commit is contained in:
omegablast2002@yahoo.com
2013-02-06 02:45:40 +00:00
parent 1d06a74fd9
commit e424c3ab27
7 changed files with 182 additions and 8 deletions

View File

@@ -1868,7 +1868,52 @@ public:
}
};
//cant be the blocker of targetchooser
//Can't be blocked by...
class ACantBeBlockerOf: public MTGAbility
{
public:
TargetChooser * fromTc;
bool thisCard;
ACantBeBlockerOf(GameObserver* observer, int id, MTGCardInstance * _source, MTGCardInstance * _target, TargetChooser *fromTc,bool aThis) :
MTGAbility(observer, id, _source, _target), fromTc(fromTc),thisCard(aThis)
{
}
int addToGame()
{
MTGCardInstance * _target = (MTGCardInstance *) target;
if(!thisCard)
_target->addCantBeBlockerOf(fromTc);
else
_target->addCantBeBlockerOfCard((MTGCardInstance*)source);
return MTGAbility::addToGame();
}
int destroy()
{
if(!thisCard)
((MTGCardInstance *) target)->removeCantBeBlockerOf(fromTc);
else
((MTGCardInstance *) target)->removeCantBeBlockerOfCard((MTGCardInstance*)source);
return 1;
}
ACantBeBlockerOf * clone() const
{
ACantBeBlockerOf * a = NEW ACantBeBlockerOf(*this);
if(fromTc)
a->fromTc = fromTc->clone();
return a;
}
~ACantBeBlockerOf()
{
SAFE_DELETE(fromTc);
}
};
//Alteration of Power and Toughness (enchantments)
class APowerToughnessModifier: public MTGAbility
{
@@ -2415,7 +2460,10 @@ public:
int canBeInList(MTGCardInstance * card)
{
if(card->isPhased || source->isPhased)
{
removed(card);
return 0;
}
if ((includeSelf || card != source) && tc->canTarget(card))
return 1;
return 0;
@@ -3975,6 +4023,7 @@ MTGCardInstance * manaReducer;
int type;
AAlterCost(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target, int amount, int type);
int addToGame();
int destroy();
int testDestroy();
void refreshCost(MTGCardInstance * card = NULL);
void increaseTheCost(MTGCardInstance * card = NULL);
@@ -5413,7 +5462,7 @@ public:
}
};
//Bushido ability
//Bushido ability todo:add bushido count.
class ABushidoAbility: public MTGAbility
{
public:

View File

@@ -119,6 +119,7 @@ class GameObserver{
Player * currentlyActing();
GameObserver(WResourceManager* output = 0, JGE* input = 0);
virtual ~GameObserver();
int waitingGameStateCheck;
void gameStateBasedEffects();
void enchantmentStatus();
void Affinity();

View File

@@ -193,9 +193,17 @@ public:
int CantBeTargetby(MTGCardInstance * card);
vector<TargetChooser *>cantBeBlockedBys;
vector<TargetChooser *>cantBeBlockerOfs;
vector<MTGCardInstance *>cantBeBlockerOfCards;
int addCantBeBlockedBy(TargetChooser * tc);
int removeCantBeBlockedBy(TargetChooser *tc, int erase = 0);
int cantBeBlockedBy(MTGCardInstance * card);
int addCantBeBlockerOf(TargetChooser * tc);
int removeCantBeBlockerOf(TargetChooser *tc, int erase = 0);
int cantBeBlockerOf(MTGCardInstance * card);
int addCantBeBlockerOfCard(MTGCardInstance * card);
int removeCantBeBlockerOfCard(MTGCardInstance * card, int erase = 0);
int cantBeBlockerOfCard(MTGCardInstance * card);
void copy(MTGCardInstance * card);

View File

@@ -3566,6 +3566,26 @@ int AAlterCost::addToGame()
return MTGAbility::addToGame();
}
int AAlterCost::destroy()
{
MTGCardInstance * _target = (MTGCardInstance *)target;
if(!this->manaReducer->isInPlay(game))
{
if (amount > 0)
{
_target->getIncreasedManaCost()->remove(type,amount);
refreshCost(_target);//special case for 0 cost.
}
else
{
_target->getReducedManaCost()->remove(type,abs(amount));
refreshCost(_target);//special case for 0 cost.
}
return MTGAbility::testDestroy();
}
return 0;
}
int AAlterCost::testDestroy()
{
MTGCardInstance * _target = (MTGCardInstance *)target;

View File

@@ -103,6 +103,7 @@ GameObserver::GameObserver(WResourceManager *output, JGE* input)
mLayers = NULL;
mTrash = new Trash();
mDeckManager = new DeckManager();
waitingGameStateCheck = 0;
}
GamePhase GameObserver::getCurrentGamePhase()
@@ -581,7 +582,13 @@ void GameObserver::gameStateBasedEffects()
{
if(getCurrentTargetChooser() && int(getCurrentTargetChooser()->getNbTargets()) == getCurrentTargetChooser()->maxtargets)
getCurrentTargetChooser()->done = true;
if (mLayers->stackLayer()->count(0, NOT_RESOLVED) <= 50)
waitingGameStateCheck++;
if(waitingGameStateCheck > 50)
{
waitingGameStateCheck++;
waitingGameStateCheck--;
}
if(waitingGameStateCheck > 50)
{
//if there are more than 50 unresolved actions on the stack, lets allow a gameStates update
//to make sure we are not caught up in a loop, example :Exquisite Blood + Sanguine Bond
@@ -592,6 +599,7 @@ void GameObserver::gameStateBasedEffects()
if (getCurrentTargetChooser() || mLayers->actionLayer()->isWaitingForAnswer())
return;
}
waitingGameStateCheck = 0;
////////////////////////
//---apply damage-----//
//after combat effects//

View File

@@ -2760,7 +2760,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
return NULL; //TODO
}
//Can't be blocked by...
//Can't be blocked by...need cantdefendagainst(
vector<string> splitCantBlock = parseBetween(s, "cantbeblockedby(", ")");
if (splitCantBlock.size())
{
@@ -2779,7 +2779,29 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
}
return NULL; //TODO
}
//cant be the blocker of targetchooser.
vector<string> splitCantBeBlock = parseBetween(s, "cantbeblockeof(", ")");
if (splitCantBeBlock.size())
{
TargetChooserFactory tcf(observer);
TargetChooser * fromTc = NULL;
if (splitCantBeBlock[1].find("this") == string::npos)
{
fromTc = tcf.createTargetChooser(splitCantBeBlock[1], card);
}
if (!activated)
{
if(fromTc)
return NEW ACantBeBlockerOf(observer, id, card, target, fromTc, false);//of a targetchooser
else
return NEW ACantBeBlockerOf(observer, id, card, target, fromTc, true);//blocker of the card source.
}
return NULL;
}
//affinity based on targetchooser
vector<string> splitNewAffinity = parseBetween(s, "affinity(", ")");
if (splitNewAffinity.size())
@@ -4835,8 +4857,8 @@ void ListMaintainerAbility::updateTargets()
for (int i = 0; i < 2; i++)
{
Player * p = game->players[i];
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library };
for (int k = 0; k < 4; k++)
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = zones[k];
if (canTarget(zone))
@@ -4907,8 +4929,8 @@ void ListMaintainerAbility::checkTargets()
for (int i = 0; i < 2; i++)
{
Player * p = game->players[i];
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library };
for (int k = 0; k < 4; k++)
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack };
for (int k = 0; k < 5; k++)
{
MTGGameZone * zone = zones[k];
if (canTarget(zone))

View File

@@ -301,7 +301,7 @@ int MTGCardInstance::isInPlay(GameObserver* game)
for (int i = 0; i < 2; i++)
{
MTGGameZone * zone = game->players[i]->game->inPlay;
if (zone->hasCard(this))
if (zone->hasCard(this) && !isPhased)
return 1;
}
return 0;
@@ -609,6 +609,10 @@ int MTGCardInstance::canBlock(MTGCardInstance * opponent)
return 0;
if (opponent->cantBeBlockedBy(this))
return 0;
if (this->cantBeBlockerOf(opponent))
return 0;
if (this->cantBeBlockerOfCard(opponent))
return 0;
if (opponent->basicAbilities[(int)Constants::UNBLOCKABLE])
return 0;
if (opponent->basicAbilities[(int)Constants::ONEBLOCKER] && opponent->blocked)
@@ -1044,7 +1048,69 @@ int MTGCardInstance::cantBeBlockedBy(MTGCardInstance * card)
}
return 0;
}
//cant be the block of
int MTGCardInstance::addCantBeBlockerOf(TargetChooser * tc)
{
cantBeBlockerOfs.push_back(tc);
return cantBeBlockerOfs.size();
}
int MTGCardInstance::removeCantBeBlockerOf(TargetChooser * tc, int erase)
{
for (size_t i = 0; i < cantBeBlockerOfs.size(); i++)
{
if (cantBeBlockerOfs[i] == tc)
{
if (erase)
delete (cantBeBlockerOfs[i]);
cantBeBlockerOfs.erase(cantBeBlockerOfs.begin() + i);
return 1;
}
}
return 0;
}
int MTGCardInstance::cantBeBlockerOf(MTGCardInstance * card)
{
for (size_t i = 0; i < cantBeBlockerOfs.size(); i++)
{
if (cantBeBlockerOfs[i]->canTarget(card))
return 1;
}
return 0;
}
//cant be the block of
int MTGCardInstance::addCantBeBlockerOfCard(MTGCardInstance * card)
{
cantBeBlockerOfCards.push_back(card);
return cantBeBlockerOfCards.size();
}
int MTGCardInstance::removeCantBeBlockerOfCard(MTGCardInstance * card, int erase)
{
for (size_t i = 0; i < cantBeBlockerOfCards.size(); i++)
{
if (cantBeBlockerOfCards[i] == card)
{
if (erase)
delete (cantBeBlockerOfCards[i]);
cantBeBlockerOfCards.erase(cantBeBlockerOfCards.begin() + i);
return 1;
}
}
return 0;
}
int MTGCardInstance::cantBeBlockerOfCard(MTGCardInstance * card)
{
for (size_t i = 0; i < cantBeBlockerOfCards.size(); i++)
{
if (cantBeBlockerOfCards[i] == card)
return 1;
}
return 0;
}
/* Choose a sound sample to associate to that card */
const string& MTGCardInstance::getSample()
{