From e1c02c8bf5ef1dc5840dbbcaa2c507f88385e871 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 30 Sep 2015 23:45:54 +0800 Subject: [PATCH 1/3] produceextra, lki(last known information) for power, toughness and basic abilities --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 16 ++++----- projects/mtg/include/AllAbilities.h | 35 ++++++++++++++++++-- projects/mtg/include/CardPrimitive.h | 1 + projects/mtg/include/MTGCardInstance.h | 4 +++ projects/mtg/src/AllAbilities.cpp | 12 +++---- projects/mtg/src/CardPrimitive.cpp | 1 + projects/mtg/src/GameObserver.cpp | 3 ++ projects/mtg/src/MTGAbility.cpp | 8 ++++- projects/mtg/src/MTGCardInstance.cpp | 16 +++++++++ projects/mtg/src/MTGRules.cpp | 4 +-- 10 files changed, 80 insertions(+), 20 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 898605725..e39702b49 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -20600,7 +20600,7 @@ toughness=1 [card] name=Crypt Ghast auto=@movedto(*|mystack):pay({WB}) life:-1 opponent && life:1 controller -auto=@tappedformana(swamp|mybattlefield):Add{B} +auto=lord(swamp|mybattlefield) transforms((,newability[produceextra:{B}])) text=Extort (Whenever you cast a spell, you may pay {WB}. If you do, each opponent loses 1 life and you gain that much life.) -- Whenever you tap a Swamp for mana, add {B} to your mana pool (in addition to the mana the land produces). mana={3}{B} type=Creature @@ -37695,8 +37695,7 @@ toughness=3 [card] name=Gauntlet of Might auto=lord(creature[red]) 1/1 -auto=@tappedformana(mountain|mybattlefield):Add{R} controller -auto=@tappedformana(mountain|opponentbattlefield):Add{R} opponent +auto=lord(mountain|battlefield) transforms((,newability[produceextra:{R}])) text=Red creatures get +1/+1. -- Whenever a Mountain is tapped for mana, its controller adds {R} to his or her mana pool (in addition to the mana the land produces). mana={4} type=Artifact @@ -45724,7 +45723,7 @@ toughness=4 [/card] [card] name=High Tide -auto=all(island) transforms((,newability[@tappedformana(this):add{U}])) ueot +auto=all(island) transforms((,newability[produceextra:{U}])) ueot text=Until end of turn, whenever a player taps an Island for mana, that player adds {U} to his or her mana pool (in addition to the mana the land produces). mana={U} type=Instant @@ -67601,7 +67600,7 @@ toughness=2 [/card] [card] name=Nirkana Revenant -auto=@tappedformana(swamp|mybattlefield):Add{B} +auto=lord(swamp|mybattlefield) transforms((,newability[produceextra:{B}])) auto={B}:1/1 text=Whenever you tap a Swamp for mana, add {B} to your mana pool (in addition to the mana the land produces). -- {B}:Nirkana Revenant gets +1/+1 until end of turn. type=Creature @@ -70229,7 +70228,7 @@ subtype=Swamp Forest [card] name=Overgrowth target=land -auto=@tappedformana(mytgt):Add{G}{G} targetcontroller +auto=teach(land) transforms((,newability[produceextra:{G}{G}])) text=Enchant land (Target a land as you cast this. This card enters the battlefield attached to that land.) -- Whenever enchanted land is tapped for mana, its controller adds {G}{G} to his or her mana pool (in addition to the mana the land produces). mana={2}{G} type=Enchantment @@ -108293,8 +108292,7 @@ toughness=1 [/card] [card] name=Vernal Bloom -auto=@tappedformana(forest|mybattlefield):Add{G} controller -auto=@tappedformana(forest|opponentbattlefield):Add{G} opponent +auto=lord(forest|battlefield) transforms((,newability[produceextra:{G}])) text=Whenever a Forest is tapped for mana, its controller adds {G} to his or her mana pool (in addition to the mana the land produces). mana={3}{G} type=Enchantment @@ -113018,7 +113016,7 @@ toughness=2 [card] name=Wild Growth target=land -auto=@tappedformana(mytgt):add{g} targetcontroller +auto=teach(land) transforms((,newability[produceextra:{G}])) text=Enchant land -- Whenever enchanted land is tapped for mana, its controller adds {G} to his or her mana pool (in addition to the mana the land produces). mana={G} type=Enchantment diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index e553a284b..eadb8ee5c 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -654,11 +654,11 @@ private: } else if (s == "p" || s == "power") { - intValue = target->getPower(); + intValue = target->getCurrentPower(); } else if (s == "t" || s == "toughness") { - intValue = target->getToughness(); + intValue = target->getCurrentToughness(); } else if (s == "kicked") { @@ -5966,6 +5966,37 @@ public: } }; +//ProduceExtra Mana when tapped for mana +class AProduceExtraAbility: public MTGAbility +{ +public: + string ManaDescription; + + AProduceExtraAbility(GameObserver* observer, int _id, MTGCardInstance * _source, string _ManaDescription) : + MTGAbility(observer, _id, _source) + { + ManaDescription = _ManaDescription; + } + int receiveEvent(WEvent * event) + { + if(WEventCardTappedForMana * isTappedForMana = dynamic_cast (event)) + { + if ((isTappedForMana->card == source) && (isTappedForMana->card->controller() == source->controller())) + { + AManaProducer *amp = NEW AManaProducer(game, game->mLayers->actionLayer()->getMaxId(), source, source->controller(), ManaCost::parseManaCost(ManaDescription,NULL,source), NULL, 0,"",false); + amp->resolve(); + SAFE_DELETE(amp); + } + } + return 1; + } + + AProduceExtraAbility * clone() const + { + return NEW AProduceExtraAbility(*this); + } +}; + //flanking ability class AFlankerAbility: public MTGAbility { diff --git a/projects/mtg/include/CardPrimitive.h b/projects/mtg/include/CardPrimitive.h index 057698922..8f6041baf 100644 --- a/projects/mtg/include/CardPrimitive.h +++ b/projects/mtg/include/CardPrimitive.h @@ -59,6 +59,7 @@ public: typedef std::bitset BasicAbilitiesSet; BasicAbilitiesSet basicAbilities; BasicAbilitiesSet origbasicAbilities; + BasicAbilitiesSet LKIbasicAbilities; map magicTexts; string magicText; diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 635eaab23..fe5d78c5d 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -233,6 +233,10 @@ public: void addbaseT(int t = 0); void revertbaseP(); void revertbaseT(); + int getCurrentPower(); + int LKIpower; + int LKItoughness; + int getCurrentToughness(); void cdaPT(int p = 0, int t = 0); bool isCDA; void switchPT(bool apply = false); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 4eaff7a7f..901b631cb 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -2081,16 +2081,16 @@ int AADynamic::resolve() switch(type) { case DYNAMIC_ABILITY_TYPE_POWER: - sourceamount = ((MTGCardInstance *) source)->power; - targetamount = ((MTGCardInstance *) _target)->power; + sourceamount = ((MTGCardInstance *) source)->getCurrentPower(); + targetamount = ((MTGCardInstance *) _target)->getCurrentPower(); if(eachother ) - sourceamount = ((MTGCardInstance *) source)->power; + sourceamount = ((MTGCardInstance *) source)->getCurrentPower(); break; case DYNAMIC_ABILITY_TYPE_TOUGHNESS: - sourceamount = ((MTGCardInstance *) source)->toughness; - targetamount = ((MTGCardInstance *) _target)->toughness; + sourceamount = ((MTGCardInstance *) source)->getCurrentToughness(); + targetamount = ((MTGCardInstance *) _target)->getCurrentToughness(); if(eachother ) - sourceamount = ((MTGCardInstance *) source)->toughness; + sourceamount = ((MTGCardInstance *) source)->getCurrentToughness(); break; case DYNAMIC_ABILITY_TYPE_MANACOST: if(amountsource == 1) diff --git a/projects/mtg/src/CardPrimitive.cpp b/projects/mtg/src/CardPrimitive.cpp index 566b1c03e..0ed61cd68 100644 --- a/projects/mtg/src/CardPrimitive.cpp +++ b/projects/mtg/src/CardPrimitive.cpp @@ -42,6 +42,7 @@ CardPrimitive::CardPrimitive(CardPrimitive * source) return; basicAbilities = source->basicAbilities; origbasicAbilities = source->basicAbilities; + LKIbasicAbilities = source->basicAbilities; for (size_t i = 0; i < source->types.size(); ++i) types.push_back(source->types[i]); diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 342e2db97..ee226cdb8 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -608,6 +608,9 @@ void GameObserver::gameStateBasedEffects() for (int j = zone->nb_cards - 1; j >= 0; j--) { MTGCardInstance * card = zone->cards[j]; + card->LKIpower = card->power; + card->LKItoughness = card->toughness; + card->LKIbasicAbilities = card->basicAbilities; card->afterDamage(); card->mPropertiesChangedSinceLastUpdate = false; if(card->hasType(Subtypes::TYPE_PLANESWALKER) && (!card->counters||!card->counters->hasCounter("loyalty",0,0))) diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index eca1ae89a..f543c950b 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -2659,6 +2659,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return NEW AEvolveAbility(observer, id, card); } + //produce additional mana when tapped for mana + if (s.find("produceextra:") != string::npos) + { + return NEW AProduceExtraAbility(observer, id, card,s.substr(13)); + } + //flanking if (s.find("flanker") != string::npos) { @@ -4259,7 +4265,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell) if (current->hasType(Subtypes::TYPE_CREATURE)) { card->controller()->game->putInGraveyard(current); - damage += current->power; + damage += current->getCurrentPower(); } } observer->mLayers->stackLayer()->addDamage(card, target, damage); diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index abe1ea1be..e4ff9beb1 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -61,6 +61,8 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to discarded = false; copiedID = getId(); modifiedbAbi = 0; + LKIpower = power; + LKItoughness = toughness; } MTGCardInstance * MTGCardInstance::createSnapShot() @@ -723,6 +725,20 @@ void MTGCardInstance::switchPT(bool apply) } } +int MTGCardInstance::getCurrentPower() +{ + if(!isInPlay(observer)) + return LKIpower; + return power; +} + +int MTGCardInstance::getCurrentToughness() +{ + if(!isInPlay(observer)) + return LKItoughness; + return toughness; +} + int MTGCardInstance::canBlock() { if (tapped) diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index b58090b21..a935992db 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -2707,7 +2707,7 @@ int MTGLifelinkRule::receiveEvent(WEvent * event) WEventDamage * e = (WEventDamage *) event; Damage * d = e->damage; MTGCardInstance * card = d->source; - if (d->damage > 0 && card && card->basicAbilities[(int)Constants::LIFELINK]) + if (d->damage > 0 && card && (card->basicAbilities[(int)Constants::LIFELINK]||card->LKIbasicAbilities[(int)Constants::LIFELINK])) { card->controller()->gainLife(d->damage); return 1; @@ -2751,7 +2751,7 @@ int MTGDeathtouchRule::receiveEvent(WEvent * event) return 0; MTGCardInstance * _target = (MTGCardInstance *) (d->target); - if (card->basicAbilities[(int)Constants::DEATHTOUCH]) + if (card->basicAbilities[(int)Constants::DEATHTOUCH]||card->LKIbasicAbilities[(int)Constants::DEATHTOUCH]) { _target->destroy(); return 1; From ddee2c08e28c43feb7977e7fe9759b2f3790567a Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 1 Oct 2015 22:25:26 +0800 Subject: [PATCH 2/3] added stack check, modified life check if activating ability, playing a land or casting sorcery spell at sorcery level(timing restriction), if the stack is not empty, don't allow it. Modified the life state check, if any of the players would lose the game, allow the gamestateeffects to check... added reduceto:value for ali from cairo... --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 24 ++++++++++-- .../bin/Res/sets/primitives/unsupported.txt | 15 -------- projects/mtg/include/AllAbilities.h | 38 +++++++++++++++++++ projects/mtg/include/MTGCardInstance.h | 3 +- projects/mtg/include/Player.h | 2 +- projects/mtg/src/GameObserver.cpp | 4 +- projects/mtg/src/MTGAbility.cpp | 32 ++++------------ projects/mtg/src/MTGCardInstance.cpp | 14 +++++++ projects/mtg/src/MTGRules.cpp | 33 +++++----------- projects/mtg/src/Player.cpp | 18 ++++++++- 10 files changed, 112 insertions(+), 71 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index e39702b49..4fa87979f 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -2168,7 +2168,7 @@ toughness=1 [/card] [card] name=Ali from Cairo -auto=@damaged(controller) restriction{compare(lifetotal)~lessthan~1}:this(controllerlife < 1) lifeset:1 controller +auto=this(controllerlife >= 1) transforms((,newability[reduceto:1])) text=Damage that would reduce your life total to less than 1 reduces it to 1 instead. mana={2}{R}{R} type=Creature @@ -28928,7 +28928,7 @@ toughness=6 name=Elderscale Wurm abilities=trample auto=if compare(lifetotal)~lessthan~7 then lifeset:7 controller -auto=this(controllerlife > 6) transforms((,newability[@damaged(controller):if compare(lifetotal)~lessthan~7 then lifeset:7 controller])) +auto=this(controllerlife >= 7) transforms((,newability[reduceto:7])) text=Trample. -- When Elderscale Wurm enters the battlefield, if your life total is less than 7, your life total becomes 7. -- As long as you have 7 or more life, damage that would reduce your life total to less than 7 reduces it to 7 instead. mana={4}{G}{G}{G} type=Creature @@ -36160,7 +36160,7 @@ toughness=3 name=Fortune Thief facedown={3} autofacedown={R}{R}:morph -auto=@damaged(controller) restriction{compare(lifetotal)~lessthan~1}:this(controllerlife < 1) lifeset:1 controller +auto=this(controllerlife >= 1) transforms((,newability[reduceto:1])) text=Damage that would reduce your life total to less than 1 reduces it to 1 instead. -- Morph {R}{R} (You may cast this face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.) mana={4}{R} type=Creature @@ -98227,6 +98227,17 @@ power=2 toughness=3 [/card] [card] +name=Sustaining Spirit +auto=cumulativeupcost[{1}{W}] sacrifice +auto=this(controllerlife >= 1) transforms((,newability[reduceto:1])) +text=Cumulative upkeep {1}{W} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- Damage that would reduce your life total to less than 1 reduces it to 1 instead. +mana={1}{W} +type=Creature +subtype=Angel Spirit +power=0 +toughness=3 +[/card] +[card] name=Sustenance auto={1}{S(land|myBattlefield)}:1/1 target(creature) text={1}, Sacrifice a land: Target creature gets +1/+1 until end of turn. @@ -114654,6 +114665,13 @@ mana={3} type=Artifact [/card] [card] +name=Worship +auto=this(variable{worshipped} >= 1) transforms((,newability[reduceto:1])) +text=If you control a creature, damage that would reduce your life total to less than 1 reduces it to 1 instead. +mana={3}{W} +type=Enchantment +[/card] +[card] name=Worthy Cause auto=life:storedtoughness controller buyback={W}{2} diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index 0f27c9015..1e5340bf6 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -16201,15 +16201,6 @@ type=Sorcery text=You gain 2 life. Then if you have more life than an opponent, draw a card. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) [/card] [card] -name=Sustaining Spirit -text=Cumulative upkeep {1}{W} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- Damage that would reduce your life total to less than 1 reduces it to 1 instead. -mana={1}{W} -type=Creature -subtype=Angel Spirit -power=0 -toughness=3 -[/card] -[card] name=Sutured Ghoul text=Trample -- As Sutured Ghoul enters the battlefield, exile any number of creature cards from your graveyard. -- Sutured Ghoul's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness. mana={4}{B}{B}{B} @@ -18718,12 +18709,6 @@ mana={2}{B}{B}{B} type=Enchantment [/card] [card] -name=Worship -text=If you control a creature, damage that would reduce your life total to less than 1 reduces it to 1 instead. -mana={3}{W} -type=Enchantment -[/card] -[card] name=Wort, the Raidmother text=When Wort, the Raidmother enters the battlefield, put two 1/1 red and green Goblin Warrior creature tokens onto the battlefield. -- Each red or green instant or sorcery spell you cast has conspire. (As you cast the spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose new targets for the copy.) mana={4}{RG}{RG} diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index eadb8ee5c..eebdd4de0 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -688,6 +688,13 @@ private: { intValue = target->controller()->opponent()->game->hand->nb_cards; } + else if (s == "worshipped")//Worship + { + if(card->controller()->game->battlefield->hasType("creature")) + intValue = card->controller()->life; + else + intValue = 0; + } else if (s == "pancientooze")//Ancient Ooze { intValue = 0; @@ -5997,6 +6004,37 @@ public: } }; +//Reduce to .. Ali from Cairo... +class AReduceToAbility: public MTGAbility +{ +public: + string life_s; + + AReduceToAbility(GameObserver* observer, int _id, MTGCardInstance * _source, string _life_s) : + MTGAbility(observer, _id, _source) + { + life_s = _life_s; + } + int receiveEvent(WEvent * event) + { + if(WEventDamage * isDamaged = dynamic_cast (event)) + { + if (isDamaged->damage->target->type_as_damageable == Damageable::DAMAGEABLE_PLAYER) + { + Player * p = (Player *) isDamaged->damage->target; + WParsedInt lifetoset(life_s, NULL, source); + if(p && p == source->controller() && p->life <= lifetoset.getValue()) + p->life = lifetoset.getValue(); + } + } + return 1; + } + AReduceToAbility * clone() const + { + return NEW AReduceToAbility(*this); + } +}; + //flanking ability class AFlankerAbility: public MTGAbility { diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index fe5d78c5d..27faf0c1c 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -234,9 +234,9 @@ public: void revertbaseP(); void revertbaseT(); int getCurrentPower(); + int getCurrentToughness(); int LKIpower; int LKItoughness; - int getCurrentToughness(); void cdaPT(int p = 0, int t = 0); bool isCDA; void switchPT(bool apply = false); @@ -248,6 +248,7 @@ public: bool discarded; int copiedID; int modifiedbAbi; + bool StackIsEmptyandSorcerySpeed(); void eventattacked(); void eventattackedAlone(); diff --git a/projects/mtg/include/Player.h b/projects/mtg/include/Player.h index 800ef7db8..ae3e46007 100644 --- a/projects/mtg/include/Player.h +++ b/projects/mtg/include/Player.h @@ -71,7 +71,7 @@ public: ManaPool * getManaPool(); void takeMulligan(); void serumMulligan(); - bool DeadLifeState(); + bool DeadLifeState(bool check = false); ManaCost * doesntEmpty; ManaCost * poolDoesntEmpty; void cleanupPhase(); diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index ee226cdb8..0b2ac2b4e 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -578,6 +578,8 @@ void GameObserver::Update(float dt) { mLayers->actionLayer()->Update(0); } + players[0]->DeadLifeState(); + players[1]->DeadLifeState(); gameStateBasedEffects(); } oldGamePhase = mCurrentGamePhase; @@ -764,7 +766,7 @@ void GameObserver::gameStateBasedEffects() /////////////////////////////////////////////////////////// //life checks/poison checks also checks cant win or lose.// /////////////////////////////////////////////////////////// - players[i]->DeadLifeState();//refactored + players[i]->DeadLifeState(true);//refactored } ////////////////////////////////////////////////////// //-------------card based states effects------------// diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index f543c950b..b660a30fe 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -2665,6 +2665,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return NEW AProduceExtraAbility(observer, id, card,s.substr(13)); } + //reducelife to specific value + if (s.find("reduceto:") != string::npos) + { + return NEW AReduceToAbility(observer, id, card,s.substr(9)); + } + //flanking if (s.find("flanker") != string::npos) { @@ -4594,6 +4600,8 @@ int ActivatedAbility::isReactingToClick(MTGCardInstance * card, ManaCost * mana) return 0; if (cPhase != MTG_PHASE_FIRSTMAIN && cPhase != MTG_PHASE_SECONDMAIN) return 0; + if (player->opponent()->getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0||game->mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0||player->getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0) + return 0; break; } if (restrictions >= MY_BEFORE_BEGIN && restrictions <= MY_AFTER_EOT) @@ -5016,30 +5024,6 @@ int TriggeredAbility::receiveEvent(WEvent * e) resolve(); return 1; } - if(dynamic_cast(e)) - { - //check life state on life triger - WEventLife * lifecheck = dynamic_cast(e); - if (lifecheck->player->DeadLifeState()) - { - return 0; - } - fireAbility(); - return 1; - } - if(dynamic_cast(e)) - { - //check life state on damage trigger - WEventDamage * lifecheck = dynamic_cast(e); - if (lifecheck->damage->target->type_as_damageable == Damageable::DAMAGEABLE_PLAYER) - { - Player * triggerPlayer = (Player *) lifecheck->damage->target; - if(triggerPlayer->DeadLifeState()) - return 0; - } - fireAbility(); - return 1; - } WEventZoneChange * stackCheck = dynamic_cast(e); if(stackCheck && (stackCheck->to == game->currentPlayer->game->stack||stackCheck->to == game->currentPlayer->opponent()->game->stack)) { diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index e4ff9beb1..08236b48c 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -739,6 +739,20 @@ int MTGCardInstance::getCurrentToughness() return toughness; } +//check stack +bool MTGCardInstance::StackIsEmptyandSorcerySpeed() +{ + if((getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0) && + (getObserver()->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN || + getObserver()->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN) && + controller() == getObserver()->currentPlayer && + !getObserver()->isInterrupting) + { + return true; + } + return false; +} + int MTGCardInstance::canBlock() { if (tapped) diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index a935992db..e7fffab29 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -310,18 +310,12 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost *) { if (game->currentActionPlayer->game->playRestrictions->canPutIntoZone(card, game->currentActionPlayer->game->inPlay) == PlayRestriction::CANT_PLAY) return 0; - if (player == currentPlayer - && (game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN || game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN) - ) - { + if (card->StackIsEmptyandSorcerySpeed()) return 1; - } + else + return 0; } - else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) - || (player == card->controller() && !game->isInterrupting - && (game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN - || game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN)) - ) + else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || (card->StackIsEmptyandSorcerySpeed())) { if(card->controller()->epic) return 0; @@ -645,17 +639,12 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * { if (game->currentActionPlayer->game->playRestrictions->canPutIntoZone(card, game->currentActionPlayer->game->inPlay) == PlayRestriction::CANT_PLAY) return 0; - if (player == currentPlayer - && (game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN - || game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN) - ) + if (card->StackIsEmptyandSorcerySpeed()) return 1; + else + return 0; } - else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || card->has(Constants::SPELLMASTERY) || card->has(Constants::OFFERING) - || (player == card->controller() && !game->isInterrupting - && (game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN - || game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN)) - ) + else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || card->has(Constants::SPELLMASTERY) || card->has(Constants::OFFERING) || (card->StackIsEmptyandSorcerySpeed())) { if(card->controller()->epic) return 0; @@ -1042,11 +1031,7 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *) if(card->controller()->epic)//zoetic cavern... morph is casted for a cost... return 0; //note lands can morph too, this is different from other cost types. - if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || (player == card->controller() - && !game->isInterrupting - && (game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN - || game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN)) - ) + if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || (card->StackIsEmptyandSorcerySpeed())) { if (card->controller()->game->playRestrictions->canPutIntoZone(card, card->controller()->game->stack) == PlayRestriction::CANT_PLAY) return 0; diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index 52d0e311b..445375166 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -236,7 +236,7 @@ void Player::serumMulligan() //Draw hand no penalty } -bool Player::DeadLifeState() +bool Player::DeadLifeState(bool check) { if ((life <= 0)||(poisonCount >= 10)) { @@ -263,7 +263,21 @@ bool Player::DeadLifeState() } if (cantlosers < 1) { - getObserver()->setLoser(this); + if(!check) + { + ActionStack * stack = getObserver()->mLayers->stackLayer(); + for (int i = stack->mObjects.size() - 1; i >= 0; i--) + { + Interruptible * current = ((Interruptible *) stack->mObjects[i]); + Spell * spell = (Spell *) current; + if (current->type == ACTION_SPELL) + spell->source->controller()->game->putInGraveyard(spell->source); + + current->state = RESOLVED_NOK; + } + } + if(check) + game->owner->getObserver()->setLoser(this); return true; } } From 4098c306e2594dbfb6a1b61aa05c4f46e08f6bc2 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 1 Oct 2015 22:56:42 +0800 Subject: [PATCH 3/3] removed unused variable. --- projects/mtg/src/MTGRules.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index e7fffab29..6b982ce95 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -284,7 +284,6 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost *) { int cardsinhand = game->players[0]->game->hand->nb_cards; Player * player = game->currentlyActing(); - Player * currentPlayer = game->currentPlayer; if (!player->game->hand->hasCard(card)) return 0; if ((game->turn < 1) && (cardsinhand != 0) && (card->basicAbilities[(int)Constants::LEYLINE]) @@ -625,7 +624,6 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *, ManaCost *alternateManaCost) { Player * player = game->currentlyActing(); - Player * currentPlayer = game->currentPlayer; if (!alternateManaCost) return 0;