diff --git a/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java b/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java index 79dd93dfd96..58cdb7b47a1 100644 --- a/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java +++ b/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java @@ -1,10 +1,11 @@ package mage.cards.g; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.PreventionEffectData; +import mage.abilities.effects.PreventionEffectImpl; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.FlyingAbility; @@ -13,12 +14,13 @@ import mage.cards.CardSetInfo; import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; +import mage.players.Player; import mage.util.CardUtil; +import java.util.UUID; + /** - * @author noxx + * @author TheElk801 */ public final class GiselaBladeOfGoldnight extends CardImpl { @@ -34,11 +36,13 @@ public final class GiselaBladeOfGoldnight extends CardImpl { this.addAbility(FirstStrikeAbility.getInstance()); // If a source would deal damage to an opponent or a permanent an opponent controls, that source deals double that damage to that player or permanent instead. + this.addAbility(new SimpleStaticAbility(new GiselaBladeOfGoldnightDoubleDamageEffect())); + // If a source would deal damage to you or a permanent you control, prevent half that damage, rounded up. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GiselaBladeOfGoldnightDoubleDamageEffect())); + this.addAbility(new SimpleStaticAbility(new GiselaBladeOfGoldnightPreventionEffect())); } - public GiselaBladeOfGoldnight(final GiselaBladeOfGoldnight card) { + private GiselaBladeOfGoldnight(final GiselaBladeOfGoldnight card) { super(card); } @@ -50,13 +54,13 @@ public final class GiselaBladeOfGoldnight extends CardImpl { class GiselaBladeOfGoldnightDoubleDamageEffect extends ReplacementEffectImpl { - public GiselaBladeOfGoldnightDoubleDamageEffect() { + GiselaBladeOfGoldnightDoubleDamageEffect() { super(Duration.WhileOnBattlefield, Outcome.Damage); - staticText = "If a source would deal damage to an opponent or a permanent an opponent controls, that source deals double that damage to that player or permanent instead." - + "If a source would deal damage to you or a permanent you control, prevent half that damage, rounded up"; + staticText = "If a source would deal damage to an opponent or a permanent an opponent controls, " + + "that source deals double that damage to that player or permanent instead."; } - public GiselaBladeOfGoldnightDoubleDamageEffect(final GiselaBladeOfGoldnightDoubleDamageEffect effect) { + private GiselaBladeOfGoldnightDoubleDamageEffect(final GiselaBladeOfGoldnightDoubleDamageEffect effect) { super(effect); } @@ -67,24 +71,24 @@ class GiselaBladeOfGoldnightDoubleDamageEffect extends ReplacementEffectImpl { @Override public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == EventType.DAMAGE_CREATURE || - event.getType() == EventType.DAMAGE_PLANESWALKER || - event.getType() == EventType.DAMAGE_PLAYER; + switch (event.getType()) { + case DAMAGE_CREATURE: + case DAMAGE_PLAYER: + case DAMAGE_PLANESWALKER: + return true; + default: + return false; + } } - @Override public boolean applies(GameEvent event, Ability source, Game game) { - return true; - } - - private void preventDamage(GameEvent event, Ability source, UUID target, Game game) { - int amount = (int) Math.ceil(event.getAmount() / 2.0); - GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, target, source.getSourceId(), source.getControllerId(), amount, false); - if (!game.replaceEvent(preventEvent)) { - event.setAmount(event.getAmount() - amount); - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, target, source.getSourceId(), source.getControllerId(), amount)); + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; } + return player.hasOpponent(event.getTargetId(), game) + || player.hasOpponent(game.getControllerId(event.getTargetId()), game); } @Override @@ -94,25 +98,36 @@ class GiselaBladeOfGoldnightDoubleDamageEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - switch (event.getType()) { - case DAMAGE_PLAYER: - if (event.getTargetId().equals(source.getControllerId())) { - preventDamage(event, source, source.getControllerId(), game); - } else if (game.getOpponents(source.getControllerId()).contains(event.getTargetId())) { - event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); - } - break; - case DAMAGE_CREATURE: - case DAMAGE_PLANESWALKER: - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null) { - if (permanent.isControlledBy(source.getControllerId())) { - preventDamage(event, source, permanent.getId(), game); - } else if (game.getOpponents(source.getControllerId()).contains(permanent.getControllerId())) { - event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); - } - } - } + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); return false; } } + +class GiselaBladeOfGoldnightPreventionEffect extends PreventionEffectImpl { + + GiselaBladeOfGoldnightPreventionEffect() { + super(Duration.WhileOnBattlefield); + this.staticText = "If a source would deal damage to you or a permanent you control, " + + "prevent half that damage, rounded up"; + } + + private GiselaBladeOfGoldnightPreventionEffect(final GiselaBladeOfGoldnightPreventionEffect effect) { + super(effect); + } + + @Override + public GiselaBladeOfGoldnightPreventionEffect copy() { + return new GiselaBladeOfGoldnightPreventionEffect(this); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return source.isControlledBy(event.getTargetId()) + || source.isControlledBy(game.getControllerId(event.getTargetId())); + } + + @Override + protected PreventionEffectData preventDamageAction(GameEvent event, Ability source, Game game) { + return game.preventDamage(event, source, game, Math.floorDiv(event.getAmount(), 2) + (event.getAmount() % 2)); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/GiselaBladeOfGoldnightTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/GiselaBladeOfGoldnightTest.java index b00442e0f42..672e6b8d1d1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/GiselaBladeOfGoldnightTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/GiselaBladeOfGoldnightTest.java @@ -2,7 +2,6 @@ package org.mage.test.cards.single; import mage.constants.PhaseStep; import mage.constants.Zone; -import org.junit.Ignore; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -48,6 +47,42 @@ public class GiselaBladeOfGoldnightTest extends CardTestPlayerBase { assertPermanentCount(playerB, "Air Elemental", 0); } + @Test + public void test_DamageToOpponent_WithGisela() { + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 6); + addCard(Zone.BATTLEFIELD, playerB, "Gisela, Blade of Goldnight"); + addCard(Zone.HAND, playerB, "Banefire"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Banefire", playerA); + setChoice(playerB, "X=5"); + + setStopAt(2, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + // Player A should take double damage + assertLife(playerA, 20 - 10); + } + + @Test + public void test_DamageToOpponentsCreature_WithGisela() { + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2); + addCard(Zone.BATTLEFIELD, playerB, "Gisela, Blade of Goldnight"); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); // 2/2 + addCard(Zone.HAND, playerB, "Banefire"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Banefire", "Grizzly Bears"); + setChoice(playerB, "X=1"); + + setStopAt(2, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + // creature takes 2 damage and dies + assertPermanentCount(playerA, "Grizzly Bears", 0); + assertLife(playerA, 20); + } + @Test public void test_DamageToPlayer_Preventable() { addCard(Zone.BATTLEFIELD, playerB, "Mountain", 5); @@ -97,7 +132,6 @@ public class GiselaBladeOfGoldnightTest extends CardTestPlayerBase { assertLife(playerA, 20 - 2); } - @Ignore @Test public void test_DamageToPlayer_UnpreventableWithGisela() { addCard(Zone.BATTLEFIELD, playerB, "Mountain", 6); @@ -134,7 +168,6 @@ public class GiselaBladeOfGoldnightTest extends CardTestPlayerBase { assertLife(playerA, 20); } - @Ignore @Test public void test_DamageToCreature_UnpreventableWithGisela() { addCard(Zone.BATTLEFIELD, playerB, "Mountain", 7);