diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index a5426a55b..26e2ca91d 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -137,6 +137,7 @@ spoils_of_evil.txt stasis.txt steelclad_serpent1.txt steelclad_serpent2.txt +stillmoon_cavalier.txt sword_to_plowshares.txt telekinetic_sliver.txt terror.txt diff --git a/projects/mtg/bin/Res/test/stillmoon_cavalier.txt b/projects/mtg/bin/Res/test/stillmoon_cavalier.txt new file mode 100644 index 000000000..600bae6ea --- /dev/null +++ b/projects/mtg/bin/Res/test/stillmoon_cavalier.txt @@ -0,0 +1,52 @@ +#Bug: Stillmoon cavalier's effects don't wear off at the end of the turn +[INIT] +FIRSTMAIN +[PLAYER1] +inplay:Stillmoon Cavalier +manapool:{B} +[PLAYER2] +inplay:grizzly bears,raging goblin +[DO] +Stillmoon Cavalier +choice 1 +next +#combat begins +next +#attackers +Stillmoon Cavalier +next +#blockers +Grizzly Bears +next +#damage +next +#end +eot +eot +#untap +next +#upkeep +next +#draw +next +#firstmain +next +#combat begins +next +#attackers +Stillmoon Cavalier +next +#blockers +raging goblin +next +#damage +next +#end +[ASSERT] +COMBATEND +[PLAYER1] +graveyard:Stillmoon Cavalier +manapool:{0} +[PLAYER2] +graveyard:grizzly bears,raging goblin +[END] \ No newline at end of file diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 9585c008f..1589f5ac1 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -29,7 +29,7 @@ class TrCardAddedToZone:public TriggeredAbility{ public: TargetChooser * toTc; TargetZoneChooser * fromTc; - TrCardAddedToZone::TrCardAddedToZone(int id,MTGCardInstance * source, TargetChooser * toTc, TargetZoneChooser * fromTc = NULL):TriggeredAbility(id,source), fromTc(fromTc),toTc(toTc){ + TrCardAddedToZone(int id,MTGCardInstance * source, TargetChooser * toTc, TargetZoneChooser * fromTc = NULL):TriggeredAbility(id,source), fromTc(fromTc),toTc(toTc){ } int resolve(){ @@ -174,8 +174,10 @@ public: int resolve(){ vector::size_type sz = abilities.size(); for (unsigned int i = 0; i < sz; i++){ + Targetable * backup = abilities[i]->target; if (target && target!= source && abilities[i]->target == abilities[i]->source) abilities[i]->target = target; abilities[i]->resolve(); + abilities[i]->target = backup; } return 1; } @@ -654,6 +656,10 @@ class AInstantBasicAbilityModifierUntilEOT: public InstantAbility{ return InstantAbility::addToGame(); } + const char * getMenuText(){ + return Constants::MTGBasicAbilities[ability]; + } + int destroy(){ ((MTGCardInstance *)target)->basicAbilities[ability] = stateBeforeActivation; return 1; @@ -677,40 +683,21 @@ class AInstantBasicAbilityModifierUntilEOT: public InstantAbility{ //Alteration of Ability until of turn (Aura) class ABasicAbilityAuraModifierUntilEOT: public ActivatedAbility{ public: - int stateBeforeActivation; - int ability; - int value; - ABasicAbilityAuraModifierUntilEOT(int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost, int _ability, int _value = 1):ActivatedAbility(_id,_source, _cost, 0,0), ability(_ability), value(_value){ + AInstantBasicAbilityModifierUntilEOT * ability; + ABasicAbilityAuraModifierUntilEOT(int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost, int _ability, int _value = 1):ActivatedAbility(_id,_source, _cost, 0,0){ target = _target; - stateBeforeActivation = _target->basicAbilities[ability]; - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_UNTAP){ - MTGCardInstance * _target = (MTGCardInstance *) target; - _target->basicAbilities[ability] = stateBeforeActivation; - } - ActivatedAbility::Update(dt); + ability = NEW AInstantBasicAbilityModifierUntilEOT(_id,_source,_target,_ability, _value); } int resolve(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - stateBeforeActivation = _target->basicAbilities[ability]; - _target->basicAbilities[ability] = value; + MTGAbility * a = ability->clone(); + a->target = target; + a->addToGame(); return 1; } const char * getMenuText(){ - return Constants::MTGBasicAbilities[ability]; - } - - virtual ostream& toString(ostream& out) const - { - out << "ABasicAbilityAuraModifierUntilEOT ::: stateBeforeActivation : " << stateBeforeActivation - << " ; ability : " << ability - << " ; value : " << value - << " ("; - return ActivatedAbility::toString(out) << ")"; + return ability->getMenuText(); } ABasicAbilityAuraModifierUntilEOT * clone() const{ @@ -719,6 +706,9 @@ class ABasicAbilityAuraModifierUntilEOT: public ActivatedAbility{ return a; } + ~ABasicAbilityAuraModifierUntilEOT(){ + if (!isClone) SAFE_DELETE(ability); + } }; @@ -986,62 +976,6 @@ class ATargetterPowerToughnessModifierUntilEOT: public TargetAbility{ } }; - - -//Alteration of Power and Toughness until end of turn (Aura) -class APowerToughnessModifierUntilEndOfTurn: public ActivatedAbility{ - public: - int power, toughness; - int counters; - int maxcounters; - APowerToughnessModifierUntilEndOfTurn(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness, ManaCost * _cost = NULL, int _maxcounters = 0):ActivatedAbility(id,_source,_cost,0,0),power(_power),toughness(_toughness),maxcounters(_maxcounters){ - counters = 0; - target=_target; - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_UNTAP){ - while(counters){ - ((MTGCardInstance *)target)->power -= power; - ((MTGCardInstance *)target)->addToToughness(-toughness); - counters--; - } - } - ActivatedAbility::Update(dt); - } - - int fireAbility(){ - return resolve(); - } - - int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL){ - if (!ActivatedAbility::isReactingToClick(card,mana)) return 0; - return (!maxcounters || (counters < maxcounters)); - } - - int resolve(){ - ((MTGCardInstance *)target)->power += power; - ((MTGCardInstance *)target)->addToToughness(toughness); - counters++; - return 1; - } - virtual ostream& toString(ostream& out) const - { - out << "APowerToughnessModifierUntilEndOfTurn ::: power : " << power - << " ; toughness : " << toughness - << " ; counters : " << counters - << " ; maxcounters : " << maxcounters - << " ("; - return ActivatedAbility::toString(out) << ")"; - } - APowerToughnessModifierUntilEndOfTurn * clone() const{ - APowerToughnessModifierUntilEndOfTurn * a = NEW APowerToughnessModifierUntilEndOfTurn(*this); - a->isClone = 1; - return a; - } -}; - - //Alteration of Power and toughness until end of turn (instant) class AInstantPowerToughnessModifierUntilEOT: public InstantAbility{ public: @@ -1076,6 +1010,51 @@ class AInstantPowerToughnessModifierUntilEOT: public InstantAbility{ }; + +//Alteration of Power and Toughness until end of turn (Aura) +class APowerToughnessModifierUntilEndOfTurn: public ActivatedAbility{ + public: + AInstantPowerToughnessModifierUntilEOT * ability; + int counters; + int maxcounters; + APowerToughnessModifierUntilEndOfTurn(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness, ManaCost * _cost = NULL, int _maxcounters = 0):ActivatedAbility(id,_source,_cost,0,0),maxcounters(_maxcounters){ + counters = 0; + target=_target; + ability = NEW AInstantPowerToughnessModifierUntilEOT(id,_source,_target,_power,_toughness); + } + + int fireAbility(){ + return resolve(); + } + + int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL){ + if (!ActivatedAbility::isReactingToClick(card,mana)) return 0; + return (!maxcounters || (counters < maxcounters)); + } + + int resolve(){ + MTGAbility * a = ability->clone(); + a->target = target; + a->addToGame(); + counters++; + return 1; + } + + APowerToughnessModifierUntilEndOfTurn * clone() const{ + APowerToughnessModifierUntilEndOfTurn * a = NEW APowerToughnessModifierUntilEndOfTurn(*this); + a->isClone = 1; + return a; + } + + ~APowerToughnessModifierUntilEndOfTurn(){ + if (!isClone) SAFE_DELETE(ability); + } +}; + + + + + //Untap Blockers with simple Mana Mechanism class AUntapManaBlocker: public UntapBlocker{ public: diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 630cf3275..7dc9fe87f 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -685,8 +685,7 @@ int AbilityFactory::abilityEfficiency(MTGAbility * a, Player * p, int mode){ APowerToughnessModifierUntilEndOfTurn * aptmu = dynamic_cast(a); if (aptmu){ - if (aptmu->power>=0 && aptmu->toughness>=0) return BAKA_EFFECT_GOOD; - return BAKA_EFFECT_BAD; + return abilityEfficiency(aptmu->ability, p, mode); } map badAbilities; @@ -715,10 +714,7 @@ int AbilityFactory::abilityEfficiency(MTGAbility * a, Player * p, int mode){ ABasicAbilityAuraModifierUntilEOT * abamu = dynamic_cast(a); if (abamu){ - int result = BAKA_EFFECT_GOOD; - if (badAbilities[abamu->ability]) result = BAKA_EFFECT_BAD; - if (abamu->value <= 0) result = -result; - return result; + return abilityEfficiency(abamu->ability, p, mode); } AManaProducer * amp = dynamic_cast(a); @@ -2228,7 +2224,7 @@ InstantAbility::InstantAbility(int _id, MTGCardInstance * source):MTGAbility(_id init = 0; for (int i = 0; i < 2; i++){ if(game->players[i]->game->inPlay->hasCard(source)){ - game->players[i]->game->putInGraveyard(source); + //game->players[i]->game->putInGraveyard(source); } } } @@ -2243,7 +2239,7 @@ InstantAbility::InstantAbility(int _id, MTGCardInstance * source, Damageable * _ init = 0; for (int i = 0; i < 2; i++){ if(game->players[i]->game->inPlay->hasCard(source)){ - game->players[i]->game->putInGraveyard(source); + //game->players[i]->game->putInGraveyard(source); } } } diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index 01c17deb5..a97437064 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -288,7 +288,7 @@ void TestSuite::initGame(){ MTGCardInstance * copy = p->game->putInZone(card, p->game->library, p->game->stack); Spell * spell = NEW Spell(copy); spell->resolve(); - if (!summoningSickness) p->game->inPlay->cards[k]->summoningSickness = 0; + if (!summoningSickness && p->game->inPlay->nb_cards>k) p->game->inPlay->cards[k]->summoningSickness = 0; delete spell; }else{ if (!p->game->library->hasCard(card)){