mirror of
https://github.com/magefree/mage.git
synced 2025-12-27 05:52:06 -08:00
Merge branch 'master' into Network_Upgrade
This commit is contained in:
commit
e7bb3a0dbf
324 changed files with 9827 additions and 1835 deletions
|
|
@ -1,51 +1,49 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.mage.test.cards.abilities.activated;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class PutOntoBattlefieldTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Tests to put a token onto the battlefield
|
||||
*/
|
||||
@Test
|
||||
public void testOozeFlux() {
|
||||
// Enchantment
|
||||
// {1}{G}, Remove one or more +1/+1 counters from among creatures you control: Put an X/X green Ooze creature token onto the battlefield, where X is the number of +1/+1 counters removed this way.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ooze Flux");
|
||||
// Trample
|
||||
// Kalonian Hydra enters the battlefield with four +1/+1 counters on it.
|
||||
// Whenever Kalonian Hydra attacks, double the number of +1/+1 counters on each creature you control.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Kalonian Hydra");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{G},");
|
||||
setChoice(playerA, "X=2"); // Remove how many
|
||||
setChoice(playerA,"Kalonian Hydra");
|
||||
setChoice(playerA, "X=2"); // Remove from Hydra
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, "Kalonian Hydra", 2, 2);
|
||||
assertPermanentCount(playerA, "Ooze", 1);
|
||||
assertPowerToughness(playerA, "Ooze", 2, 2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.mage.test.cards.abilities.activated;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class PutOntoBattlefieldTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Tests to put a token onto the battlefield
|
||||
*/
|
||||
@Test
|
||||
public void testOozeFlux() {
|
||||
// Enchantment
|
||||
// {1}{G}, Remove one or more +1/+1 counters from among creatures you control: Put an X/X green Ooze creature token onto the battlefield, where X is the number of +1/+1 counters removed this way.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ooze Flux");
|
||||
// Trample
|
||||
// Kalonian Hydra enters the battlefield with four +1/+1 counters on it.
|
||||
// Whenever Kalonian Hydra attacks, double the number of +1/+1 counters on each creature you control.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Kalonian Hydra");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{G},");
|
||||
setChoice(playerA, "X=2"); // Remove how many
|
||||
setChoice(playerA,"Kalonian Hydra");
|
||||
setChoice(playerA, "X=2"); // Remove from Hydra
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, "Kalonian Hydra", 2, 2);
|
||||
assertPermanentCount(playerA, "Ooze", 1);
|
||||
assertPowerToughness(playerA, "Ooze", 2, 2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.cards.abilities.activated;
|
||||
|
||||
import mage.abilities.keyword.BloodthirstAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class ReturnToHandTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Tests to put a token onto the battlefield
|
||||
*/
|
||||
@Test
|
||||
public void SkarrganFirebirdTest() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox");
|
||||
// Bloodthirst 3
|
||||
// Flying
|
||||
// {R}{R}{R}: Return Skarrgan Firebird from your graveyard to your hand. Activate this ability only if an opponent was dealt damage this turn.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Skarrgan Firebird");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3);
|
||||
addCard(Zone.HAND, playerB, "Bone Splinters");
|
||||
|
||||
// As an additional cost to cast Bone Splinters, sacrifice a creature.
|
||||
// Destroy target creature.
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Bone Splinters", "Pillarfield Ox");
|
||||
setChoice(playerB, "Skarrgan Firebird");
|
||||
|
||||
attack(2, playerB, "Silvercoat Lion");
|
||||
|
||||
activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{R}{R}{R}: Return");
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Skarrgan Firebird", 0);
|
||||
assertGraveyardCount(playerA, "Pillarfield Ox", 1);
|
||||
assertGraveyardCount(playerB, "Bone Splinters", 1);
|
||||
assertHandCount(playerB, "Skarrgan Firebird", 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class ChangelingTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Casting changelings with a Long-Forgotten Gohei in play reduces its casting cost by {1}.
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testLongForgottenGohei() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.HAND, playerA, "Woodland Changeling");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Long-Forgotten Gohei");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Woodland Changeling");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Woodland Changeling", 0); // Casting cost of spell is not reduced so not on the battlefield
|
||||
assertHandCount(playerA, "Woodland Changeling", 1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class PhasingTest extends CardTestPlayerBase {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test that abilities of phased out cards do not trigger or apply their effects
|
||||
*/
|
||||
@Test
|
||||
public void TestAbilitiesOfPhasedOutAreNotApplied() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
// At the beginning of each player's upkeep, that player chooses artifact, creature, land, or non-Aura enchantment.
|
||||
// All nontoken permanents of that type phase out.
|
||||
addCard(Zone.HAND, playerA, "Teferi's Realm", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Crusade", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Teferi's Realm");
|
||||
|
||||
setChoice(playerB, "Non-Aura enchantment");
|
||||
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerB, "Crusade", 0);
|
||||
assertPermanentCount(playerB, "Silvercoat Lion", 1);
|
||||
assertPowerToughness(playerB, "Silvercoat Lion", 2, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -69,4 +69,48 @@ public class ProliferateTest extends CardTestPlayerBase{
|
|||
assertCounterCount("Chandra, Pyromaster", CounterType.LOYALTY, 5); // 4 + 1 from proliferate
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Counters aren't cancelling each other out. Reproducible with any creature (graft and bloodthirst in my case)
|
||||
* with a single +1/+1 counter on it, with a single -1/-1 placed on it (Grim Affliction, Instill Infection, etc).
|
||||
* The counters should cancel each other out, leaving neither on the creature, which they don't (though visually
|
||||
* there aren't any counters sitting on the card). Triggering proliferate at any point now (Thrumming Bird,
|
||||
* Steady Progress, etc) will give you the option to add another of either counter, where you shouldn't have any as an option.
|
||||
*/
|
||||
@Test
|
||||
public void testValidTargets() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
|
||||
// Put a +1/+1 counter on target creature.
|
||||
addCard(Zone.HAND, playerA, "Battlegrowth"); // {G}
|
||||
// Proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.)
|
||||
// Draw a card.
|
||||
addCard(Zone.HAND, playerA, "Steady Progress"); // {U}{2}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Sporeback Troll"); // has two +1/+1 counter
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3);
|
||||
// Put a -1/-1 counter on target creature, then proliferate.
|
||||
addCard(Zone.HAND, playerB, "Grim Affliction"); // {B}{2}
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Battlegrowth", "Silvercoat Lion");
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Grim Affliction", "Silvercoat Lion");
|
||||
// proliferate Sporeback Troll
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Steady Progress");
|
||||
// Silvercoat Lion may not be a valid target now
|
||||
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
|
||||
assertGraveyardCount(playerA, "Battlegrowth", 1);
|
||||
assertGraveyardCount(playerA, "Steady Progress", 1);
|
||||
assertGraveyardCount(playerB, "Grim Affliction", 1);
|
||||
|
||||
assertCounterCount("Silvercoat Lion", CounterType.P1P1, 0); // no valid target because no counter
|
||||
assertCounterCount("Sporeback Troll", CounterType.P1P1, 3); // 2 + 1 from proliferate
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ package org.mage.test.cards.abilities.keywords;
|
|||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
|
@ -114,4 +115,28 @@ public class SuspendTest extends CardTestPlayerBase {
|
|||
assertPermanentCount(playerA, "Silvercoat Lion", 1);
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testDeepSeaKraken() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
// Suspend 9-{2}{U}
|
||||
// Whenever an opponent casts a spell, if Deep-Sea Kraken is suspended, remove a time counter from it.
|
||||
addCard(Zone.HAND, playerA, "Deep-Sea Kraken",1);
|
||||
|
||||
// Instant {1}{U}
|
||||
// Counter target spell. If the spell is countered this way, exile it with three time counters on it instead of putting it into its owner's graveyard. If it doesn't have suspend, it gains suspend. (At the beginning of its owner's upkeep, remove a counter from that card. When the last is removed, the player plays it without paying its mana cost. If it's a creature, it has haste.)
|
||||
addCard(Zone.HAND, playerB, "Lightning Bolt",1);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Suspend");
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, "Lightning Bolt", 1);
|
||||
assertExileCount("Deep-Sea Kraken", 1);
|
||||
|
||||
assertCounterOnExiledCardCount("Deep-Sea Kraken", CounterType.TIME, 8); // -1 from spell of player B
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class UnearthTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Hellspark Elemental (and probably other cards with the unearth ability) - If I unearth the elemental,
|
||||
* attack, and then go to the end of my turn both the "sacrifice" and "exile" clauses will trigger and
|
||||
* the game will ask me which one I want to put on the stack first. If I choose "sacrifice" first and
|
||||
* "exile" second, all good, the exile part resolves first and the elemental is exiled, the sacrifice
|
||||
* part does nothing afterwards. But if I choose "exile" first and "sacrifice" second then the elemental
|
||||
* will be sacrificed and placed on my graveyard and after that the "exile" resolves but does nothing, as
|
||||
* I'm guessing it can't "find" the elemental anymore and so it stays in my graveyard, despite the fact
|
||||
* that because I use its unearth ability it should always be exiled once leaving the battlefield no matter what.
|
||||
* The bug should be easy to reproduce if following the order I mention above (click the exile part,
|
||||
* so the sacrifice goes on the top of the stack).
|
||||
*/
|
||||
@Test
|
||||
public void testUnearthAttackExile() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
// 3/1 - Trample, haste
|
||||
// At the beginning of the end step, sacrifice Hellspark Elemental.
|
||||
// Unearth {1}{R} ({1}{R}: Return this card from your graveyard to the battlefield.
|
||||
// It gains haste. Exile it at the beginning of the next end step or if it would
|
||||
// leave the battlefield. Unearth only as a sorcery.)
|
||||
addCard(Zone.GRAVEYARD, playerA, "Hellspark Elemental", 1);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Unearth");
|
||||
|
||||
attack(1, playerA, "Hellspark Elemental");
|
||||
|
||||
setStopAt(2, PhaseStep.UNTAP);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Hellspark Elemental", 0);
|
||||
assertLife(playerB, 17);
|
||||
|
||||
assertPermanentCount(playerA, "Hellspark Elemental", 0);
|
||||
assertExileCount("Hellspark Elemental", 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -205,7 +205,7 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase {
|
|||
}
|
||||
/**
|
||||
* Test that if Soulfire Grand Master has left the battlefield
|
||||
* spell have no longer lifelink
|
||||
* spell has no longer lifelink
|
||||
*/
|
||||
|
||||
@Test
|
||||
|
|
@ -294,5 +294,39 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase {
|
|||
assertLife(playerB, 20);
|
||||
assertLife(playerA, 20);
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* With a Soulfire Grand Master in play, Deflecting Palm doesn't gain the caster life.
|
||||
* It should as it has lifelink, and it's Deflecting Palm (an instant) dealing damage.
|
||||
* I was playing against a human in Standard Constructed.
|
||||
*
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testWithDeflectingPalm() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
// Instant -{R}{W}
|
||||
// The next time a source of your choice would deal damage to you this turn, prevent that damage.
|
||||
// If damage is prevented this way, Deflecting Palm deals that much damage to that source's controller.
|
||||
addCard(Zone.HAND, playerA, "Deflecting Palm");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Soulfire Grand Master", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
|
||||
addCard(Zone.HAND, playerB, "Lightning Bolt", 1);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Deflecting Palm", null, "Lightning Bolt");
|
||||
setChoice(playerA, "Lightning Bolt");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, "Lightning Bolt", 1);
|
||||
assertGraveyardCount(playerA, "Deflecting Palm", 1);
|
||||
|
||||
assertLife(playerB, 17);
|
||||
assertLife(playerA, 23); // damage is prevented + lifelink + 3
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.cards.asthough;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class PlayFromNonHandZoneTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testWorldheartPhoenixNoMana() {
|
||||
// Creature - Phoenix {3}{R}
|
||||
// Flying
|
||||
// You may cast Worldheart Phoenix from your graveyard by paying {W}{U}{B}{R}{G} rather than paying its mana cost.
|
||||
// If you do, it enters the battlefield with two +1/+1 counters on it.
|
||||
addCard(Zone.GRAVEYARD, playerA, "Worldheart Phoenix");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Worldheart Phoenix"); // can only be cast by {W}{U}{B}{R}{G}
|
||||
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Worldheart Phoenix", 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testWorldheartPhoenix() {
|
||||
// Creature - Phoenix {3}{R}
|
||||
// Flying
|
||||
// You may cast Worldheart Phoenix from your graveyard by paying {W}{U}{B}{R}{G} rather than paying its mana cost.
|
||||
// If you do, it enters the battlefield with two +1/+1 counters on it.
|
||||
addCard(Zone.GRAVEYARD, playerA, "Worldheart Phoenix");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Worldheart Phoenix"); // can only be cast by {W}{U}{B}{R}{G}
|
||||
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Worldheart Phoenix", 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.cards.continuous;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class AlmsBeastTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testLifelink() {
|
||||
// Creatures blocking or blocked by Alms Beast have lifelink.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Alms Beast");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
|
||||
|
||||
attack(2, playerB, "Silvercoat Lion");
|
||||
block(2, playerA, "Alms Beast", "Silvercoat Lion");
|
||||
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
|
||||
|
||||
assertLife(playerB, 22); // 20 + 2 from lifelink
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoLifelinkAfterCombat() {
|
||||
// {T}: Rootwater Hunter deals 1 damage to target creature or player.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Rootwater Hunter");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains");
|
||||
// Prevent all damage that would be dealt to target creature this turn.
|
||||
addCard(Zone.HAND, playerA, "Shielded Passage");
|
||||
|
||||
|
||||
// Creatures blocking or blocked by Alms Beast have lifelink.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Alms Beast");
|
||||
|
||||
attack(2, playerB, "Alms Beast");
|
||||
block(2, playerA, "Rootwater Hunter", "Alms Beast");
|
||||
castSpell(2, PhaseStep.DECLARE_BLOCKERS, playerA, "Shielded Passage", "Rootwater Hunter");
|
||||
|
||||
activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: ", playerB); // no life because lifelink ends at combat end
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Shielded Passage", 1);
|
||||
assertPermanentCount(playerA, "Rootwater Hunter", 1);
|
||||
|
||||
assertLife(playerA, 21); // 20 + 1 from lifelink block
|
||||
assertLife(playerB, 19); // -1 from Rootwater Hunter
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.cards.dynamicvalue;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class NumericSetToEffectValueTest extends CardTestPlayerBase {
|
||||
|
||||
|
||||
/**
|
||||
* Check that the dealt damage is added to life
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void ArmadilloCloakTest() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
// Enchant creature
|
||||
// Enchanted creature gets +2/+2 and has trample.
|
||||
// Whenever enchanted creature deals damage, you gain that much life.
|
||||
addCard(Zone.HAND, playerA, "Armadillo Cloak");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Armadillo Cloak", "Silvercoat Lion");
|
||||
|
||||
attack(3, playerA, "Silvercoat Lion");
|
||||
|
||||
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA,"Armadillo Cloak", 1);
|
||||
assertPowerToughness(playerA, "Silvercoat Lion", 4, 4);
|
||||
|
||||
assertLife(playerA, 24);
|
||||
assertLife(playerB, 16);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -29,7 +29,6 @@ package org.mage.test.cards.mana;
|
|||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
|
@ -73,5 +72,36 @@ public class ConditionalManaTest extends CardTestPlayerBase {
|
|||
|
||||
assertHandCount(playerA, "Silvercoat Lion", 1); // player A could not cast Silvercoat Lion because the conditional mana is not available
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testWorkingWithReflectingPool() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Cavern of Souls", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1); // can create white mana without restriction from the Cavern
|
||||
addCard(Zone.HAND, playerA, "Silvercoat Lion", 1);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Silvercoat Lion", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorkingWithReflectingPool2() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1); // can create white mana without restriction from the Hive
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Sliver Hive", 1);
|
||||
addCard(Zone.HAND, playerA, "Silvercoat Lion", 1);
|
||||
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {1} to your mana pool");
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add to your mana pool one mana of any type");
|
||||
setChoice(playerA, "White");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Silvercoat Lion", 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,4 +64,30 @@ public class SwansOfBrynArgollTest extends CardTestPlayerBase{
|
|||
assertHandCount(playerA, 0);
|
||||
|
||||
}
|
||||
/**
|
||||
* Since you can't prevent damage that Combust deals, it should be able to kill Swans of Bryn Argoll.
|
||||
*/
|
||||
@Test
|
||||
public void testAgainstBanefire() {
|
||||
// 4/3 Flying
|
||||
// If a source would deal damage to Swans of Bryn Argoll, prevent that damage. The source's controller draws cards equal to the damage prevented this way.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swans of Bryn Argoll");
|
||||
|
||||
// Banefire deals X damage to target creature or player.
|
||||
// If X is 5 or more, Banefire can't be countered by spells or abilities and the damage can't be prevented.
|
||||
addCard(Zone.HAND, playerB, "Banefire", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 8);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Banefire", "Swans of Bryn Argoll");
|
||||
setChoice(playerB, "X=7");
|
||||
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, "Banefire", 1);
|
||||
assertPermanentCount(playerA, "Swans of Bryn Argoll", 0);
|
||||
assertGraveyardCount(playerA, "Swans of Bryn Argoll", 1);
|
||||
assertHandCount(playerA, 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,8 @@ public class HarmsWayRedirectDamageTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Plains");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Harm's Way", "Lightning Bolt^targetPlayer=PlayerA");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Harm's Way", playerA);
|
||||
setChoice(playerB, "Lightning Bolt");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
|
@ -48,8 +49,9 @@ public class HarmsWayRedirectDamageTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Craw Wurm");
|
||||
|
||||
attack(2, playerB, "Craw Wurm");
|
||||
castSpell(2, PhaseStep.DECLARE_BLOCKERS, playerA, "Harm's Way", "Craw Wurm^targetPlayer=PlayerB");
|
||||
|
||||
castSpell(2, PhaseStep.DECLARE_BLOCKERS, playerA, "Harm's Way", playerB);
|
||||
setChoice(playerA, "Craw Wurm");
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
|
|
@ -76,8 +78,9 @@ public class HarmsWayRedirectDamageTest extends CardTestPlayerBase {
|
|||
// When Magma Phoenix dies, it deals 3 damage to each creature and each player.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Magma Phoenix");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Harm's Way", "Magma Phoenix^targetPlayer=PlayerB"/**,
|
||||
"When Magma Phoenix dies, Magma Phoenix deals 3 damage to each creature and each player"**/);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Harm's Way", playerB);
|
||||
setChoice(playerA, "Magma Phoenix");
|
||||
/** When Magma Phoenix dies, Magma Phoenix deals 3 damage to each creature and each player **/
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Magma Phoenix");
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.cards.rules;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class WorldEnchantmentsRuleTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* 704.5m If two or more permanents have the supertype world, all except the one that has had
|
||||
* the world supertype for the shortest amount of time are put into their owners’ graveyards.
|
||||
* In the event of a tie for the shortest amount of time, all are put into their owners’ graveyards.
|
||||
* This is called the “world rule.
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void TestTwoWorldEnchantsments() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
addCard(Zone.HAND, playerA, "Nether Void", 1);
|
||||
addCard(Zone.HAND, playerA, "Silvercoat Lion", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 7);
|
||||
addCard(Zone.HAND, playerB, "Nether Void", 1);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Nether Void");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion"); // just needed to get different craete time to second Nether Void
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Nether Void");
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Nether Void", 0);
|
||||
assertPermanentCount(playerB, "Nether Void", 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ public class HavengulLichTest extends CardTestPlayerBase {
|
|||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", "Prodigal Pyromancer");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Prodigal Pyromancer");
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}", playerB);
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: {source} deals", playerB);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
|
|
@ -53,13 +53,16 @@ public class HavengulLichTest extends CardTestPlayerBase {
|
|||
@Test
|
||||
public void testCard2() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
|
||||
// {1}: You may cast target creature card in a graveyard this turn. When you cast that card this turn, Havengul Lich
|
||||
// gains all activated abilities of that card until end of turn.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Havengul Lich");
|
||||
// {T}: Prodigal Pyromancer deals 1 damage to target creature or player.
|
||||
addCard(Zone.GRAVEYARD, playerA, "Prodigal Pyromancer");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", "Prodigal Pyromancer");
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}: You may", "Prodigal Pyromancer");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Prodigal Pyromancer");
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}", playerB);
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}", playerB);
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", playerB);
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", playerB); // only inm turn 1, so Havengul Lich has the abilit ylost now
|
||||
setStopAt(3, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
|
|
|
|||
|
|
@ -360,16 +360,24 @@ public class TestPlayer extends ComputerPlayer {
|
|||
MageObject targetObject = game.getObject(targetId);
|
||||
if (targetObject != null) {
|
||||
for (String choose2: choices) {
|
||||
if (targetObject.getName().equals(choose2)) {
|
||||
List<UUID> alreadyTargetted = target.getTargets();
|
||||
if (t.canTarget(targetObject.getId(), game)) {
|
||||
if (alreadyTargetted != null && !alreadyTargetted.contains(targetObject.getId())) {
|
||||
target.add(targetObject.getId(), game);
|
||||
choices.remove(choose2);
|
||||
return true;
|
||||
String[] targetList = choose2.split("\\^");
|
||||
boolean targetFound = false;
|
||||
for (String targetName: targetList) {
|
||||
if (targetObject.getName().equals(targetName)) {
|
||||
List<UUID> alreadyTargetted = target.getTargets();
|
||||
if (t.canTarget(targetObject.getId(), game)) {
|
||||
if (alreadyTargetted != null && !alreadyTargetted.contains(targetObject.getId())) {
|
||||
target.add(targetObject.getId(), game);
|
||||
choices.remove(choose2);
|
||||
targetFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (targetFound) {
|
||||
choices.remove(choose2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -448,7 +448,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
@Override
|
||||
public void assertPermanentCount(Player player, String cardName, int count) throws AssertionError {
|
||||
int actualCount = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) {
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents()) {
|
||||
if (permanent.getControllerId().equals(player.getId())) {
|
||||
if (permanent.getName().equals(cardName)) {
|
||||
actualCount++;
|
||||
|
|
@ -490,12 +490,32 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertNotNull("There is no such permanent on the battlefield, cardName=" + cardName, found);
|
||||
|
||||
Assert.assertEquals("(Battlefield) Counter counts are not equal (" + cardName + ":" + type + ")", count, found.getCounters().getCount(type));
|
||||
}
|
||||
/**
|
||||
* Assert counter count on a card in exile
|
||||
*
|
||||
* @param cardName Name of the cards that should be counted.
|
||||
* @param type Type of the counter that should be counted.
|
||||
* @param count Expected count.
|
||||
*/
|
||||
public void assertCounterOnExiledCardCount(String cardName, CounterType type, int count) throws AssertionError {
|
||||
Card found = null;
|
||||
|
||||
if (found == null) {
|
||||
for (Card card : currentGame.getExile().getAllCards(currentGame)) {
|
||||
if (card.getName().equals(cardName)) {
|
||||
found = card;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Assert.assertNotNull("There is no such card in the exile, cardName=" + cardName, found);
|
||||
Assert.assertEquals("(Exile) Counter counts are not equal (" + cardName + ":" + type + ")", count, found.getCounters(currentGame).getCount(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert counter count on a player
|
||||
*
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ import org.junit.Test;
|
|||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* This test checks if the calculated possible mana options are correct related to the given mana sources available.
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class ManaOptionsTest extends CardTestPlayerBase {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ public class ManaUtilTest extends CardTestPlayerBase {
|
|||
testManaToPayVsLand("{1}{R}", "Cavern of Souls", 2, 2); // can't auto choose to pay
|
||||
testManaToPayVsLand("{2}", "Cavern of Souls", 2, 2); // can't auto choose to pay
|
||||
|
||||
testManaToPayVsLand("{2}", "Eldrazi Temple", 2, 2); // can't auto choose to pay
|
||||
|
||||
// hybrid mana
|
||||
testManaToPayVsLand("{W/R}{W/R}{W/R}", "Sacred Foundry", 2, 1); // auto choose for hybrid mana: choose any
|
||||
testManaToPayVsLand("{R}{W/R}", "Sacred Foundry", 2, RedManaAbility.class); // auto choose for hybrid mana: we should choose {R}
|
||||
|
|
@ -122,7 +124,7 @@ public class ManaUtilTest extends CardTestPlayerBase {
|
|||
* @return
|
||||
*/
|
||||
private HashMap<UUID, ManaAbility> getManaAbilities(Card card) {
|
||||
HashMap<UUID, ManaAbility> useableAbilities = new LinkedHashMap<UUID, ManaAbility>();
|
||||
HashMap<UUID, ManaAbility> useableAbilities = new LinkedHashMap<>();
|
||||
for (Ability ability: card.getAbilities()) {
|
||||
if (ability instanceof ManaAbility) {
|
||||
ability.newId(); // we need to assign id manually as we are not in game
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue