Modify the way some second targets are chosen

If implemented the wrong way when you try to choose second targets the
game can get into an impossible state this fixes three such cards.
This commit is contained in:
Samuel Sandeen 2016-07-24 22:07:04 -04:00
parent d97d9ea130
commit 68e84d9c23
3 changed files with 82 additions and 72 deletions

View file

@ -33,6 +33,8 @@ import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.common.FightTargetsEffect;
import mage.cards.CardImpl;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AnotherTargetPredicate;
import mage.game.Game;
import mage.target.common.TargetCreaturePermanent;
@ -46,11 +48,18 @@ public class BloodFeud extends CardImpl {
super(ownerId, 83, "Blood Feud", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{4}{R}{R}");
this.expansionSetCode = "DKA";
// Target creature fights another target creature.
this.getSpellAbility().addEffect(new FightTargetsEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addTarget(new TargetOtherCreaturePermanent());
TargetCreaturePermanent target = new TargetCreaturePermanent();
target.setTargetTag(1);
this.getSpellAbility().addTarget(target);
FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature to fight");
filter.add(new AnotherTargetPredicate(2));
TargetCreaturePermanent target2 = new TargetCreaturePermanent(filter);
target2.setTargetTag(2);
this.getSpellAbility().addTarget(target2);
}
public BloodFeud(final BloodFeud card) {
@ -62,28 +71,3 @@ public class BloodFeud extends CardImpl {
return new BloodFeud(this);
}
}
class TargetOtherCreaturePermanent extends TargetCreaturePermanent {
public TargetOtherCreaturePermanent() {
super();
}
public TargetOtherCreaturePermanent(final TargetOtherCreaturePermanent target) {
super(target);
}
@Override
public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
if (source.getTargets().get(0).getTargets().contains(id)) {
return false;
}
return super.canTarget(controllerId, id, source, game);
}
@Override
public TargetOtherCreaturePermanent copy() {
return new TargetOtherCreaturePermanent(this);
}
}

View file

@ -29,6 +29,7 @@ package mage.sets.dissension;
import java.util.UUID;
import mage.MageInt;
import mage.MageItem;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -43,12 +44,16 @@ import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.common.FilterEnchantmentPermanent;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AnotherTargetPredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.filter.predicate.permanent.PermanentIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
@ -76,8 +81,18 @@ public class SimicGuildmage extends CardImpl {
// {1}{G}: Move a +1/+1 counter from target creature onto another target creature with the same controller.
Ability countersAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MoveCounterFromTargetToTargetEffect(), new ManaCostsImpl("{1}{G}"));
countersAbility.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (you take counters from)")));
countersAbility.addTarget(new SimicGuildmageSecondTargetCreaturePermanent());
TargetCreaturePermanent target = new TargetCreaturePermanent(
new FilterCreaturePermanent("creature (you take counter from)"));
target.setTargetTag(1);
countersAbility.addTarget(target);
FilterCreaturePermanent filter = new FilterCreaturePermanent(
"another target creature with the same controller (counter goes to)");
filter.add(new AnotherTargetPredicate(2));
filter.add(new SameControllerPredicate());
TargetCreaturePermanent target2 = new TargetCreaturePermanent(filter);
target2.setTargetTag(2);
countersAbility.addTarget(target2);
this.addAbility(countersAbility);
// {1}{U}: Attach target Aura enchanting a permanent to another permanent with the same controller.
Ability auraAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MoveAuraEffect(), new ManaCostsImpl("{1}{U}"));
@ -134,34 +149,31 @@ class MoveCounterFromTargetToTargetEffect extends OneShotEffect {
}
}
class SimicGuildmageSecondTargetCreaturePermanent extends TargetCreaturePermanent {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another target creature with the same controller (counters go to)");
SimicGuildmageSecondTargetCreaturePermanent() {
super(filter);
}
SimicGuildmageSecondTargetCreaturePermanent(final SimicGuildmageSecondTargetCreaturePermanent target) {
super(target);
}
class SameControllerPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<MageItem>> {
@Override
public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
Permanent firstPermanent = game.getPermanent(source.getTargets().getFirstTarget());
Permanent secondPermanent = game.getPermanent(id);
if (firstPermanent != null && secondPermanent != null) {
if (!firstPermanent.getId().equals(id) && firstPermanent.getControllerId().equals(secondPermanent.getControllerId())) {
return super.canTarget(controllerId, id, source, game);
public boolean apply(ObjectSourcePlayer<MageItem> input, Game game) {
StackObject source = game.getStack().getStackObject(input.getSourceId());
if (source != null) {
if (source.getStackAbility().getTargets().isEmpty()
|| source.getStackAbility().getTargets().get(0).getTargets().isEmpty()) {
return true;
}
Permanent firstTarget = game.getPermanent(
source.getStackAbility().getTargets().get(0).getTargets().get(0));
Permanent inputPermanent = game.getPermanent(input.getObject().getId());
if (firstTarget != null && inputPermanent != null) {
return firstTarget.getControllerId().equals(inputPermanent.getControllerId());
}
}
return false;
return true;
}
@Override
public SimicGuildmageSecondTargetCreaturePermanent copy() {
return new SimicGuildmageSecondTargetCreaturePermanent(this);
public String toString() {
return "Target with the same controller";
}
}
class MoveAuraEffect extends OneShotEffect {

View file

@ -28,6 +28,7 @@
package mage.sets.gatecrash;
import java.util.UUID;
import mage.MageItem;
import mage.constants.CardType;
import mage.constants.Rarity;
@ -37,9 +38,14 @@ import mage.cards.CardImpl;
import mage.constants.Outcome;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.filter.predicate.mageobject.AnotherTargetPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetCreaturePermanent;
/**
@ -54,8 +60,19 @@ public class Bioshift extends CardImpl {
// Move any number of +1/+1 counters from target creature onto another target creature with the same controller.
getSpellAbility().addEffect(new MoveCounterFromTargetToTargetEffect());
getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (you take counters from)")));
getSpellAbility().addTarget(new BioshiftSecondTargetCreaturePermanent());
TargetCreaturePermanent target = new TargetCreaturePermanent(
new FilterCreaturePermanent("creature (you take counters from)"));
target.setTargetTag(1);
this.getSpellAbility().addTarget(target);
FilterCreaturePermanent filter = new FilterCreaturePermanent(
"another target creature with the same controller (counters go to)");
filter.add(new AnotherTargetPredicate(2));
filter.add(new SameControllerPredicate());
TargetCreaturePermanent target2 = new TargetCreaturePermanent(filter);
target2.setTargetTag(2);
this.getSpellAbility().addTarget(target2);
}
@ -112,32 +129,29 @@ class MoveCounterFromTargetToTargetEffect extends OneShotEffect {
}
}
class BioshiftSecondTargetCreaturePermanent extends TargetCreaturePermanent {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another target creature with the same controller (counters go to)");
BioshiftSecondTargetCreaturePermanent() {
super(filter);
}
BioshiftSecondTargetCreaturePermanent(final BioshiftSecondTargetCreaturePermanent target) {
super(target);
}
class SameControllerPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<MageItem>> {
@Override
public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
Permanent firstPermanent = game.getPermanent(source.getTargets().getFirstTarget());
Permanent secondPermanent = game.getPermanent(id);
if (firstPermanent != null && secondPermanent != null) {
if (!firstPermanent.getId().equals(id) && firstPermanent.getControllerId().equals(secondPermanent.getControllerId())) {
return super.canTarget(controllerId, id, source, game);
public boolean apply(ObjectSourcePlayer<MageItem> input, Game game) {
StackObject source = game.getStack().getStackObject(input.getSourceId());
if (source != null) {
if (source.getStackAbility().getTargets().isEmpty()
|| source.getStackAbility().getTargets().get(0).getTargets().isEmpty()) {
return true;
}
Permanent firstTarget = game.getPermanent(
source.getStackAbility().getTargets().get(0).getTargets().get(0));
Permanent inputPermanent = game.getPermanent(input.getObject().getId());
if (firstTarget != null && inputPermanent != null) {
return firstTarget.getControllerId().equals(inputPermanent.getControllerId());
}
}
return false;
return true;
}
@Override
public BioshiftSecondTargetCreaturePermanent copy() {
return new BioshiftSecondTargetCreaturePermanent(this);
public String toString() {
return "Target with the same controller";
}
}