Fixed Etchings of the Chosen (issue #1051 by @ranger7271), added primitives with choose card name, added two keywords "chooseaname" and "chooseanameopp" to choose a card name ("chosenname" and "lastchoosenname") between your cards or opponent cards, added a keyword "[attached]" to target equipment attached to a permanent.
This commit is contained in:
@@ -2739,14 +2739,15 @@ AAProliferate::~AAProliferate()
|
||||
{
|
||||
}
|
||||
//
|
||||
//choosing a type or color
|
||||
GenericChooseTypeColor::GenericChooseTypeColor(GameObserver* observer, int id, MTGCardInstance * source, Targetable *,string _toAdd,bool chooseColor,bool nonwall, ManaCost * cost) :
|
||||
ActivatedAbility(observer, id, source, cost, 0), baseAbility(_toAdd),chooseColor(chooseColor),ANonWall(nonwall)
|
||||
//choosing a type or color or name
|
||||
GenericChooseTypeColorName::GenericChooseTypeColorName(GameObserver* observer, int id, MTGCardInstance * source, Targetable *, string _toAdd, bool chooseColor, bool chooseName, bool chooseOppName, bool nonwall, bool nonbasicland, bool nonland, ManaCost * cost) :
|
||||
ActivatedAbility(observer, id, source, cost, 0), baseAbility(_toAdd),chooseColor(chooseColor),chooseName(chooseName),chooseOppName(chooseOppName),ANonWall(nonwall),ANonBasicLand(nonbasicland),ANonLand(nonland)
|
||||
{
|
||||
this->GetId();
|
||||
setColor = NULL;
|
||||
setName = NULL;
|
||||
}
|
||||
int GenericChooseTypeColor::resolve()
|
||||
int GenericChooseTypeColorName::resolve()
|
||||
{
|
||||
if (!target)
|
||||
return 0;
|
||||
@@ -2762,6 +2763,33 @@ int GenericChooseTypeColor::resolve()
|
||||
SAFE_DELETE(setColor);
|
||||
}
|
||||
}
|
||||
else if(chooseName || chooseOppName)
|
||||
{
|
||||
vector<string> names;
|
||||
Player* p = (chooseName)?source->controller():source->controller()->opponent();
|
||||
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile, p->game->commandzone, p->game->sideboard, p->game->reveal };
|
||||
for (int k = 0; k < 9; k++){
|
||||
MTGGameZone * zone = zones[k];
|
||||
for (int j = zone->nb_cards - 1; j >= 0; --j){
|
||||
if ((!ANonBasicLand || (!zone->cards[j]->hasType(Subtypes::TYPE_BASIC) && !zone->cards[j]->hasType(Subtypes::TYPE_LAND))) && (!ANonLand || !zone->cards[j]->hasType(Subtypes::TYPE_LAND))){
|
||||
bool added = false;
|
||||
for (int i = names.size() - 1; i >= 0; --i)
|
||||
if(names[i] == zone->cards[j]->name)
|
||||
added = true;
|
||||
if(!added)
|
||||
names.push_back(zone->cards[j]->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < names.size(); ++i){
|
||||
string menu = names[i];
|
||||
setName = NEW AASetNameChosen(game, game->mLayers->actionLayer()->getMaxId(), source, (MTGCardInstance*)target, names[i], menu, baseAbility);
|
||||
MTGAbility * set = setName->clone();
|
||||
set->oneShot = true;
|
||||
selection.push_back(set);
|
||||
SAFE_DELETE(setName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vector<string> values = MTGAllCards::getCreatureValuesById();
|
||||
@@ -2789,21 +2817,23 @@ int GenericChooseTypeColor::resolve()
|
||||
|
||||
}
|
||||
|
||||
const string GenericChooseTypeColor::getMenuText()
|
||||
const string GenericChooseTypeColorName::getMenuText()
|
||||
{
|
||||
if(chooseColor)
|
||||
return "Choose a color";
|
||||
if(chooseName || chooseOppName)
|
||||
return "Choose a name";
|
||||
else
|
||||
return "Choose a type";
|
||||
}
|
||||
|
||||
GenericChooseTypeColor * GenericChooseTypeColor::clone() const
|
||||
GenericChooseTypeColorName * GenericChooseTypeColorName::clone() const
|
||||
{
|
||||
GenericChooseTypeColor * a = NEW GenericChooseTypeColor(*this);
|
||||
GenericChooseTypeColorName * a = NEW GenericChooseTypeColorName(*this);
|
||||
return a;
|
||||
}
|
||||
|
||||
GenericChooseTypeColor::~GenericChooseTypeColor()
|
||||
GenericChooseTypeColorName::~GenericChooseTypeColorName()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2922,6 +2952,64 @@ AASetTypeChosen::~AASetTypeChosen()
|
||||
{
|
||||
}
|
||||
|
||||
//set name choosen
|
||||
AASetNameChosen::AASetNameChosen(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * _target,string _name ,string _menu,string toAlter):
|
||||
InstantAbility(observer, id, source),name(_name), abilityToAlter(toAlter), menutext(_menu)
|
||||
{
|
||||
this->target = _target;
|
||||
abilityAltered = NULL;
|
||||
}
|
||||
int AASetNameChosen::resolve()
|
||||
{
|
||||
MTGCardInstance * _target = (MTGCardInstance *)target;
|
||||
string nameChoosen = menutext;
|
||||
_target->chooseaname = nameChoosen;
|
||||
_target->controller()->lastChosenName = nameChoosen;
|
||||
|
||||
if(abilityToAlter.size())
|
||||
{
|
||||
AbilityFactory af(game);
|
||||
abilityAltered = af.parseMagicLine(abilityToAlter, 0, NULL, _target);
|
||||
if(abilityAltered->oneShot)
|
||||
{
|
||||
abilityAltered->resolve();
|
||||
SAFE_DELETE(abilityAltered);
|
||||
}
|
||||
else
|
||||
{
|
||||
abilityAltered->target = _target;
|
||||
MayAbility * dontAdd = dynamic_cast<MayAbility*>(abilityAltered);
|
||||
if (!dontAdd)
|
||||
{
|
||||
_target->cardsAbilities.push_back(abilityAltered);
|
||||
for(unsigned int j = 0;j < _target->cardsAbilities.size();++j)
|
||||
{
|
||||
if(_target->cardsAbilities[j] == this)
|
||||
_target->cardsAbilities.erase(_target->cardsAbilities.begin() + j);
|
||||
}
|
||||
}
|
||||
|
||||
abilityAltered->addToGame();
|
||||
}
|
||||
_target->skipDamageTestOnce = true;//some cards rely on this ability updating before damage test are run. otherwise they die before toughnes bonus applies.
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const string AASetNameChosen::getMenuText()
|
||||
{
|
||||
return menutext.c_str();
|
||||
}
|
||||
|
||||
AASetNameChosen * AASetNameChosen::clone() const
|
||||
{
|
||||
return NEW AASetNameChosen(*this);
|
||||
}
|
||||
|
||||
AASetNameChosen::~AASetNameChosen()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
//choosing flip coin
|
||||
GenericFlipACoin::GenericFlipACoin(GameObserver* observer, int id, MTGCardInstance * source, Targetable *,string _toAdd, ManaCost * cost) :
|
||||
@@ -4261,6 +4349,8 @@ int AAFlip::resolve()
|
||||
{
|
||||
if(flipStats == "myorigname" && _target->nameOrig != "")
|
||||
flipStats = _target->nameOrig; // Added to undo the copy effect at end of turn for a generic card (es. Shapeshifter transformations).
|
||||
else if(flipStats == "chosenname" && _target->chooseaname != "")
|
||||
flipStats = _target->chooseaname; // Added to allow the transformation of a card in a choosen name.
|
||||
MTGCard * fcard = MTGCollection()->getCardByName(flipStats);
|
||||
if(!fcard) return 0;
|
||||
MTGCardInstance * myFlip = NEW MTGCardInstance(fcard, _target->controller()->game);
|
||||
|
||||
@@ -31,6 +31,7 @@ CardDescriptor::CardDescriptor()
|
||||
CDcontrollerDamaged = 0;
|
||||
CDdamager = 0;
|
||||
CDgeared = 0;
|
||||
CDattached = 0;
|
||||
CDblocked = 0;
|
||||
CDcanProduceC = 0;
|
||||
CDcanProduceG = 0;
|
||||
@@ -293,7 +294,12 @@ MTGCardInstance * CardDescriptor::match(MTGCardInstance * card)
|
||||
{
|
||||
match = NULL;
|
||||
}
|
||||
|
||||
|
||||
if ((CDattached == -1 && card->parentCards.size() > 0) || (CDattached == 1 && card->parentCards.size() < 1))
|
||||
{
|
||||
match = NULL;
|
||||
}
|
||||
|
||||
if (CDblocked == -1)
|
||||
{
|
||||
if(!card->isAttacker())
|
||||
|
||||
@@ -512,6 +512,16 @@ void CardGui::Render()
|
||||
mFont->DrawString(buffer, actX - 10 * actZ, actY - (25.3f * actZ));
|
||||
mFont->SetScale(1);
|
||||
}
|
||||
if(card->chooseaname.size() && !alternate && game)
|
||||
{
|
||||
mFont->SetScale(DEFAULT_MAIN_FONT_SCALE);
|
||||
char buffer[200];
|
||||
sprintf(buffer, "%s", card->chooseaname.c_str());
|
||||
mFont->SetColor(ARGB(static_cast<unsigned char>(actA),255,215,0));//Gold indicator
|
||||
mFont->SetScale(0.8f);
|
||||
mFont->DrawString(buffer, actX - 10 * actZ, actY - (25.3f * actZ));
|
||||
mFont->SetScale(1);
|
||||
}
|
||||
if(!alternate && buff != "" && game)
|
||||
{
|
||||
mFont->SetScale(DEFAULT_MAIN_FONT_SCALE);
|
||||
@@ -1568,6 +1578,17 @@ bool CardGui::FilterCard(MTGCard * _card,string filter)
|
||||
cd.CDgeared = 1;
|
||||
}
|
||||
}
|
||||
else if (attribute.find("attached") != string::npos)
|
||||
{
|
||||
if (minus)
|
||||
{
|
||||
cd.CDattached = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cd.CDattached = 1;
|
||||
}
|
||||
}
|
||||
//creature is a level up creature
|
||||
else if (attribute.find("leveler") != string::npos)
|
||||
{
|
||||
|
||||
@@ -278,7 +278,7 @@ int Damage::resolve()
|
||||
}
|
||||
}
|
||||
|
||||
if (target->type_as_damageable == Damageable::DAMAGEABLE_MTGCARDINSTANCE && ((MTGCardInstance*)target)->hasType(Subtypes::TYPE_PLANESWALKER)){ // Fix life calculation for planeswalker damage.
|
||||
if (target->type_as_damageable == Damageable::DAMAGEABLE_MTGCARDINSTANCE && ((MTGCardInstance*)target)->hasType(Subtypes::TYPE_PLANESWALKER)){ // Fix life calculation for planeswalker damage.
|
||||
if (((MTGCardInstance*)target)->counters){
|
||||
Counters * counters = ((MTGCardInstance*)target)->counters;
|
||||
for(size_t i = 0; i < counters->counters.size(); ++i){
|
||||
|
||||
@@ -1778,7 +1778,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
}
|
||||
|
||||
|
||||
if (StartsWith(s, "chooseacolor ") || StartsWith(s, "chooseatype "))
|
||||
if (StartsWith(s, "chooseacolor ") || StartsWith(s, "chooseatype ") || StartsWith(s, "chooseaname"))
|
||||
{
|
||||
MTGAbility * choose = parseChooseActionAbility(s,card,spell,target,0,id);
|
||||
choose = NEW GenericActivatedAbility(observer, "","",id, card,choose,NULL);
|
||||
@@ -4807,7 +4807,7 @@ MTGAbility * AbilityFactory::parseChooseActionAbility(string s,MTGCardInstance *
|
||||
if (splitChooseAColor2.size())
|
||||
{
|
||||
string a1 = splitChooseAColor2[1];
|
||||
MTGAbility * a = NEW GenericChooseTypeColor(observer, id, card, target,a1,true);
|
||||
MTGAbility * a = NEW GenericChooseTypeColorName(observer, id, card, target,a1,true);
|
||||
a->oneShot = 1;
|
||||
a->canBeInterrupted = false;
|
||||
return a;
|
||||
@@ -4817,7 +4817,7 @@ MTGAbility * AbilityFactory::parseChooseActionAbility(string s,MTGCardInstance *
|
||||
if (splitChooseAType2.size())
|
||||
{
|
||||
string a1 = splitChooseAType2[1];
|
||||
MTGAbility * a = NEW GenericChooseTypeColor(observer, id, card, target,a1,false,s.find("nonwall")!=string::npos);
|
||||
MTGAbility * a = NEW GenericChooseTypeColorName(observer, id, card, target,a1,false,false,false,s.find("nonwall")!=string::npos);
|
||||
a->oneShot = 1;
|
||||
a->canBeInterrupted = false;
|
||||
return a;
|
||||
@@ -4827,7 +4827,7 @@ MTGAbility * AbilityFactory::parseChooseActionAbility(string s,MTGCardInstance *
|
||||
if (splitChooseAColor.size())
|
||||
{
|
||||
string a1 = splitChooseAColor[1];
|
||||
MTGAbility * a = NEW GenericChooseTypeColor(observer, id, card, target,a1,true);
|
||||
MTGAbility * a = NEW GenericChooseTypeColorName(observer, id, card, target,a1,true);
|
||||
a->oneShot = 1;
|
||||
a->canBeInterrupted = false;
|
||||
return a;
|
||||
@@ -4837,7 +4837,19 @@ MTGAbility * AbilityFactory::parseChooseActionAbility(string s,MTGCardInstance *
|
||||
if (splitChooseAType.size())
|
||||
{
|
||||
string a1 = splitChooseAType[1];
|
||||
MTGAbility * a = NEW GenericChooseTypeColor(observer, id, card, target,a1,false,s.find("nonwall")!=string::npos);
|
||||
MTGAbility * a = NEW GenericChooseTypeColorName(observer, id, card, target,a1,false,false,false,s.find("nonwall")!=string::npos);
|
||||
a->oneShot = 1;
|
||||
a->canBeInterrupted = false;
|
||||
return a;
|
||||
}
|
||||
//choose a name
|
||||
vector<string> splitChooseAName = parseBetween(s, "chooseaname ", " chooseend");
|
||||
vector<string> splitChooseAOppName = parseBetween(s, "chooseanameopp ", " chooseend");
|
||||
if (splitChooseAName.size() || splitChooseAOppName.size())
|
||||
{
|
||||
bool oppName = (splitChooseAOppName.size() > 0);
|
||||
string a1 = oppName?splitChooseAOppName[1]:splitChooseAName[1];
|
||||
MTGAbility * a = NEW GenericChooseTypeColorName(observer, id, card, target,a1,false,!oppName,oppName,false,s.find("nonbasicland")!=string::npos,s.find("nonland")!=string::npos);
|
||||
a->oneShot = 1;
|
||||
a->canBeInterrupted = false;
|
||||
return a;
|
||||
|
||||
@@ -261,6 +261,7 @@ void MTGCardInstance::initMTGCI()
|
||||
zpos = 0;
|
||||
chooseacolor = -1;
|
||||
chooseasubtype = "";
|
||||
chooseaname = "";
|
||||
coinSide = -1;
|
||||
lastFlipResult = -1;
|
||||
dieSide = 0;
|
||||
|
||||
@@ -51,6 +51,7 @@ Player::Player(GameObserver *observer, string file, string fileSmall, MTGDeck *
|
||||
snowManaU = 0;
|
||||
snowManaW = 0;
|
||||
snowManaC = 0;
|
||||
lastChosenName = "";
|
||||
prowledTypes.clear();
|
||||
doesntEmpty = NEW ManaCost();
|
||||
poolDoesntEmpty = NEW ManaCost();
|
||||
|
||||
@@ -607,6 +607,7 @@ void Rules::initGame(GameObserver *g, bool currentPlayerSet)
|
||||
p->monarch = initState.playerData[i].player->monarch;
|
||||
p->surveilOffset = initState.playerData[i].player->surveilOffset;
|
||||
p->devotionOffset = initState.playerData[i].player->devotionOffset;
|
||||
p->lastChosenName = initState.playerData[i].player->lastChosenName;
|
||||
if (initState.playerData[i].player->mAvatarName.size())
|
||||
{
|
||||
p->mAvatarName = initState.playerData[i].player->mAvatarName;
|
||||
|
||||
@@ -607,6 +607,17 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
||||
cd->CDgeared = 1;
|
||||
}
|
||||
}
|
||||
else if (attribute.find("attached") != string::npos)
|
||||
{
|
||||
if (minus)
|
||||
{
|
||||
cd->CDattached = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cd->CDattached = 1;
|
||||
}
|
||||
}
|
||||
//creature is a level up creature
|
||||
else if (attribute.find("leveler") != string::npos)
|
||||
{
|
||||
@@ -953,6 +964,26 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
||||
}
|
||||
}
|
||||
|
||||
if (attribute.find("chosenname") != string::npos && card->chooseaname != "")
|
||||
{
|
||||
attributefound = 1;
|
||||
cd->compareName = card->chooseaname;
|
||||
if (minus)
|
||||
cd->nameComparisonMode = COMPARISON_UNEQUAL;
|
||||
else
|
||||
cd->nameComparisonMode = COMPARISON_EQUAL;
|
||||
}
|
||||
|
||||
if (attribute.find("lastnamechosen") != string::npos && card->controller()->lastChosenName != "")
|
||||
{
|
||||
attributefound = 1;
|
||||
cd->compareName = card->controller()->lastChosenName;
|
||||
if (minus)
|
||||
cd->nameComparisonMode = COMPARISON_UNEQUAL;
|
||||
else
|
||||
cd->nameComparisonMode = COMPARISON_EQUAL;
|
||||
}
|
||||
|
||||
if (attribute.find("evictname") != string::npos && card->imprintedCards.size())
|
||||
{
|
||||
attributefound = 1;
|
||||
|
||||
Reference in New Issue
Block a user