diff --git a/CHANGELOG.md b/CHANGELOG.md index 066d1ef75..cd6b48def 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,18 +2,20 @@ ## [master] (https://github.com/WagicProject/wagic/tree/master) -### 05/09/21 -- *Committed:* Fixed bug that was not correctly showing the full Commander decks list in the deck choosing menu page, added a new gesture for Android to emulate back button pressure: now sliding from down to up for almost all screen size will trigger the back button in game (e.g. pause match in gameplay, going back from shop, and so on). ([Vitty85](https://github.com/Vitty85)) +### 06/09/21 +- *Committed:* Fixed primitives, changed type of "isFlipped" card variable from bool to int and fixed a related bug on targeting cards with "isFlipped" attribute, improved "disturb" ability (now fi you counter a card casted with disturb it correctly goes to exile), added "decayed" ability, added two new zone alias "mycommandplay" and "opponentcommandplay" for targeting Battlefield and CommandZone at the same time. ([Vitty85](https://github.com/Vitty85)) ### 04/09/21 +- *Committed:* Fixed bug that was not correctly showing the full Commander decks list in the deck choosing menu page, added a new gesture for Android to emulate back button pressure: now sliding from down to up for almost all screen size will trigger the back button in game (e.g. pause match in gameplay, going back from shop, and so on). https://github.com/WagicProject/wagic/commit/ccae9673e620b8f47aa66e9b9f25cbd79a715d2b ([Vitty85](https://github.com/Vitty85)) + - *Committed:* Fixed several primitives with "castcard" ability, fixed a bug when using "noevent" and "copied" options togheter with "namedcard" option in "castcard" ability, allowed the usage of "and!()!" ability with "namedcard" option in "castcard" ability for permanents, added "daybound" and "nightbound" abilities. https://github.com/WagicProject/wagic/commit/c211b2eaa481639725f29490d93f87797ea5a718 ([Vitty85](https://github.com/Vitty85)) +### 03/09/21 - *Committed:* Added/fixed primitives, refactored and improved almost all transforming human cards (included all the Werewolves), improved "flip ability and "doubleside" ability adding a new "backside" option, fixed a bug on "doubleside" ability for planeswalkers, added "backside=" key to CardPrimitive in order to specify the other side of double-faced cards, added "hasbackside" option to target chooser in order to find cards which have a back side, added "dualfaced" that return 1 if a card has a backside card, fixed loyalty counter ability on planeswalker flip (is was not resolving correctly), changed type of damageToController, damageToOpponent, damageToCreature, wasDealtDamage, combatdamageToOpponent from bool to int in order to retrieve those values if needed, added "totaldmg" keyword that returns the total amount of damage dealt by a creature in the current turn, added new restriction "coven in order to check if a player controls three or more creatures with different powers, added new ability "hasdisturb" when the Retrace cost of a card is a disturb cost (e.g. "Beloved Beggar"). https://github.com/WagicProject/wagic/commit/cc16db7256138febf26c1bf7fd4d9907c4f708fa ([Vitty85](https://github.com/Vitty85)) -### 03/09/21 +### 02/09/21 - *Committed:* Fixed primitives, fixed some possible crashes on Commander Format. https://github.com/WagicProject/wagic/commit/236f677f2a08d538191de5c16970340dcd39c5f0 ([Vitty85](https://github.com/Vitty85)) -### 02/09/21 - *Committed:* Added/fixed primitives, updated the "missing_cards_by_sets" folder, fixed several crash on Commander Format, fixed a possible crash using "and!()!" with "imprint", added a new macros "_REBOUND_" and "_GOAD_" related to rebound and goad abilities and refactored all cards using them, implemented a new keywords "haunt", "hasprey", "preyname" and "isprey" related the haunting ability and improved all cards using it, Added "commander" and "\*" to HINT castpriority for AI decks in order to allow the user to give a cast priority to commanders. https://github.com/WagicProject/wagic/commit/001cea95bd501ca47b6510037af2725508f321d5 ([Vitty85](https://github.com/Vitty85)) ### 31/08/21 diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index 0fd1fa4fd..6dfb4c2cb 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -17592,7 +17592,7 @@ target=creature auto=cantattack auto=cantpwattack auto=cantblock -auto={2}{W}:all(this) moveTo(exile) +auto={2}{W}:name(Exile enchanted creature) imprint text=Enchant creature -- Enchanted creature can’t attack or block. -- {2}{W}: Exile enchanted creature. mana={2}{W} type=Enchantment @@ -18541,8 +18541,8 @@ type=Instant name=Eat to Extinction target=creature,planeswalker auto=moveto(exile) -aicode=activate may moveto(mygraveyard) all(*[zpos=1]|mylibrary) -auto=name(Look) reveal:1 optionone name(Put On Top) target(*|reveal) moveto(mylibrary) optiononeend optiontwo name(put in graveyard) target(<1>*|reveal) moveto(mygraveyard) optiontwoend revealend +aicode=activate may name(Put in graveyard) target(*[zpos=1]|mylibrary) moveto(mygraveyard) +auto=name(Look) reveal:1 optionone name(Put On Top) target(*|reveal) moveto(mylibrary) optiononeend optiontwo name(put in graveyard) target(*|reveal) moveto(mygraveyard) optiontwoend revealend text=Exile target creature or planeswalker. Look at the top card of your library. You may put that card into your graveyard. mana={3}{B} type=Instant @@ -72609,8 +72609,7 @@ toughness=3 [card] name=Westgate Regent abilities=flying -auto=@targeted(this) from(*|opponentzones) restriction{type(*|opponenthand)~equalto~0}:name(Counter spell) target(*|opponentzones) fizzle -auto=@targeted(this) from(*|opponentzones) restriction{type(*|opponenthand)~morethan~0}:choice name(Discard or counter) name(Discard or counter) target(*|opponentzones) transforms((,newability[pay[[{0}]] name(Discard a card) target(*|myhand) reject?fizzle])) oneshot +auto=@targeted(this) from(*|opponentzones):choice name(Discard a card to cast this spell) name(Discard a card to cast this spell) target(*|opponentzones) transforms((,newability[if type(*|myhand)~morethan~0 then choice name(Discard a card) name(Discard a card) donothing],newability[choice name(Don't discard card) fizzle])) oneshot auto=@combatdamaged(player) from(this):name(Put 1/1 counters) counter(1/1,thatmuch) text=Flying -- Ward — Discard a card. (Whenever this creature becomes the target of a spell or ability an opponent controls, counter it unless that player discards a card.) -- Whenever Westgate Regent deals combat damage to a player, put that many +1/+1 counters on it. mana={3}{B}{B} diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index f982708c5..ded5f0a19 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -19501,7 +19501,7 @@ target=creature auto=cantattack auto=cantpwattack auto=cantblock -auto={3}{w}{w}{s}:sacrifice all(mytgt) +auto={3}{W}{W}{S}:name(Exile enchanted creature) imprint text=Enchant creature -- Enchanted creature can't attack or block. -- {3}{W}{W}, Sacrifice Choking Restraints: Exile enchanted creature. mana={2}{W} type=Enchantment diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 065993614..21355bb04 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -96,7 +96,7 @@ public: bool exerted; bool turningOver; bool isMorphed; - bool isFlipped; + int isFlipped; string MeldedFrom; bool isPhased; bool isCascaded; diff --git a/projects/mtg/include/MTGDefinitions.h b/projects/mtg/include/MTGDefinitions.h index f02db86a0..53ae26f58 100644 --- a/projects/mtg/include/MTGDefinitions.h +++ b/projects/mtg/include/MTGDefinitions.h @@ -326,7 +326,8 @@ class Constants HASDISTURB = 199, DAYBOUND = 200, NIGHTBOUND = 201, - NB_BASIC_ABILITIES = 202, + DECAYED = 202, + NB_BASIC_ABILITIES = 203, RARITY_S = 'S', //Special Rarity RARITY_M = 'M', //Mythics diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index d46a84cc2..ebf1d89ee 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -635,7 +635,7 @@ int OrderedAIAction::getEfficiency() { efficiency = 0; // AI does not have to use the doubleside ability to avoid loops but it can randomly choose to flip card and cast its back side. if(std::rand() % 2) - ats->source->isFlipped = !ats->source->isFlipped; + ats->source->isFlipped = (ats->source->isFlipped > 0)?0:1; } else if (ATokenCreator * atc = dynamic_cast(a)) { diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 77ca3accd..42a01a158 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -585,7 +585,7 @@ Interruptible(observer, id) int PutInGraveyard::resolve() { MTGGameZone * zone = card->getCurrentZone(); - if (card->basicAbilities[(int)Constants::EXILEDEATH] || card->basicAbilities[(int)Constants::GAINEDEXILEDEATH]) + if (card->basicAbilities[(int)Constants::EXILEDEATH] || card->basicAbilities[(int)Constants::GAINEDEXILEDEATH] || (card->basicAbilities[(int)Constants::HASDISTURB] && card->alternateCostPaid[ManaCost::MANA_PAID_WITH_RETRACE] == 1)) { card->basicAbilities[(int)Constants::GAINEDEXILEDEATH] = 0; card->controller()->game->putInZone(card, zone, card->owner->game->exile); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index d8af723de..a2546ad4b 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -2461,7 +2461,7 @@ AACounter::AACounter(GameObserver* observer, int id, MTGCardInstance * source, M if (target) { MTGCardInstance * _target = (MTGCardInstance *) target; - if(_target->isFlipped && _target->hasType(Subtypes::TYPE_PLANESWALKER))//is flipping pw + if(_target->isFlipped > 0 && _target->hasType(Subtypes::TYPE_PLANESWALKER))//is flipping pw return 0; AbilityFactory af(game); @@ -4606,9 +4606,9 @@ int AATurnSide::resolve() if(_target->mutation && _target->parentCards.size() > 0) return 0; // Mutated down cards cannot be turned, they will follow the fate of top-card MTGCard * fcard; MTGCardInstance* sideCard; - if(_target->controller()->isAI() && _target->isFlipped) _target->isFlipped = false; // If it's AI calling back we just have to reset isFLipped flag and then return. - if(!_target->isFlipped && _SideName == "") return 0; // No need to turn front if card has not been flipped before. - if(!_target->isFlipped){ + if(_target->controller()->isAI() && _target->isFlipped > 0) _target->isFlipped = 0; // If it's AI calling back we just have to reset isFLipped flag and then return. + if(_target->isFlipped == 0 && _SideName == "") return 0; // No need to turn front if card has not been flipped before. + if(_target->isFlipped == 0){ if(_SideName == "backside" && _target->backSide != "") _SideName = _target->backSide; // Added to allow to turn a card on its backside. fcard = MTGCollection()->getCardByName(_SideName); @@ -4673,7 +4673,7 @@ int AATurnSide::resolve() _target->formattedText = sideCard->formattedText; _target->magicText = sideCard->magicText; _target->colors = sideCard->colors; - _target->isFlipped = !_target->isFlipped; + _target->isFlipped = (_target->isFlipped > 0)?0:1; _target->mPropertiesChangedSinceLastUpdate = true; SAFE_DELETE(sideCard); return 1; @@ -4704,7 +4704,7 @@ int AAFlip::resolve() int activatedanyability = 0; MTGCardInstance * Flipper = (MTGCardInstance*)source; this->oneShot = true; - if(Flipper->isFlipped && forcetype == "") + if(Flipper->isFlipped > 0 && forcetype == "") { game->removeObserver(this); return 0; @@ -4735,7 +4735,7 @@ int AAFlip::resolve() } AbilityFactory af(game); - _target->isFlipped = true; + _target->isFlipped = 1; GameObserver * game = _target->getObserver(); if(flipStats.size()) { @@ -4929,13 +4929,13 @@ int AAFlip::testDestroy() MTGCardInstance * _target = (MTGCardInstance *) target; if(target) { - if(_target->isFlipped) + if(_target->isFlipped > 0) { this->forceDestroy = 1; //_target->getObserver()->removeObserver(this); //originally added as a safegaurd to insure the ability was removed //it's been so long and so much has changed that it appears to do nothing but cause a crash now - _target->isFlipped = false; + _target->isFlipped = 0; return 1; } } diff --git a/projects/mtg/src/CardDescriptor.cpp b/projects/mtg/src/CardDescriptor.cpp index 80656b5c4..364d3e473 100644 --- a/projects/mtg/src/CardDescriptor.cpp +++ b/projects/mtg/src/CardDescriptor.cpp @@ -293,7 +293,7 @@ MTGCardInstance * CardDescriptor::match(MTGCardInstance * card) match = NULL; } - if (isFlipped != card->isFlipped) + if ((isFlipped == -1 && card->isFlipped > 0) || (isFlipped == 1 && card->isFlipped == 0)) { match = NULL; } diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index 3bad00db1..38e26aaeb 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -1561,11 +1561,11 @@ bool CardGui::FilterCard(MTGCard * _card,string filter) { if (minus) { - cd.isFlipped = false; + cd.isFlipped = -1; } else { - cd.isFlipped = true; + cd.isFlipped = 1; } } //Has x in cost diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index aa99bedd1..9953ee3b5 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -6223,7 +6223,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell) { MTGPlayerCards * zones = card->controller()->game; MTGPlayerCards * Endzones = card->owner->game;//put them in thier owners respective zones as per rules. - if (card->basicAbilities[(int)Constants::EXILEDEATH] || card->basicAbilities[(int)Constants::GAINEDEXILEDEATH]) + if (card->basicAbilities[(int)Constants::EXILEDEATH] || card->basicAbilities[(int)Constants::GAINEDEXILEDEATH] || (card->basicAbilities[(int)Constants::HASDISTURB] && card->alternateCostPaid[ManaCost::MANA_PAID_WITH_RETRACE] == 1)) { card->basicAbilities[(int)Constants::GAINEDEXILEDEATH] = 0; card->controller()->game->putInZone(card, card->getCurrentZone(), card->owner->game->exile); @@ -6557,7 +6557,7 @@ int ActivatedAbility::isReactingToClick(MTGCardInstance * card, ManaCost * mana) for(unsigned int k = 0; k < card->getObserver()->mLayers->actionLayer()->mObjects.size(); ++k) { ActivatedAbility * check = dynamic_cast(card->getObserver()->mLayers->actionLayer()->mObjects[k]); - turnSide = card->isFlipped && !card->isInPlay(card->getObserver()); + turnSide = card->isFlipped > 0 && !card->isInPlay(card->getObserver()); if(!turnSide && check && check->source == card && check->counters) return 0; } diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 70a8af97f..a4725dd07 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -230,7 +230,7 @@ void MTGCardInstance::initMTGCI() turningOver = false; isMorphed = false; MeldedFrom = ""; - isFlipped = false; + isFlipped = 0; isPhased = false; isCascaded = false; phasedTurn = -1; @@ -512,7 +512,7 @@ int MTGCardInstance::totem(bool noregen) int MTGCardInstance::toGrave( bool forced ) { Player * p = controller(); - if (basicAbilities[(int)Constants::EXILEDEATH] || basicAbilities[(int)Constants::GAINEDEXILEDEATH]) + if (basicAbilities[(int)Constants::EXILEDEATH] || basicAbilities[(int)Constants::GAINEDEXILEDEATH] || (basicAbilities[(int)Constants::HASDISTURB] && alternateCostPaid[ManaCost::MANA_PAID_WITH_RETRACE] == 1)) { p->game->putInZone(this, p->game->inPlay, owner->game->exile); basicAbilities[(int)Constants::GAINEDEXILEDEATH] = 0; diff --git a/projects/mtg/src/MTGDefinitions.cpp b/projects/mtg/src/MTGDefinitions.cpp index 5119a8a9a..5778096ac 100644 --- a/projects/mtg/src/MTGDefinitions.cpp +++ b/projects/mtg/src/MTGDefinitions.cpp @@ -232,7 +232,8 @@ const char* Constants::MTGBasicAbilities[] = { "isprey", //Creature has been haunted by some other card. "hasdisturb", //Retrace cost is a disturb cost (e.g. "Beloved Beggar") "daybound", //Card has daybound (e.g. "Brutal Cathar") - "nightbound" //Card has nightbound (e.g. "Moonrage Brute") + "nightbound", //Card has nightbound (e.g. "Moonrage Brute") + "decayed" //Card has decayd. }; map Constants::MTGBasicAbilitiesMap; diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index c113fff17..1fdc478ce 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -407,7 +407,7 @@ void MTGPlayerCards::showHand() // Moves a card to its owner's graveyard MTGCardInstance * MTGPlayerCards::putInGraveyard(MTGCardInstance * card) { - if (card->getCurrentZone() != card->controller()->game->hand && (card->basicAbilities[(int)Constants::EXILEDEATH] || card->basicAbilities[(int)Constants::GAINEDEXILEDEATH])) + if (card->getCurrentZone() != card->controller()->game->hand && (card->basicAbilities[(int)Constants::EXILEDEATH] || card->basicAbilities[(int)Constants::GAINEDEXILEDEATH] || (card->basicAbilities[(int)Constants::HASDISTURB] && card->alternateCostPaid[ManaCost::MANA_PAID_WITH_RETRACE] == 1))) { MTGCardInstance* ret = putInZone(card, card->getCurrentZone(), card->owner->game->exile); ret->basicAbilities[(int)Constants::GAINEDEXILEDEATH] = 0; diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index a1e8ac683..3393e1250 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -269,6 +269,11 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta zones[nbzones++] = MTGGameZone::MY_HAND; zones[nbzones++] = MTGGameZone::MY_COMMANDZONE; } + else if (zoneName.compare("mycommandplay") == 0) + { + zones[nbzones++] = MTGGameZone::MY_BATTLEFIELD; + zones[nbzones++] = MTGGameZone::MY_COMMANDZONE; + } else if (zoneName.compare("opponentcastingzone") == 0) { zones[nbzones++] = MTGGameZone::OPPONENT_GRAVEYARD; @@ -282,6 +287,11 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta zones[nbzones++] = MTGGameZone::OPPONENT_HAND; zones[nbzones++] = MTGGameZone::OPPONENT_COMMANDZONE; } + else if (zoneName.compare("opponentcommandplay") == 0) + { + zones[nbzones++] = MTGGameZone::OPPONENT_BATTLEFIELD; + zones[nbzones++] = MTGGameZone::OPPONENT_COMMANDZONE; + } else if (zoneName.compare("mynonplaynonexile") == 0) { zones[nbzones++] = MTGGameZone::MY_GRAVEYARD; @@ -612,11 +622,11 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta { if (minus) { - cd->isFlipped = false; + cd->isFlipped = -1; } else { - cd->isFlipped = true; + cd->isFlipped = 1; } } //Has x in cost