mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
Rework Infectious Rage (#10625)
* put custom predicate back with Aura Graft * Rework Infectious Rage and add unit test * cleanup Aura Graft
This commit is contained in:
parent
d11269cb56
commit
e2cff095b3
4 changed files with 109 additions and 85 deletions
|
|
@ -1,9 +1,7 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -12,35 +10,37 @@ import mage.constants.CardType;
|
|||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.Filter;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||
import mage.filter.predicate.permanent.PermanentCanBeAttachedToPredicate;
|
||||
import mage.filter.predicate.permanent.CanBeEnchantedByPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.util.TargetAddress;
|
||||
|
||||
/**
|
||||
* @author duncant
|
||||
*/
|
||||
public final class AuraGraft extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent("Aura that's attached to a permanent");
|
||||
static {
|
||||
filter.add(SubType.AURA.getPredicate());
|
||||
filter.add(AuraGraftAttachedToPermanentPredicate.instance);
|
||||
}
|
||||
|
||||
public AuraGraft(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
|
||||
|
||||
// Gain control of target Aura that's attached to a permanent. Attach it to another permanent it can enchant.
|
||||
FilterPermanent filter = new FilterPermanent("Aura that's attached to a permanent");
|
||||
filter.add(SubType.AURA.getPredicate());
|
||||
filter.add(new AttachedToPermanentPredicate());
|
||||
this.getSpellAbility().addTarget(new TargetPermanent(filter));
|
||||
|
||||
Effect gainControlEffect = new GainControlTargetEffect(Duration.EndOfGame);
|
||||
this.getSpellAbility().addEffect(gainControlEffect);
|
||||
|
||||
this.getSpellAbility().addEffect(new MoveTargetAuraEffect());
|
||||
this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfGame));
|
||||
this.getSpellAbility().addEffect(new AuraGraftMoveAuraEffect());
|
||||
}
|
||||
|
||||
private AuraGraft(final AuraGraft card) {
|
||||
|
|
@ -53,11 +53,8 @@ public final class AuraGraft extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class AttachedToPermanentPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
|
||||
public AttachedToPermanentPredicate() {
|
||||
super();
|
||||
}
|
||||
enum AuraGraftAttachedToPermanentPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
instance;
|
||||
|
||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
Permanent attached = input.getObject();
|
||||
|
|
@ -65,49 +62,68 @@ class AttachedToPermanentPredicate implements ObjectSourcePlayerPredicate<Perman
|
|||
}
|
||||
}
|
||||
|
||||
class MoveTargetAuraEffect extends OneShotEffect {
|
||||
class AuraGraftAuraCanEnchantPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
|
||||
public MoveTargetAuraEffect() {
|
||||
protected Permanent aura;
|
||||
|
||||
AuraGraftAuraCanEnchantPredicate(Permanent aura) {
|
||||
super();
|
||||
this.aura = aura;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
Permanent potentialAttachment = input.getObject();
|
||||
for (TargetAddress addr : TargetAddress.walk(aura)) {
|
||||
Target target = addr.getTarget(aura);
|
||||
Filter filter = target.getFilter();
|
||||
return filter.match(potentialAttachment, game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class AuraGraftMoveAuraEffect extends OneShotEffect {
|
||||
|
||||
AuraGraftMoveAuraEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "Attach it to another permanent it can enchant";
|
||||
}
|
||||
|
||||
public MoveTargetAuraEffect(final MoveTargetAuraEffect effect) {
|
||||
private AuraGraftMoveAuraEffect(final AuraGraftMoveAuraEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MoveTargetAuraEffect copy() {
|
||||
return new MoveTargetAuraEffect(this);
|
||||
public AuraGraftMoveAuraEffect copy() {
|
||||
return new AuraGraftMoveAuraEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent enchantment = game.getPermanent(targetPointer.getFirst(game, source));
|
||||
if (enchantment == null) {
|
||||
return false;
|
||||
}
|
||||
Permanent oldAttachment = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (oldAttachment == null) {
|
||||
return false;
|
||||
}
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
if (enchantment == null || controller == null) {
|
||||
return false;
|
||||
}
|
||||
Permanent previouslyEnchanted = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (previouslyEnchanted == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FilterPermanent filter = new FilterPermanent("another permanent " + enchantment.getLogName() + " can enchant");
|
||||
filter.add(AnotherPredicate.instance);
|
||||
filter.add(new PermanentCanBeAttachedToPredicate(enchantment));
|
||||
filter.add(new AuraGraftAuraCanEnchantPredicate(enchantment)); // extracts Targets from Aura spell ability
|
||||
filter.add(new CanBeEnchantedByPredicate(enchantment)); // checks for protection
|
||||
Target target = new TargetPermanent(filter);
|
||||
target.setNotTarget(true);
|
||||
if (target.canChoose(controller.getId(), source, game)
|
||||
&& controller.choose(outcome, target, source, game)) {
|
||||
Permanent newAttachment = game.getPermanent(target.getFirstTarget());
|
||||
if (newAttachment != null
|
||||
&& oldAttachment.removeAttachment(enchantment.getId(), source, game)) {
|
||||
&& previouslyEnchanted.removeAttachment(enchantment.getId(), source, game)) {
|
||||
newAttachment.addAttachment(enchantment.getId(), source, game);
|
||||
game.informPlayers(enchantment.getLogName() + " was unattached from " + oldAttachment.getLogName() + " and attached to " + newAttachment.getLogName());
|
||||
game.informPlayers(enchantment.getLogName() + " was unattached from " + previouslyEnchanted.getLogName() + " and attached to " + newAttachment.getLogName());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import mage.cards.Card;
|
|||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.permanent.PermanentCanBeAttachedToPredicate;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.CanBeEnchantedByPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
|
@ -80,32 +80,28 @@ class InfectiousRageReattachEffect extends OneShotEffect {
|
|||
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Card auraCard = game.getCard(source.getSourceId());
|
||||
Permanent auraPermanent = source.getSourcePermanentOrLKI(game);
|
||||
if (controller == null || auraCard == null || auraPermanent == null) {
|
||||
if (controller == null || auraCard == null) {
|
||||
return false;
|
||||
}
|
||||
if (source.getSourceObjectZoneChangeCounter() != auraCard.getZoneChangeCounter(game)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FilterPermanent filter = new FilterPermanent();
|
||||
filter.add(CardType.CREATURE.getPredicate());
|
||||
filter.add(new PermanentCanBeAttachedToPredicate(auraPermanent)); // Doesn't yet exclude creatures with protection abilities
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
filter.add(new CanBeEnchantedByPredicate(auraCard));
|
||||
List<Permanent> permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game);
|
||||
|
||||
if (!permanents.isEmpty()) {
|
||||
Permanent creature = RandomUtil.randomFromCollection(permanents);
|
||||
if (creature != null) {
|
||||
game.getState().setValue("attachTo:" + auraCard.getId(), creature);
|
||||
controller.moveCards(auraCard, Zone.BATTLEFIELD, source, game);
|
||||
return creature.addAttachment(auraCard.getId(), source, game);
|
||||
}
|
||||
if (permanents.isEmpty()) {
|
||||
game.informPlayers("No valid creatures for " + auraCard.getLogName() + "to enchant.");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
game.informPlayers("No valid creatures for " + auraPermanent.getLogName() + "to enchant.");
|
||||
Permanent creature = RandomUtil.randomFromCollection(permanents);
|
||||
if (creature == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
game.getState().setValue("attachTo:" + auraCard.getId(), creature);
|
||||
controller.moveCards(auraCard, Zone.BATTLEFIELD, source, game);
|
||||
return creature.addAttachment(auraCard.getId(), source, game);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
package org.mage.test.cards.enchantments;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author xenohedron
|
||||
*/
|
||||
public class AuraAttachTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testInfectiousRage() {
|
||||
/*
|
||||
* Infectious Rage {1}{R}
|
||||
* Enchant creature
|
||||
* Enchanted creature gets +2/-1.
|
||||
* When enchanted creature dies, choose a creature at random Infectious Rage can enchant.
|
||||
* Return Infectious Rage to the battlefield attached to that creature.
|
||||
*/
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Pensive Minotaur", 1); // 2/3 (vanilla)
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Slippery Bogle", 1); // 1/1 hexproof
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Thermal Glider", 1); // 2/1 flying, protection from red
|
||||
addCard(Zone.HAND, playerA, "Infectious Rage", 1);
|
||||
addCard(Zone.HAND, playerA, "Shock", 1);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Infectious Rage", "Pensive Minotaur");
|
||||
// Minotaur is now a 4/2
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shock", "Pensive Minotaur");
|
||||
// Minotaur dies. Infectious Rage triggers, only legal creature to enchant is Slippery Bogle
|
||||
// Bogle dies. // Infectious Rage triggers, Thermal Glider can't be enchanted by it, so it remains in graveyard
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Pensive Minotaur", 1);
|
||||
assertGraveyardCount(playerA, "Infectious Rage", 1);
|
||||
assertGraveyardCount(playerA, "Shock", 1);
|
||||
assertGraveyardCount(playerB, "Slippery Bogle", 1);
|
||||
assertPermanentCount(playerB, "Thermal Glider", 1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package mage.filter.predicate.permanent;
|
||||
|
||||
import mage.filter.Filter;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.Target;
|
||||
import mage.util.TargetAddress;
|
||||
|
||||
/**
|
||||
* @author duncant
|
||||
*/
|
||||
|
||||
public class PermanentCanBeAttachedToPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
|
||||
protected Permanent aura;
|
||||
|
||||
public PermanentCanBeAttachedToPredicate(Permanent aura) {
|
||||
super();
|
||||
this.aura = aura;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
// TODO: Is it possible to add functionality to exclude objects the aura can't enchant (e.g. protection from)?
|
||||
Permanent potentialAttachment = input.getObject();
|
||||
for (TargetAddress addr : TargetAddress.walk(aura)) {
|
||||
Target target = addr.getTarget(aura);
|
||||
Filter filter = target.getFilter();
|
||||
return filter.match(potentialAttachment, game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue