From 4d3b944b65f92c7098608b9e6a0323f017ae43fb Mon Sep 17 00:00:00 2001 From: Susucre <34709007+Susucre@users.noreply.github.com> Date: Fri, 4 Aug 2023 04:11:59 +0200 Subject: [PATCH] Fix Clash effect causing NullPointerExceptions (#10742) --- .../src/mage/cards/c/CaptivatingGlance.java | 12 ++++++------ .../mage/abilities/effects/EffectImpl.java | 7 +++++++ .../abilities/effects/common/ClashEffect.java | 3 ++- .../effects/common/DoIfClashWonEffect.java | 18 +++++++++--------- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CaptivatingGlance.java b/Mage.Sets/src/mage/cards/c/CaptivatingGlance.java index e9bd8abface..bcba97ac69d 100644 --- a/Mage.Sets/src/mage/cards/c/CaptivatingGlance.java +++ b/Mage.Sets/src/mage/cards/c/CaptivatingGlance.java @@ -1,7 +1,6 @@ package mage.cards.c; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; import mage.abilities.effects.ContinuousEffect; @@ -13,9 +12,9 @@ import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -23,8 +22,9 @@ import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class CaptivatingGlance extends CardImpl { @@ -87,9 +87,9 @@ class CaptivatingGlanceEffect extends OneShotEffect { effect.setTargetPointer(new FixedTarget(enchantedCreature, game)); game.addEffect(effect, source); } else { - Object opponent = getValue("clashOpponent"); - if (opponent instanceof Player) { - ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, ((Player)opponent).getId()); + Player opponent = game.getPlayer((UUID) getValue("clashOpponent")); + if (opponent != null) { + ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, opponent.getId()); effect.setTargetPointer(new FixedTarget(enchantedCreature, game)); game.addEffect(effect, source); } diff --git a/Mage/src/main/java/mage/abilities/effects/EffectImpl.java b/Mage/src/main/java/mage/abilities/effects/EffectImpl.java index 086846611a6..79b7c93c332 100644 --- a/Mage/src/main/java/mage/abilities/effects/EffectImpl.java +++ b/Mage/src/main/java/mage/abilities/effects/EffectImpl.java @@ -4,6 +4,7 @@ import mage.abilities.MageSingleton; import mage.abilities.Mode; import mage.constants.EffectType; import mage.constants.Outcome; +import mage.players.Player; import mage.target.targetpointer.FirstTargetPointer; import mage.target.targetpointer.TargetPointer; @@ -104,6 +105,12 @@ public abstract class EffectImpl implements Effect { values = new HashMap<>(); } } + if (value instanceof Player) { + // If Player are set as value, there might be PlayerImpl serialized in ClientMessage's GameView. + // That does cause the message's data to not be unzippable, since the PlayerImpl class are not + // client-side. + throw new IllegalArgumentException("Players should not be set as value, set the UUID instead."); + } values.put(key, value); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ClashEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ClashEffect.java index da9556cda7d..c4b522c60a8 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ClashEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ClashEffect.java @@ -146,6 +146,7 @@ public class ClashEffect extends OneShotEffect { if (cardOpponent != null) { opponent.moveCardToLibraryWithInfo(cardOpponent, source, game, Zone.LIBRARY, topOpponent, true); } + // fire CLASHED events with info about winner (flag is true if playerId won; other player is targetId) game.fireEvent(new GameEvent( GameEvent.EventType.CLASHED, opponent.getId(), source, @@ -157,7 +158,7 @@ public class ClashEffect extends OneShotEffect { )); // set opponent to DoIfClashWonEffect - source.getEffects().setValue("clashOpponent", opponent); + source.getEffects().setValue("clashOpponent", opponent.getId()); return cmcController > cmcOpponent; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DoIfClashWonEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DoIfClashWonEffect.java index aad0175d8df..cd7ad0f4cc5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DoIfClashWonEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DoIfClashWonEffect.java @@ -14,8 +14,9 @@ import mage.players.Player; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.UUID; + /** - * * @author LevelX2 */ @@ -31,7 +32,7 @@ public class DoIfClashWonEffect extends OneShotEffect { public DoIfClashWonEffect(Effect effect, boolean setTargetPointerToClashedOpponent, String chooseUseText) { super(Outcome.Benefit); this.executingEffect = effect; - this.chooseUseText = chooseUseText; + this.chooseUseText = chooseUseText; this.setTargetPointerToClashedOpponent = setTargetPointerToClashedOpponent; } @@ -52,21 +53,20 @@ public class DoIfClashWonEffect extends OneShotEffect { message = chooseUseText; message = CardUtil.replaceSourceName(message, mageObject.getLogName()); } - + if (chooseUseText == null || player.chooseUse(executingEffect.getOutcome(), message, source, game)) { if (new ClashEffect().apply(game, source)) { if (setTargetPointerToClashedOpponent) { - Object opponent = getValue("clashOpponent"); - if (opponent instanceof Player) { - executingEffect.setTargetPointer(new FixedTarget(((Player)opponent).getId())); - } + Player opponent = game.getPlayer((UUID) getValue("clashOpponent")); + if (opponent != null) { + executingEffect.setTargetPointer(new FixedTarget(opponent.getId())); + } } else { executingEffect.setTargetPointer(this.targetPointer); } if (executingEffect instanceof OneShotEffect) { return executingEffect.apply(game, source); - } - else { + } else { game.addEffect((ContinuousEffect) executingEffect, source); } }