Fixed some primitives from issue #1085 and from Discord channel, fixed all curses primitives and targets, added new keywords "oppotgt" and "ctrltgt" to check wich player has been targeted from a card, fixed an issue on "chooseaname" ability.
This commit is contained in:
@@ -3817,7 +3817,7 @@ GenericRollDie::~GenericRollDie()
|
||||
|
||||
//set die result
|
||||
AASetDie::AASetDie(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * _target, int _side, int _diefaces, string toAlter):
|
||||
InstantAbility(observer, id, source),side(_side), diefaces(_diefaces), abilityToAlter(toAlter)
|
||||
InstantAbility(observer, id, source), side(_side), diefaces(_diefaces), abilityToAlter(toAlter)
|
||||
{
|
||||
this->target = _target;
|
||||
abilityAltered = NULL;
|
||||
@@ -3833,12 +3833,12 @@ int AASetDie::resolve()
|
||||
_target->dieNumFaces = diefaces;
|
||||
WEvent * e = NEW WEventCardRollDie(_target, source->controller()->getDisplayName());
|
||||
game->receiveEvent(e);
|
||||
vector<string>Win = parseBetween(abilityToAlter,"winability "," winabilityend");
|
||||
vector<string>Win = parseBetween(abilityToAlter, "winability ", " winabilityend");
|
||||
if(Win.size())
|
||||
{
|
||||
abilityWin = Win[1];
|
||||
}
|
||||
vector<string>Lose = parseBetween(abilityToAlter,"loseability "," loseabilityend");
|
||||
vector<string>Lose = parseBetween(abilityToAlter, "loseability ", " loseabilityend");
|
||||
if(Lose.size())
|
||||
{
|
||||
abilityLose = Lose[1];
|
||||
@@ -3860,14 +3860,14 @@ int AASetDie::resolve()
|
||||
abilityAltered->addToGame();
|
||||
}
|
||||
msg << "Result is: " << roll << ". You Won The Die Roll";
|
||||
MTGAbility * message = NEW MTGEventText(game,this->GetId(), source, msg.str());
|
||||
MTGAbility * message = NEW MTGEventText(game, this->GetId(), source, msg.str());
|
||||
message->oneShot = true;
|
||||
message->addToGame();
|
||||
}
|
||||
else if(abilityWin.size() && !abilityLose.size())
|
||||
{
|
||||
msg << "Result is: " << roll << ". You Lost The Die Roll";
|
||||
MTGAbility * message = NEW MTGEventText(game,this->GetId(), source, msg.str());
|
||||
MTGAbility * message = NEW MTGEventText(game, this->GetId(), source, msg.str());
|
||||
message->oneShot = true;
|
||||
message->addToGame();
|
||||
}
|
||||
@@ -3886,14 +3886,14 @@ int AASetDie::resolve()
|
||||
abilityAltered->addToGame();
|
||||
}
|
||||
msg << "Result is: " << roll << ". You Lost The Die Roll";
|
||||
MTGAbility * message = NEW MTGEventText(game,this->GetId(), source, msg.str());
|
||||
MTGAbility * message = NEW MTGEventText(game, this->GetId(), source, msg.str());
|
||||
message->oneShot = true;
|
||||
message->addToGame();
|
||||
}
|
||||
else if(abilityLose.size())
|
||||
{
|
||||
msg << "Result is: " << roll << ". You Won The Die Roll";
|
||||
MTGAbility * message = NEW MTGEventText(game,this->GetId(), source, msg.str());
|
||||
MTGAbility * message = NEW MTGEventText(game, this->GetId(), source, msg.str());
|
||||
message->oneShot = true;
|
||||
message->addToGame();
|
||||
}
|
||||
|
||||
@@ -726,7 +726,6 @@ void GameObserver::gameStateBasedEffects()
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
MTGGameZone * zone = players[i]->game->inPlay;
|
||||
players[i]->curses.clear();
|
||||
for (int j = zone->nb_cards - 1; j >= 0; j--)
|
||||
{
|
||||
MTGCardInstance * card = zone->cards[j];
|
||||
@@ -843,10 +842,6 @@ void GameObserver::gameStateBasedEffects()
|
||||
{
|
||||
card->target->enchanted = true;
|
||||
}
|
||||
if (card->playerTarget && card->hasType("curse"))
|
||||
{
|
||||
card->playerTarget->curses.push_back(card);
|
||||
}
|
||||
|
||||
//704.5n If an Aura is attached to an illegal object or player,
|
||||
//or is not attached to an object or player, that Aura is put into its owner’s graveyard.
|
||||
|
||||
@@ -2259,12 +2259,34 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
MayAbility * mainAbility = NEW MayAbility(observer, id, choose, card,true);
|
||||
if (storedAbilityString.size() && StartsWith(s, "chooseaname"))
|
||||
{
|
||||
bool chooseoppo = false;
|
||||
vector<string> splitChoose = parseBetween(s, "chooseaname ", " chooseend", false);
|
||||
if(!splitChoose.size()){
|
||||
splitChoose = parseBetween(s, "chooseanameopp ", " chooseend", false);
|
||||
chooseoppo = true;
|
||||
}
|
||||
if (splitChoose.size())
|
||||
{
|
||||
if(!chooseoppo)
|
||||
s = "chooseaname ";
|
||||
else
|
||||
s = "chooseanameopp ";
|
||||
|
||||
s.append(storedAbilityString);
|
||||
s.append(" ");
|
||||
if(splitChoose[2].empty())
|
||||
s.append(splitChoose[1]);
|
||||
else
|
||||
s.append(splitChoose[2]);
|
||||
}
|
||||
}
|
||||
MTGAbility * choose = parseChooseActionAbility(s, card, spell, target, 0, id);
|
||||
choose = NEW GenericActivatedAbility(observer, "", "", id, card, choose, NULL);
|
||||
MayAbility * mainAbility = NEW MayAbility(observer, id, choose, card, true);
|
||||
return mainAbility;
|
||||
}
|
||||
|
||||
@@ -2305,6 +2327,34 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
storedPayString.clear();
|
||||
}
|
||||
|
||||
bool chooseoppo = false;
|
||||
vector<string> splitChoose = parseBetween(s, "chooseaname ", " chooseend", false);
|
||||
if(!splitChoose.size()){
|
||||
splitChoose = parseBetween(s, "chooseanameopp ", " chooseend", false);
|
||||
chooseoppo = true;
|
||||
}
|
||||
if (splitChoose.size() && storedAbilityString.empty())
|
||||
{
|
||||
storedAbilityString = splitChoose[1];
|
||||
size_t pos1 = s.find("transforms(("); // Try to handle chooseaname ability inside ability$! or transforms keywords.
|
||||
size_t pos2 = s.find("ability$!");
|
||||
if(pos2 == string::npos)
|
||||
pos2 = s.find("winability"); // Try to handle chooseaname ability inside winability or loseability keywords.
|
||||
if(pos2 == string::npos)
|
||||
pos2 = s.find("loseability");
|
||||
size_t pos3 = s.find(splitChoose[1]);
|
||||
if((pos1 == string::npos && pos2 == string::npos) || (pos2 != string::npos && pos1 != string::npos && pos3 <= pos1 && pos3 <= pos2) ||
|
||||
(pos2 == string::npos && pos1 != string::npos && pos3 <= pos1) || (pos1 == string::npos && pos2 != string::npos && pos3 <= pos2)){
|
||||
s = splitChoose[0];
|
||||
if(!chooseoppo)
|
||||
s.append("chooseaname ");
|
||||
else
|
||||
s.append("chooseanameopp ");
|
||||
s.append(splitChoose[2]);
|
||||
} else
|
||||
storedAbilityString.clear();
|
||||
}
|
||||
|
||||
vector<string> splitGrant = parseBetween(s, "grant ", " grantend", false);
|
||||
if (splitGrant.size() && storedAbilityString.empty())
|
||||
{
|
||||
@@ -4540,7 +4590,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
SAFE_DELETE(parser);
|
||||
}
|
||||
Damageable * t = spell ? spell->getNextDamageableTarget() : NULL;
|
||||
MTGAbility * a = NEW AASetHand(observer, id, card, t, hand, NULL, who);
|
||||
MTGAbility * a = NEW AASetHand(observer, id, card, t, hand, NULL, who);
|
||||
a->oneShot = 1;
|
||||
return a;
|
||||
}
|
||||
@@ -5751,37 +5801,38 @@ MTGAbility * AbilityFactory::parseUpkeepAbility(string s,MTGCardInstance * card,
|
||||
|
||||
MTGAbility * AbilityFactory::parsePhaseActionAbility(string s,MTGCardInstance * card,Spell * spell,MTGCardInstance * target, int restrictions,int id)
|
||||
{
|
||||
vector<string> splitActions = parseBetween(s, "[", "]");
|
||||
if (!splitActions.size())
|
||||
vector<string> splitActions = parseBetween(s, "[", "]");
|
||||
if (!splitActions.size())
|
||||
{
|
||||
DebugTrace("MTGABILITY:Parsing Error " << s);
|
||||
return NULL;
|
||||
}
|
||||
string s1 = splitActions[1];
|
||||
int phase = MTG_PHASE_UPKEEP;
|
||||
for (int i = 0; i < NB_MTG_PHASES; i++)
|
||||
{
|
||||
string phaseStr = Constants::MTGPhaseCodeNames[i];
|
||||
if (s1.find(phaseStr) != string::npos)
|
||||
{
|
||||
DebugTrace("MTGABILITY:Parsing Error " << s);
|
||||
return NULL;
|
||||
}
|
||||
string s1 = splitActions[1];
|
||||
int phase = MTG_PHASE_UPKEEP;
|
||||
for (int i = 0; i < NB_MTG_PHASES; i++)
|
||||
{
|
||||
string phaseStr = Constants::MTGPhaseCodeNames[i];
|
||||
if (s1.find(phaseStr) != string::npos)
|
||||
{
|
||||
phase = PhaseRing::phaseStrToInt(phaseStr);
|
||||
break;
|
||||
}
|
||||
phase = PhaseRing::phaseStrToInt(phaseStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool opponentturn = (s1.find("my") == string::npos);
|
||||
bool myturn = (s1.find("opponent") == string::npos);
|
||||
bool sourceinPlay = (s1.find("sourceinplay") != string::npos);
|
||||
bool checkexile = (s1.find("checkex") != string::npos);
|
||||
bool next = (s1.find("next") == string::npos); //Why is this one the opposite of the two others? That's completely inconsistent
|
||||
bool once = (s1.find("once") != string::npos);
|
||||
bool opponentturn = (s1.find("my") == string::npos);
|
||||
bool myturn = (s1.find("opponent") == string::npos);
|
||||
bool sourceinPlay = (s1.find("sourceinplay") != string::npos);
|
||||
bool checkexile = (s1.find("checkex") != string::npos);
|
||||
bool next = (s1.find("next") == string::npos); //Why is this one the opposite of the two others? That's completely inconsistent
|
||||
bool once = (s1.find("once") != string::npos);
|
||||
|
||||
MTGCardInstance * _target = NULL;
|
||||
if (spell)
|
||||
_target = spell->getNextCardTarget();
|
||||
if(!_target)
|
||||
_target = target;
|
||||
return NEW APhaseActionGeneric(observer, id, card,_target, trim(splitActions[2]), restrictions, phase,sourceinPlay,next,myturn,opponentturn,once,checkexile);
|
||||
MTGCardInstance * _target = NULL;
|
||||
if (spell)
|
||||
_target = spell->getNextCardTarget();
|
||||
if(!_target)
|
||||
_target = target;
|
||||
|
||||
return NEW APhaseActionGeneric(observer, id, card, _target, trim(splitActions[2]), restrictions, phase, sourceinPlay, next, myturn, opponentturn, once, checkexile);
|
||||
}
|
||||
|
||||
MTGAbility * AbilityFactory::parseChooseActionAbility(string s,MTGCardInstance * card,Spell *,MTGCardInstance * target, int, int id)
|
||||
|
||||
@@ -2289,12 +2289,18 @@ bool TriggerTargetChooser::equals(TargetChooser * tc)
|
||||
}
|
||||
|
||||
/*my curses */
|
||||
bool myCursesChooser::canTarget(Targetable * target,bool)
|
||||
bool myCursesChooser::canTarget(Targetable * target, bool)
|
||||
{
|
||||
for(unsigned int i = 0;i < source->controller()->curses.size();++i)
|
||||
for (int j = source->controller()->game->battlefield->nb_cards - 1; j >= 0; --j)
|
||||
{
|
||||
MTGCardInstance * compare = source->controller()->curses[i];
|
||||
if(compare == dynamic_cast<MTGCardInstance*>(target))
|
||||
MTGCardInstance * compare = source->controller()->game->battlefield->cards[j];
|
||||
if(compare->hasType("Curse") && compare->playerTarget == source->controller() && compare == dynamic_cast<MTGCardInstance*>(target))
|
||||
return true;
|
||||
}
|
||||
for (int j = source->controller()->opponent()->game->battlefield->nb_cards - 1; j >= 0; --j)
|
||||
{
|
||||
MTGCardInstance * compare = source->controller()->opponent()->game->battlefield->cards[j];
|
||||
if(compare->hasType("Curse") && compare->playerTarget == source->controller() && compare == dynamic_cast<MTGCardInstance*>(target))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -572,7 +572,19 @@ void WParsedInt::init(string s, Spell * spell, MTGCardInstance * card)
|
||||
}
|
||||
else if (s == "targetedcurses")
|
||||
{
|
||||
intValue = (card->playerTarget)?card->playerTarget->curses.size():0;
|
||||
intValue = 0;
|
||||
for (int j = card->controller()->game->battlefield->nb_cards - 1; j >= 0; --j)
|
||||
{
|
||||
MTGCardInstance * curse = card->controller()->game->battlefield->cards[j];
|
||||
if (curse->hasType("Curse") && curse->playerTarget == card->playerTarget)
|
||||
intValue++;
|
||||
}
|
||||
for (int j = card->controller()->opponent()->game->battlefield->nb_cards - 1; j >= 0; --j)
|
||||
{
|
||||
MTGCardInstance * curse = card->controller()->opponent()->game->battlefield->cards[j];
|
||||
if (curse->hasType("Curse") && curse->playerTarget == card->playerTarget)
|
||||
intValue++;
|
||||
}
|
||||
}
|
||||
else if (s == "lifetotal" || s == "opponentlifetotal")
|
||||
{
|
||||
@@ -820,9 +832,9 @@ void WParsedInt::init(string s, Spell * spell, MTGCardInstance * card)
|
||||
{
|
||||
intValue = (s == "countedamount")?target->CountedObjects:target->CountedObjectsB;
|
||||
}
|
||||
else if (s == "kicked" || s == "handsize")
|
||||
else if (s == "handsize" || s == "ohandsize")
|
||||
{
|
||||
intValue = (s == "kicked")?card->kicked:target->controller()->handsize;
|
||||
intValue = (s == "ohandsize")?card->controller()->opponent()->handsize:target->controller()->handsize;
|
||||
}
|
||||
else if (s == "olandg" || s == "olandu")
|
||||
{
|
||||
@@ -1650,6 +1662,17 @@ void WParsedInt::extendedParse(string s, Spell * spell, MTGCardInstance * card)
|
||||
{
|
||||
intValue = (s == "iscommander")?card->isCommander:card->isRingBearer;
|
||||
}
|
||||
else if (s == "oppotgt" || s == "ctrltgt") // Return 1 if card targeted the opponent -- Return 1 if card targeted its controller
|
||||
{
|
||||
intValue = 0;
|
||||
Player* p = (s == "oppotgt")?card->controller()->opponent():card->controller();
|
||||
if(card->playerTarget == p)
|
||||
intValue = 1;
|
||||
}
|
||||
else if (s == "kicked")
|
||||
{
|
||||
intValue = card->kicked;
|
||||
}
|
||||
else if(!intValue)//found nothing, try parsing a atoi
|
||||
{
|
||||
intValue = atoi(s.c_str());
|
||||
|
||||
Reference in New Issue
Block a user