fixed Gisela preventing damage from unpreventable damage sources (fixes #5554)

This commit is contained in:
Evan Kranzler 2019-01-27 19:43:14 -05:00
parent 2ad90e44b0
commit 9d96efb936
2 changed files with 93 additions and 45 deletions

View file

@ -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));
}
}