fixed Blatant Thievery test failure

This commit is contained in:
Evan Kranzler 2021-04-04 13:19:15 -04:00
parent 8699b847d8
commit 734bd6f118
4 changed files with 121 additions and 38 deletions

View file

@ -1,20 +1,29 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.targetadjustment.TargetAdjuster;
import mage.target.targetpointer.FixedTargets;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author emerald000
@ -25,8 +34,7 @@ public final class BlatantThievery extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}{U}{U}");
// For each opponent, gain control of target permanent that player controls.
this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfGame)
.setText("for each opponent, gain control of target permanent that player controls"));
this.getSpellAbility().addEffect(new BlatantThieveryEffect());
this.getSpellAbility().setTargetAdjuster(BlatantThieveryAdjuster.instance);
}
@ -61,3 +69,35 @@ enum BlatantThieveryAdjuster implements TargetAdjuster {
}
}
}
class BlatantThieveryEffect extends OneShotEffect {
BlatantThieveryEffect() {
super(Outcome.Benefit);
staticText = "for each opponent, gain control of target permanent that player controls";
}
private BlatantThieveryEffect(final BlatantThieveryEffect effect) {
super(effect);
}
@Override
public BlatantThieveryEffect copy() {
return new BlatantThieveryEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
List<Permanent> permanents = source
.getTargets()
.stream()
.map(Target::getTargets)
.flatMap(Collection::stream)
.map(game::getPermanent)
.filter(Objects::nonNull)
.collect(Collectors.toList());
game.addEffect(new GainControlTargetEffect(Duration.Custom, true)
.setTargetPointer(new FixedTargets(permanents, game)), source);
return true;
}
}

View file

@ -1,22 +1,31 @@
package mage.cards.t;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.targetadjustment.TargetAdjuster;
import mage.target.targetpointer.FixedTargets;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author TheElk801
@ -27,10 +36,7 @@ public final class TemptedByTheOriq extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}{U}{U}");
// For each opponent, gain control of up to one target creature or planeswalker that player controls with mana value 3 or less.
this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfGame).setText(
"for each opponent, gain control of up to one target creature or planeswalker " +
"that player controls with mana value 3 or less"
));
this.getSpellAbility().addEffect(new TemptedByTheOriqEffect());
this.getSpellAbility().setTargetAdjuster(TemptedByTheOriqAdjuster.instance);
}
@ -64,3 +70,36 @@ enum TemptedByTheOriqAdjuster implements TargetAdjuster {
}
}
}
class TemptedByTheOriqEffect extends OneShotEffect {
TemptedByTheOriqEffect() {
super(Outcome.Benefit);
staticText = "for each opponent, gain control of up to one target creature " +
"or planeswalker that player controls with mana value 3 or less";
}
private TemptedByTheOriqEffect(final TemptedByTheOriqEffect effect) {
super(effect);
}
@Override
public TemptedByTheOriqEffect copy() {
return new TemptedByTheOriqEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
List<Permanent> permanents = source
.getTargets()
.stream()
.map(Target::getTargets)
.flatMap(Collection::stream)
.map(game::getPermanent)
.filter(Objects::nonNull)
.collect(Collectors.toList());
game.addEffect(new GainControlTargetEffect(Duration.Custom, true)
.setTargetPointer(new FixedTargets(permanents, game)), source);
return true;
}
}

View file

@ -45,8 +45,10 @@ public class BlatantThieveryTest extends CardTestMultiPlayerBase {
addTarget(playerA, "Walking Corpse");
addTarget(playerA, "Pillarfield Ox");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Blatant Thievery", 1);
assertPermanentCount(playerA, "Silvercoat Lion", 1);
@ -79,6 +81,7 @@ public class BlatantThieveryTest extends CardTestMultiPlayerBase {
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Blatant Thievery", 1);
assertGraveyardCount(playerB, "Act of Aggression", 1);

View file

@ -9,7 +9,6 @@ import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
@ -76,42 +75,44 @@ public class GainControlTargetEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
boolean oneTargetStillExists = false;
for (UUID permanentId : getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(permanentId);
if (permanent != null) {
oneTargetStillExists = true;
if (!permanent.isControlledBy(controllingPlayerId)) {
boolean controlChanged = false;
if (controllingPlayerId != null) {
if (permanent.changeControllerId(controllingPlayerId, game, source)) {
controlChanged = true;
}
} else {
if (permanent.changeControllerId(source.getControllerId(), game, source)) {
controlChanged = true;
}
}
if (source instanceof ActivatedAbility
&& firstControlChange && !controlChanged) {
// If it was not possible to get control of target permanent by the activated ability the first time it took place
// the effect failed (e.g. because of Guardian Beast) and must be discarded
// This does not handle correctly multiple targets at once
discard();
}
}
if (controller == null) {
discard(); // controller no longer exists
return false;
}
boolean oneTargetStillExists = false;
for (UUID permanentId : getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(permanentId);
if (permanent == null) {
continue;
}
oneTargetStillExists = true;
if (permanent.isControlledBy(controllingPlayerId)) {
continue;
}
boolean controlChanged = false;
if (controllingPlayerId != null) {
if (permanent.changeControllerId(controllingPlayerId, game, source)) {
controlChanged = true;
}
} else {
if (permanent.changeControllerId(source.getControllerId(), game, source)) {
controlChanged = true;
}
}
// no valid target exists and the controller is no longer in the game, effect can be discarded
if (!oneTargetStillExists || !controller.isInGame()) {
if (source instanceof ActivatedAbility
&& firstControlChange && !controlChanged) {
// If it was not possible to get control of target permanent by the activated ability the first time it took place
// the effect failed (e.g. because of Guardian Beast) and must be discarded
// This does not handle correctly multiple targets at once
discard();
}
firstControlChange = false;
return true;
}
discard(); // controller no longer exists
return false;
// no valid target exists and the controller is no longer in the game, effect can be discarded
if (!oneTargetStillExists || !controller.isInGame()) {
discard();
}
firstControlChange = false;
return true;
}
@Override