package net.demilich.metastone.tests; import java.util.List; import org.testng.Assert; import org.testng.annotations.Test; import net.demilich.metastone.game.GameContext; import net.demilich.metastone.game.Player; import net.demilich.metastone.game.actions.GameAction; import net.demilich.metastone.game.actions.PhysicalAttackAction; import net.demilich.metastone.game.cards.Card; import net.demilich.metastone.game.cards.CardCatalogue; import net.demilich.metastone.game.cards.MinionCard; import net.demilich.metastone.game.cards.SpellCard; import net.demilich.metastone.game.entities.Actor; import net.demilich.metastone.game.entities.Entity; import net.demilich.metastone.game.entities.heroes.Hero; import net.demilich.metastone.game.entities.heroes.HeroClass; import net.demilich.metastone.game.entities.minions.Minion; import net.demilich.metastone.game.spells.DamageSpell; import net.demilich.metastone.game.spells.DestroySpell; import net.demilich.metastone.game.spells.desc.SpellDesc; import net.demilich.metastone.game.targeting.EntityReference; import net.demilich.metastone.game.targeting.TargetSelection; public class SpecialCardTests extends TestBase { @Test public void testFaerieDragon() { GameContext context = createContext(HeroClass.MAGE, HeroClass.WARRIOR); Player mage = context.getPlayer1(); mage.setMana(10); Player warrior = context.getPlayer2(); warrior.setMana(10); MinionCard faerieDragonCard = (MinionCard) CardCatalogue.getCardById("minion_faerie_dragon"); context.getLogic().receiveCard(warrior.getId(), faerieDragonCard); context.getLogic().performGameAction(warrior.getId(), faerieDragonCard.play()); MinionCard devMonsterCard = new TestMinionCard(1, 1); context.getLogic().receiveCard(mage.getId(), devMonsterCard); context.getLogic().performGameAction(mage.getId(), devMonsterCard.play()); Entity attacker = getSingleMinion(mage.getMinions()); Actor elusiveOne = getSingleMinion(warrior.getMinions()); GameAction attackAction = new PhysicalAttackAction(attacker.getReference()); List<Entity> validTargets = context.getLogic().getValidTargets(warrior.getId(), attackAction); // should be two valid targets: enemy hero and faerie dragon Assert.assertEquals(validTargets.size(), 2); GameAction useFireblast = mage.getHero().getHeroPower().play(); validTargets = context.getLogic().getValidTargets(mage.getId(), useFireblast); // should be three valid targets, both heroes + minion which is not the // faerie dragon Assert.assertEquals(validTargets.size(), 3); Assert.assertFalse(validTargets.contains(elusiveOne)); Card arcaneExplosionCard = CardCatalogue.getCardById("spell_arcane_explosion"); context.getLogic().receiveCard(mage.getId(), arcaneExplosionCard); int faerieDragonHp = elusiveOne.getHp(); context.getLogic().performGameAction(mage.getId(), arcaneExplosionCard.play()); // hp should been affected after playing area of effect spell Assert.assertNotEquals(faerieDragonHp, elusiveOne.getHp()); } @Test public void testGurubashiBerserker() { GameContext context = createContext(HeroClass.MAGE, HeroClass.WARRIOR); Player mage = context.getPlayer1(); mage.setMana(10); Player warrior = context.getPlayer2(); warrior.setMana(10); final int BASE_ATTACK = 2; final int ATTACK_BONUS = 3; MinionCard gurubashiBerserkerCard = (MinionCard) CardCatalogue.getCardById("minion_gurubashi_berserker"); playCard(context, warrior, gurubashiBerserkerCard); MinionCard oasisSnapjawCard = (MinionCard) CardCatalogue.getCardById("minion_oasis_snapjaw"); playCard(context, mage, oasisSnapjawCard); Actor attacker = getSingleMinion(mage.getMinions()); Actor defender = getSingleMinion(warrior.getMinions()); // Gurubashi Berserker should start with just his base attack Assert.assertEquals(defender.getAttack(), BASE_ATTACK); // first attack, Gurubashi Berserker should have increased attack GameAction attackAction = new PhysicalAttackAction(attacker.getReference()); attackAction.setTarget(defender); context.getLogic().performGameAction(mage.getId(), attackAction); Assert.assertEquals(attacker.getHp(), attacker.getMaxHp() - BASE_ATTACK); Assert.assertEquals(defender.getHp(), defender.getMaxHp() - attacker.getAttack()); Assert.assertEquals(defender.getAttack(), BASE_ATTACK + ATTACK_BONUS); // second attack, Gurubashi Berserker should become even stronger context.getLogic().performGameAction(mage.getId(), attackAction); Assert.assertEquals(attacker.getHp(), attacker.getMaxHp() - 2 * BASE_ATTACK - ATTACK_BONUS); Assert.assertEquals(defender.getHp(), defender.getMaxHp() - 2 * attacker.getAttack()); Assert.assertEquals(defender.getAttack(), BASE_ATTACK + 2 * ATTACK_BONUS); } @Test public void testSavageRoar() { GameContext context = createContext(HeroClass.DRUID, HeroClass.WARRIOR); Player player = context.getPlayer1(); Hero druid = player.getHero(); player.setMana(10); Player warrior = context.getPlayer2(); warrior.setMana(10); MinionCard devMonsterCard = new TestMinionCard(1, 1); context.getLogic().receiveCard(player.getId(), devMonsterCard); context.getLogic().performGameAction(player.getId(), devMonsterCard.play()); Actor minion = getSingleMinion(player.getMinions()); context.getLogic().performGameAction(player.getId(), druid.getHeroPower().play()); Assert.assertEquals(druid.getAttack(), 1); Assert.assertEquals(minion.getAttack(), 1); Card savageRoar = CardCatalogue.getCardById("spell_savage_roar"); context.getLogic().receiveCard(player.getId(), savageRoar); context.getLogic().performGameAction(player.getId(), savageRoar.play()); Assert.assertEquals(druid.getAttack(), 3); Assert.assertEquals(minion.getAttack(), 3); context.getLogic().endTurn(player.getId()); Assert.assertEquals(druid.getAttack(), 0); Assert.assertEquals(minion.getAttack(), 1); context.getLogic().endTurn(player.getId()); Assert.assertEquals(druid.getAttack(), 0); Assert.assertEquals(minion.getAttack(), 1); } @Test public void testSpitefulSmith() { GameContext context = createContext(HeroClass.WARRIOR, HeroClass.WARRIOR); Player player = context.getPlayer1(); player.setMana(10); Card fieryWarAxe = CardCatalogue.getCardById("weapon_fiery_war_axe"); playCard(context, player, fieryWarAxe); Assert.assertTrue(player.getHero().getWeapon() != null); Assert.assertEquals(player.getHero().getWeapon().getWeaponDamage(), 3); MinionCard spitefulSmithCard = (MinionCard) CardCatalogue.getCardById("minion_spiteful_smith"); Minion spitefulSmith = playMinionCard(context, player, spitefulSmithCard); // Smith has been played, but is not enraged yet, so weapon damage // should still be unaltered Assert.assertEquals(player.getHero().getWeapon().getWeaponDamage(), 3); SpellCard damageSpell = new TestSpellCard(DamageSpell.create(1)); damageSpell.setTargetRequirement(TargetSelection.ANY); context.getLogic().receiveCard(player.getId(), damageSpell); GameAction spellAction = damageSpell.play(); spellAction.setTarget(spitefulSmith); context.getLogic().performGameAction(player.getId(), spellAction); // Smith is damaged now, so weapon should be buffed Assert.assertEquals(player.getHero().getWeapon().getWeaponDamage(), 5); // equip a new weapon; this one should get buffed too fieryWarAxe = CardCatalogue.getCardById("weapon_fiery_war_axe"); playCard(context, player, fieryWarAxe); Assert.assertEquals(player.getHero().getWeapon().getWeaponDamage(), 5); // wipe everything SpellDesc wipeSpell = DestroySpell.create(EntityReference.ALL_MINIONS); SpellCard wipe = new TestSpellCard(wipeSpell); playCard(context, player, wipe); // Smith is destroyed, weapon power should be back to normal Assert.assertEquals(player.getHero().getWeapon().getWeaponDamage(), 3); } @Test public void testSummoningPortal() { GameContext context = createContext(HeroClass.WARLOCK, HeroClass.WARRIOR); Player player = context.getPlayer1(); player.setMana(10); Card summoningPortal1 = CardCatalogue.getCardById("minion_summoning_portal"); context.getLogic().receiveCard(player.getId(), summoningPortal1); Card summoningPortal2 = CardCatalogue.getCardById("minion_summoning_portal"); context.getLogic().receiveCard(player.getId(), summoningPortal2); MinionCard testMinionCard = new TestMinionCard(1, 1, 4); context.getLogic().receiveCard(player.getId(), testMinionCard); Assert.assertEquals(player.getMana(), 10); // first summoning portal costs full 4 mana context.getLogic().performGameAction(player.getId(), summoningPortal1.play()); Assert.assertEquals(player.getMana(), 6); // second summoning portal affected by first one, costs only 2 mana context.getLogic().performGameAction(player.getId(), summoningPortal2.play()); Assert.assertEquals(player.getMana(), 4); // base cost of minion card is 4, reduced by both summoning portals, but // not below 1 context.getLogic().performGameAction(player.getId(), testMinionCard.play()); Assert.assertEquals(player.getMana(), 3); } @Test public void testWildPyromancer() { GameContext context = createContext(HeroClass.PRIEST, HeroClass.WARRIOR); Player warrior = context.getPlayer2(); Card hauntedCreeper = CardCatalogue.getCardById("minion_haunted_creeper"); playCard(context, warrior, hauntedCreeper); Player priest = context.getPlayer1(); Card wildPyromancer = CardCatalogue.getCardById("minion_wild_pyromancer"); playCard(context, priest, wildPyromancer); Assert.assertEquals(warrior.getMinions().size(), 1); Card holyNova = CardCatalogue.getCardById("spell_holy_nova"); playCard(context, priest, holyNova); // the warriors board should be completely wiped, as the Holy Nova // should kill the // first body of Haunted Creeper, the Deathrattle resolves and then Wild // Pyromancer // triggers, clearing the two 1/1 Spectral Spiders Assert.assertEquals(warrior.getMinions().size(), 0); } @Test public void testBetrayal() { GameContext context = createContext(HeroClass.PALADIN, HeroClass.ROGUE); Player paladin = context.getPlayer1(); MinionCard adjacentMinionCard1 = new TestMinionCard(1, 5, 0); Minion adjacentMinion1 = playMinionCard(context, paladin, adjacentMinionCard1); MinionCard targetMinionCard = new TestMinionCard(3, 1, 0); Minion targetMinion = playMinionCard(context, paladin, targetMinionCard); MinionCard adjacentMinionCard2 = new TestMinionCard(1, 5, 0); Minion adjacentMinion2 = playMinionCard(context, paladin, adjacentMinionCard2); context.getLogic().endTurn(paladin.getId()); Assert.assertEquals(paladin.getMinions().size(), 3); Player rogue = context.getPlayer2(); Card betrayal = CardCatalogue.getCardById("spell_betrayal"); context.getLogic().receiveCard(rogue.getId(), betrayal); GameAction action = betrayal.play(); action.setTarget(targetMinion); context.getLogic().performGameAction(rogue.getId(), action); Assert.assertEquals(targetMinion.getAttack(), 3); Assert.assertEquals(targetMinion.getHp(), 1); Assert.assertEquals(adjacentMinion1.getHp(), 2); Assert.assertEquals(adjacentMinion2.getHp(), 2); Assert.assertEquals(paladin.getMinions().size(), 3); } @Test public void testBetrayalNotAffectedBySpellDamage() { GameContext context = createContext(HeroClass.PALADIN, HeroClass.ROGUE); Player paladin = context.getPlayer1(); MinionCard adjacentMinionCard1 = new TestMinionCard(1, 5, 0); Minion adjacentMinion1 = playMinionCard(context, paladin, adjacentMinionCard1); MinionCard targetMinionCard = new TestMinionCard(3, 1, 0); Minion targetMinion = playMinionCard(context, paladin, targetMinionCard); MinionCard adjacentMinionCard2 = new TestMinionCard(1, 5, 0); Minion adjacentMinion2 = playMinionCard(context, paladin, adjacentMinionCard2); context.getLogic().endTurn(paladin.getId()); Player rogue = context.getPlayer2(); MinionCard azureDrakeCard = (MinionCard) CardCatalogue.getCardById("minion_azure_drake"); playMinionCard(context, rogue, azureDrakeCard); Card betrayal = CardCatalogue.getCardById("spell_betrayal"); context.getLogic().receiveCard(rogue.getId(), betrayal); GameAction action = betrayal.play(); action.setTarget(targetMinion); context.getLogic().performGameAction(rogue.getId(), action); Assert.assertEquals(targetMinion.getAttack(), 3); Assert.assertEquals(targetMinion.getHp(), 1); Assert.assertEquals(adjacentMinion1.getHp(), 2); Assert.assertEquals(adjacentMinion2.getHp(), 2); } @Test public void testBetrayalOnEmperorCobraDestroysAdjacentMinions() { GameContext context = createContext(HeroClass.PALADIN, HeroClass.ROGUE); Player paladin = context.getPlayer1(); MinionCard adjacentMinionCard1 = new TestMinionCard(1, 5, 0); playMinionCard(context, paladin, adjacentMinionCard1); MinionCard targetMinionCard = (MinionCard) CardCatalogue.getCardById("minion_emperor_cobra"); Minion targetMinion = playMinionCard(context, paladin, targetMinionCard); MinionCard adjacentMinionCard2 = new TestMinionCard(1, 5, 0); playMinionCard(context, paladin, adjacentMinionCard2); context.getLogic().endTurn(paladin.getId()); Assert.assertEquals(paladin.getMinions().size(), 3); Player rogue = context.getPlayer2(); Card betrayal = CardCatalogue.getCardById("spell_betrayal"); context.getLogic().receiveCard(rogue.getId(), betrayal); GameAction action = betrayal.play(); action.setTarget(targetMinion); context.getLogic().performGameAction(rogue.getId(), action); Assert.assertEquals(paladin.getMinions().size(), 1); } @Test public void testEydisDarkbane() { GameContext context = createContext(HeroClass.PRIEST, HeroClass.WARRIOR); Player priest = context.getPlayer1(); Player warrior = context.getPlayer2(); MinionCard eydisDarkbaneCard = (MinionCard) CardCatalogue.getCardById("minion_eydis_darkbane"); Minion eydisDarkbane = playMinionCard(context, priest, eydisDarkbaneCard); Card testSpellCard = CardCatalogue.getCardById("spell_power_word_shield"); context.getLogic().receiveCard(priest.getId(), testSpellCard); GameAction spellAction = testSpellCard.play(); spellAction.setTarget(eydisDarkbane); context.getLogic().performGameAction(priest.getId(), spellAction); // priest casted a spell on Eydis - warrior should be wounded Assert.assertEquals(warrior.getHero().getHp(), warrior.getHero().getMaxHp() - 3); testSpellCard = CardCatalogue.getCardById("spell_shield_slam"); context.getLogic().receiveCard(warrior.getId(), testSpellCard); spellAction = testSpellCard.play(); spellAction.setTarget(eydisDarkbane); context.getLogic().performGameAction(warrior.getId(), spellAction); // warrior casted a spell on Eydis - nothing should happen Assert.assertEquals(warrior.getHero().getHp(), warrior.getHero().getMaxHp() - 3); } @Test public void testBetrayalOnBurlyRockjawTroggDeals5Damage() { GameContext context = createContext(HeroClass.PALADIN, HeroClass.ROGUE); Player paladin = context.getPlayer1(); MinionCard adjacentMinionCard1 = new TestMinionCard(1, 5, 0); playMinionCard(context, paladin, adjacentMinionCard1); MinionCard targetMinionCard = (MinionCard) CardCatalogue.getCardById("minion_burly_rockjaw_trogg"); Minion targetMinion = playMinionCard(context, paladin, targetMinionCard); MinionCard adjacentMinionCard2 = new TestMinionCard(1, 5, 0); playMinionCard(context, paladin, adjacentMinionCard2); context.getLogic().endTurn(paladin.getId()); Assert.assertEquals(paladin.getMinions().size(), 3); Player rogue = context.getPlayer2(); Card betrayal = CardCatalogue.getCardById("spell_betrayal"); context.getLogic().receiveCard(rogue.getId(), betrayal); GameAction action = betrayal.play(); action.setTarget(targetMinion); context.getLogic().performGameAction(rogue.getId(), action); Assert.assertEquals(paladin.getMinions().size(), 1); } @Test public void testRallyingBlade() { GameContext context = createContext(HeroClass.PALADIN, HeroClass.ROGUE); Player player = context.getPlayer1(); MinionCard argentSquireCard = (MinionCard) CardCatalogue.getCardById("minion_argent_squire"); Minion argentSquire = playMinionCard(context, player, argentSquireCard); Assert.assertEquals(argentSquire.getAttack(), 1); Assert.assertEquals(argentSquire.getHp(), 1); Card rallyingBladeCard = CardCatalogue.getCardById("weapon_rallying_blade"); playCard(context, player, rallyingBladeCard); Assert.assertEquals(argentSquire.getAttack(), 2); Assert.assertEquals(argentSquire.getHp(), 2); } @Test public void testCurseOfRafaam() { GameContext context = createContext(HeroClass.WARRIOR, HeroClass.WARLOCK); Player player = context.getPlayer1(); Card koboldGeomancerCard = CardCatalogue.getCardById("minion_kobold_geomancer"); playCard(context, player, koboldGeomancerCard); context.endTurn(); Player opponent = context.getPlayer2(); Card curseOfRafaamCard = CardCatalogue.getCardById("spell_curse_of_rafaam"); playCard(context, opponent, curseOfRafaamCard); context.endTurn(); final int CURSE_OF_RAFAAM_DAMAGE = 2; // first player should take exactly 2 damage (NOT 3, because the spell // damage should not be applied) Assert.assertEquals(player.getHero().getHp(), player.getHero().getMaxHp() - CURSE_OF_RAFAAM_DAMAGE); } @Test public void testEmperorThaurissanEmptyHand() { GameContext context = createContext(HeroClass.WARRIOR, HeroClass.WARLOCK); Player player = context.getPlayer1(); MinionCard emperorThaurissanCard = (MinionCard) CardCatalogue.getCardById("minion_emperor_thaurissan"); Minion emperorThaurissan = playMinionCard(context, player, emperorThaurissanCard); for (Card card : player.getHand().toList()) { context.getLogic().removeCard(player.getId(), card); } Assert.assertTrue(player.getHand().isEmpty()); context.endTurn(); Player opponent = context.getPlayer2(); Card assassinateCard = CardCatalogue.getCardById("spell_assassinate"); playCardWithTarget(context, opponent, assassinateCard, emperorThaurissan); context.getLogic().receiveCard(player.getId(), CardCatalogue.getCardById("minion_chillwind_yeti")); context.endTurn(); Card card = player.getHand().peekFirst(); int modifiedCost = context.getLogic().getModifiedManaCost(player, card); System.out.println("Card [" + card.getName() + "] has baseManaCost of " + card.getBaseManaCost() + " and current actual manacost of " + modifiedCost); Assert.assertEquals(card.getBaseManaCost(), modifiedCost); } }