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:
@@ -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)
|
//Alteration of Power and Toughness (enchantments)
|
||||||
class APowerToughnessModifier: public MTGAbility
|
class APowerToughnessModifier: public MTGAbility
|
||||||
{
|
{
|
||||||
@@ -2415,7 +2460,10 @@ public:
|
|||||||
int canBeInList(MTGCardInstance * card)
|
int canBeInList(MTGCardInstance * card)
|
||||||
{
|
{
|
||||||
if(card->isPhased || source->isPhased)
|
if(card->isPhased || source->isPhased)
|
||||||
|
{
|
||||||
|
removed(card);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
if ((includeSelf || card != source) && tc->canTarget(card))
|
if ((includeSelf || card != source) && tc->canTarget(card))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3975,6 +4023,7 @@ MTGCardInstance * manaReducer;
|
|||||||
int type;
|
int type;
|
||||||
AAlterCost(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target, int amount, int type);
|
AAlterCost(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target, int amount, int type);
|
||||||
int addToGame();
|
int addToGame();
|
||||||
|
int destroy();
|
||||||
int testDestroy();
|
int testDestroy();
|
||||||
void refreshCost(MTGCardInstance * card = NULL);
|
void refreshCost(MTGCardInstance * card = NULL);
|
||||||
void increaseTheCost(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
|
class ABushidoAbility: public MTGAbility
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ class GameObserver{
|
|||||||
Player * currentlyActing();
|
Player * currentlyActing();
|
||||||
GameObserver(WResourceManager* output = 0, JGE* input = 0);
|
GameObserver(WResourceManager* output = 0, JGE* input = 0);
|
||||||
virtual ~GameObserver();
|
virtual ~GameObserver();
|
||||||
|
int waitingGameStateCheck;
|
||||||
void gameStateBasedEffects();
|
void gameStateBasedEffects();
|
||||||
void enchantmentStatus();
|
void enchantmentStatus();
|
||||||
void Affinity();
|
void Affinity();
|
||||||
|
|||||||
@@ -193,9 +193,17 @@ public:
|
|||||||
int CantBeTargetby(MTGCardInstance * card);
|
int CantBeTargetby(MTGCardInstance * card);
|
||||||
|
|
||||||
vector<TargetChooser *>cantBeBlockedBys;
|
vector<TargetChooser *>cantBeBlockedBys;
|
||||||
|
vector<TargetChooser *>cantBeBlockerOfs;
|
||||||
|
vector<MTGCardInstance *>cantBeBlockerOfCards;
|
||||||
int addCantBeBlockedBy(TargetChooser * tc);
|
int addCantBeBlockedBy(TargetChooser * tc);
|
||||||
int removeCantBeBlockedBy(TargetChooser *tc, int erase = 0);
|
int removeCantBeBlockedBy(TargetChooser *tc, int erase = 0);
|
||||||
int cantBeBlockedBy(MTGCardInstance * card);
|
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);
|
void copy(MTGCardInstance * card);
|
||||||
|
|
||||||
|
|||||||
@@ -3566,6 +3566,26 @@ int AAlterCost::addToGame()
|
|||||||
return MTGAbility::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()
|
int AAlterCost::testDestroy()
|
||||||
{
|
{
|
||||||
MTGCardInstance * _target = (MTGCardInstance *)target;
|
MTGCardInstance * _target = (MTGCardInstance *)target;
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ GameObserver::GameObserver(WResourceManager *output, JGE* input)
|
|||||||
mLayers = NULL;
|
mLayers = NULL;
|
||||||
mTrash = new Trash();
|
mTrash = new Trash();
|
||||||
mDeckManager = new DeckManager();
|
mDeckManager = new DeckManager();
|
||||||
|
waitingGameStateCheck = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GamePhase GameObserver::getCurrentGamePhase()
|
GamePhase GameObserver::getCurrentGamePhase()
|
||||||
@@ -581,7 +582,13 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
{
|
{
|
||||||
if(getCurrentTargetChooser() && int(getCurrentTargetChooser()->getNbTargets()) == getCurrentTargetChooser()->maxtargets)
|
if(getCurrentTargetChooser() && int(getCurrentTargetChooser()->getNbTargets()) == getCurrentTargetChooser()->maxtargets)
|
||||||
getCurrentTargetChooser()->done = true;
|
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
|
//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
|
//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())
|
if (getCurrentTargetChooser() || mLayers->actionLayer()->isWaitingForAnswer())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
waitingGameStateCheck = 0;
|
||||||
////////////////////////
|
////////////////////////
|
||||||
//---apply damage-----//
|
//---apply damage-----//
|
||||||
//after combat effects//
|
//after combat effects//
|
||||||
|
|||||||
@@ -2760,7 +2760,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
return NULL; //TODO
|
return NULL; //TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
//Can't be blocked by...
|
//Can't be blocked by...need cantdefendagainst(
|
||||||
vector<string> splitCantBlock = parseBetween(s, "cantbeblockedby(", ")");
|
vector<string> splitCantBlock = parseBetween(s, "cantbeblockedby(", ")");
|
||||||
if (splitCantBlock.size())
|
if (splitCantBlock.size())
|
||||||
{
|
{
|
||||||
@@ -2779,7 +2779,29 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
}
|
}
|
||||||
return NULL; //TODO
|
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
|
//affinity based on targetchooser
|
||||||
vector<string> splitNewAffinity = parseBetween(s, "affinity(", ")");
|
vector<string> splitNewAffinity = parseBetween(s, "affinity(", ")");
|
||||||
if (splitNewAffinity.size())
|
if (splitNewAffinity.size())
|
||||||
@@ -4835,8 +4857,8 @@ void ListMaintainerAbility::updateTargets()
|
|||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
Player * p = game->players[i];
|
Player * p = game->players[i];
|
||||||
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library };
|
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack };
|
||||||
for (int k = 0; k < 4; k++)
|
for (int k = 0; k < 5; k++)
|
||||||
{
|
{
|
||||||
MTGGameZone * zone = zones[k];
|
MTGGameZone * zone = zones[k];
|
||||||
if (canTarget(zone))
|
if (canTarget(zone))
|
||||||
@@ -4907,8 +4929,8 @@ void ListMaintainerAbility::checkTargets()
|
|||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
Player * p = game->players[i];
|
Player * p = game->players[i];
|
||||||
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library };
|
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack };
|
||||||
for (int k = 0; k < 4; k++)
|
for (int k = 0; k < 5; k++)
|
||||||
{
|
{
|
||||||
MTGGameZone * zone = zones[k];
|
MTGGameZone * zone = zones[k];
|
||||||
if (canTarget(zone))
|
if (canTarget(zone))
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ int MTGCardInstance::isInPlay(GameObserver* game)
|
|||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
MTGGameZone * zone = game->players[i]->game->inPlay;
|
MTGGameZone * zone = game->players[i]->game->inPlay;
|
||||||
if (zone->hasCard(this))
|
if (zone->hasCard(this) && !isPhased)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -609,6 +609,10 @@ int MTGCardInstance::canBlock(MTGCardInstance * opponent)
|
|||||||
return 0;
|
return 0;
|
||||||
if (opponent->cantBeBlockedBy(this))
|
if (opponent->cantBeBlockedBy(this))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (this->cantBeBlockerOf(opponent))
|
||||||
|
return 0;
|
||||||
|
if (this->cantBeBlockerOfCard(opponent))
|
||||||
|
return 0;
|
||||||
if (opponent->basicAbilities[(int)Constants::UNBLOCKABLE])
|
if (opponent->basicAbilities[(int)Constants::UNBLOCKABLE])
|
||||||
return 0;
|
return 0;
|
||||||
if (opponent->basicAbilities[(int)Constants::ONEBLOCKER] && opponent->blocked)
|
if (opponent->basicAbilities[(int)Constants::ONEBLOCKER] && opponent->blocked)
|
||||||
@@ -1044,7 +1048,69 @@ int MTGCardInstance::cantBeBlockedBy(MTGCardInstance * card)
|
|||||||
}
|
}
|
||||||
return 0;
|
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 */
|
/* Choose a sound sample to associate to that card */
|
||||||
const string& MTGCardInstance::getSample()
|
const string& MTGCardInstance::getSample()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user