Fixed primitives, fixed "proliferate" target chooser, improved "cycled" and "discarded" triggers, added new keywords "pcycledcount" and "ocycledcount" to calculate how may cards have been cycled this turn from a specific player, added new menu choices to instantly select/deselect and confirm all the possible targets (in any zone) during the target selection of an ability (e.g. Proliferation ability can target a lot of permanents and players so using that menu choice all the targets will be instantly chosen and then the current player will be able to remove any of them or confirm the entire selection).

This commit is contained in:
Vittorio Alfieri
2021-10-13 17:39:48 +02:00
parent 371d4c9f85
commit fbcb1feb88
17 changed files with 96 additions and 37 deletions

View File

@@ -109,8 +109,10 @@ int AIAction::clickMultiAct(vector<Targetable*>& actionTargets)
{
if (MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(actionTargets[k]))
{
if(k+1 == int(actionTargets.size()))
if(k+1 == int(actionTargets.size())){
tc->done = true;
tc->autoChoice = false;
}
g->cardClick(card);
}
}

View File

@@ -1972,6 +1972,7 @@ int AIPlayerBaka::createAbilityTargets(MTGAbility * a, MTGCardInstance * c, Rank
if(a->getActionTc()->getNbTargets() && a->getActionTc()->attemptsToFill > 4)
{
a->getActionTc()->done = true;
a->getActionTc()->autoChoice = false;
return 0;
}
while(potentialTargets.size())

View File

@@ -191,7 +191,7 @@ void ActionLayer::Update(float dt)
without this, the game locks into a freeze state while you try to select the targets and dont have enough to
fill the maxtargets list.
*/
if (int(ae->getActionTc()->getNbTargets()) == countTargets)//if the amount of targets is equal the all we can target
if (int(ae->getActionTc()->getNbTargets()) == countTargets && !ae->getActionTc()->autoChoice)//if the amount of targets is equal the all we can target
{
ae->getActionTc()->done = true;//were done
ae->getActionTc()->source->getObserver()->cardClick(ae->getActionTc()->source, 0, false);//click source.

View File

@@ -441,6 +441,7 @@ bool MTGRevealingCards::CheckUserInput(JButton key)
if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS))
{
tc->done = true;
tc->autoChoice = false;
tc->forceTargetListReadyByPlayer = 1;
//this is for when we have <upto:x> targets but only want to move Y targets, it allows us to
//tell the targetchooser we are done.
@@ -749,6 +750,7 @@ bool MTGScryCards::CheckUserInput(JButton key)
if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS))
{
tc->done = true;
tc->autoChoice = false;
tc->forceTargetListReadyByPlayer = 1;
if (!abilitySecond && !tc->getNbTargets() && tc->source)
{

View File

@@ -513,6 +513,7 @@ int CycleCost::doPay()
WEvent * e2 = NEW WEventCardCycle(_source);
game->receiveEvent(e2);
_source->controller()->game->putInGraveyard(_source);
_source->controller()->cycledCount++;
if (tc)
tc->initTargets();
return 1;

View File

@@ -215,8 +215,10 @@ void GameObserver::nextGamePhase()
currentPlayer->nonCombatDamage = 0;
currentPlayer->drawCounter = 0;
currentPlayer->raidcount = 0;
currentPlayer->cycledCount = 0;
currentPlayer->dealsdamagebycombat = 0; //clear check for restriction
currentPlayer->opponent()->raidcount = 0;
currentPlayer->opponent()->cycledCount = 0;
currentPlayer->prowledTypes.clear();
currentPlayer->opponent()->damageCount = 0; //added to clear odcount
currentPlayer->opponent()->nonCombatDamage = 0;
@@ -322,6 +324,7 @@ void GameObserver::userRequestNextGamePhase(bool allowInterrupt, bool log)
if(getCurrentTargetChooser() && getCurrentTargetChooser()->maxtargets == 1000)
{
getCurrentTargetChooser()->done = true;
getCurrentTargetChooser()->autoChoice = false;
if(getCurrentTargetChooser()->source)
cardClick(getCurrentTargetChooser()->source, 0, false);
}
@@ -613,8 +616,10 @@ void GameObserver::Update(float dt)
//Handles game state based effects
void GameObserver::gameStateBasedEffects()
{
if(getCurrentTargetChooser() && int(getCurrentTargetChooser()->getNbTargets()) == getCurrentTargetChooser()->maxtargets)
if(getCurrentTargetChooser() && int(getCurrentTargetChooser()->getNbTargets()) == getCurrentTargetChooser()->maxtargets){
getCurrentTargetChooser()->done = true;
getCurrentTargetChooser()->autoChoice = false;
}
/////////////////////////////////////
for (int d = 0; d < 2; d++)
{

View File

@@ -959,8 +959,14 @@ void GameStateDuel::Update(float dt)
if(game->getCurrentGamePhase() == MTG_PHASE_COMBATATTACKERS && game->currentlyActing() == (Player*)game->currentPlayer){ // During attack phase it shows a button to toggle all creatures to attack mode
menu->Add(MENUITEM_TOGGLEATTACK_ALL_CREATURES, "Toggle Attack all Creatures");
}
if(game->getCurrentTargetChooser() && game->getCurrentTargetChooser()->source->controller() == game->currentlyActing())
menu->Add(MENUITEM_SELECT_ALL, "Select all possible targets");
if(game->getCurrentTargetChooser() && game->getCurrentTargetChooser()->source->controller() == game->currentlyActing()){
if(game->getCurrentTargetChooser()->getNbTargets() < 1)
menu->Add(MENUITEM_TOGGLE_SELECT_ALL, "Select all Targets");
else {
menu->Add(MENUITEM_TOGGLE_SELECT_ALL, "Remove Selection");
menu->Add(MENUITEM_CONFIRM_SELECT_ALL, "Confirm Selection");
}
}
menu->Add(MENUITEM_MAIN_MENU, "Back to main menu");
#ifdef TESTSUITE
menu->Add(MENUITEM_UNDO, "Undo");
@@ -1712,20 +1718,37 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
menu->Close();
setGamePhase(DUEL_STATE_CANCEL);
break;
case MENUITEM_SELECT_ALL:
if(game->getCurrentTargetChooser() && game->getCurrentTargetChooser()->source && game->getCurrentTargetChooser()->source->isInPlay(game) && game->getCurrentTargetChooser()->canTarget(game->getCurrentTargetChooser()->source))
game->cardClick(game->getCurrentTargetChooser()->source, game->getCurrentTargetChooser()->source);
if(game->getCurrentTargetChooser() && game->getCurrentTargetChooser()->canTarget(game->players[0]))
game->cardClick(NULL, game->players[0]);
if(game->getCurrentTargetChooser() && game->getCurrentTargetChooser()->canTarget(game->players[1]))
game->cardClick(NULL, game->players[1]);
for(unsigned int i = 0; i < game->players[1]->inPlay()->cards.size(); i++){
if(game->getCurrentTargetChooser() && game->getCurrentTargetChooser()->canTarget(game->players[1]->inPlay()->cards[i]))
game->cardClick(game->players[1]->inPlay()->cards[i], game->players[1]->inPlay()->cards[i]);
case MENUITEM_TOGGLE_SELECT_ALL:
if(game->getCurrentTargetChooser() && game->getCurrentTargetChooser()->getNbTargets() < 1){
for (int j = 0; j < 2; ++j){
if(game->getCurrentTargetChooser()->canTarget(game->players[j]) && game->getCurrentTargetChooser()->getNbTargets() < (unsigned int) game->getCurrentTargetChooser()->maxtargets)
game->getCurrentTargetChooser()->addTarget(game->players[j]);
MTGGameZone * zones[] = { game->players[j]->game->inPlay, game->players[j]->game->graveyard, game->players[j]->game->hand, game->players[j]->game->library, game->players[j]->game->exile, game->players[j]->game->stack, game->players[j]->game->commandzone, game->players[j]->game->sideboard, game->players[j]->game->reveal };
for (int k = 0; k < 9; k++){
for(unsigned int i = 0; i < zones[k]->cards.size(); i++){
if(game->getCurrentTargetChooser()->canTarget(zones[k]->cards[i]) && game->getCurrentTargetChooser()->getNbTargets() < (unsigned int) game->getCurrentTargetChooser()->maxtargets)
game->getCurrentTargetChooser()->addTarget(zones[k]->cards[i]);
}
}
}
if(game->getCurrentTargetChooser()){
game->getCurrentTargetChooser()->done = false;
game->getCurrentTargetChooser()->autoChoice = true;
}
} else if(game->getCurrentTargetChooser()){
game->getCurrentTargetChooser()->initTargets();
game->getCurrentTargetChooser()->done = false;
game->getCurrentTargetChooser()->autoChoice = false;
}
for(unsigned int i = 0; i < game->players[0]->inPlay()->cards.size(); i++){
if(game->getCurrentTargetChooser() && game->getCurrentTargetChooser()->source != game->players[0]->inPlay()->cards[i] && game->getCurrentTargetChooser()->canTarget(game->players[0]->inPlay()->cards[i]))
game->cardClick(game->players[0]->inPlay()->cards[i], game->players[0]->inPlay()->cards[i]);
menu->Close();
setGamePhase(DUEL_STATE_CANCEL);
break;
case MENUITEM_CONFIRM_SELECT_ALL:
if(game->getCurrentTargetChooser()){
game->getCurrentTargetChooser()->done = true;
game->getCurrentTargetChooser()->autoChoice = false;
if(game->getCurrentTargetChooser()->source)
game->cardClick(game->getCurrentTargetChooser()->source, game->getCurrentTargetChooser()->source);
}
menu->Close();
setGamePhase(DUEL_STATE_CANCEL);

View File

@@ -1353,11 +1353,11 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string, int id, Spell
//Card is Discarded
if (TargetChooser * tc = parseSimpleTC(s, "discarded", card))
return NEW TrCardDiscarded(observer, id, card, tc, once);
return NEW TrCardDiscarded(observer, id, card, tc, once, limitOnceATurn);
//Card is cycled
if (TargetChooser * tc = parseSimpleTC(s, "cycled", card))
return NEW TrCardDiscarded(observer, id, card, tc, once, true);
return NEW TrCardDiscarded(observer, id, card, tc, once, limitOnceATurn, true);
//Card Damaging non combat current controller
if (TargetChooser * tc = parseSimpleTC(s, "noncombatdamageof", card))

View File

@@ -47,6 +47,7 @@ Player::Player(GameObserver *observer, string file, string fileSmall, MTGDeck *
forcefield = 0;
dealsdamagebycombat = 0;
raidcount = 0;
cycledCount = 0;
handmodifier = 0;
snowManaG = 0;
snowManaR = 0;

View File

@@ -1241,6 +1241,7 @@ TargetChooser::TargetChooser(GameObserver *observer, MTGCardInstance * card, int
other = _other;
targetMin = _targetMin;
done = false;
autoChoice = false;
attemptsToFill = 0;
if(source)
Owner = source->controller();
@@ -2201,7 +2202,9 @@ bool ProliferateChooser::canTarget(Targetable * target, bool withoutProtections)
}
else if (MTGCardInstance * card = dynamic_cast<MTGCardInstance*>(target))
{
if (source && card->isInPlay(observer) && !withoutProtections)
if(!observer || !card->isInPlay(observer))
return false;
if (source && !withoutProtections)
{
if (card->has(Constants::SHROUD)) return source->bypassTC;
if (card->protectedAgainst(source)) return source->bypassTC;
@@ -2212,7 +2215,7 @@ bool ProliferateChooser::canTarget(Targetable * target, bool withoutProtections)
return source->bypassTC;
}
}
if(card->counters && card->counters->counters.empty())
if(!card->counters || (card->counters && card->counters->counters.empty()))
return false;
return true;
}

View File

@@ -1157,6 +1157,10 @@ void WParsedInt::init(string s, Spell * spell, MTGCardInstance * card)
intValue++;
}
}
else if (s == "pcycledcount" || s == "ocycledcount") //return how may cards have been cycled this turn from a specific player.
{
intValue = (s == "pcycledcount")?card->controller()->cycledCount:card->controller()->opponent()->cycledCount;
}
else //Continue parsing in another method to avoid compiler C1061 error.
{
extendedParse(s, spell, card);