mirror of
https://github.com/correl/mage.git
synced 2025-04-01 09:05:59 -09:00
Fixed handling of DontUntapInControllersNextUntapStepTargetEffect (fixes Sleep bug).
This commit is contained in:
parent
c85cc9cb98
commit
272f68b530
11 changed files with 169 additions and 171 deletions
Mage.Sets/src/mage/sets
battleforzendikar
commander
commander2014
darkascension
invasion
magic2010
portalthreekingdoms
theros
zendikar
Mage.Tests/src/test/java/org/mage/test/combat
Mage/src/main/java/mage/abilities/effects/common
|
@ -152,12 +152,10 @@ class GuardianOfTazeemEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent land = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
|
Permanent land = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
|
||||||
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
|
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
|
||||||
if (land != null && targetCreature != null) {
|
if (land != null && targetCreature != null && land.hasSubtype("Island")) {
|
||||||
if (land.hasSubtype("Island")) {
|
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("that creature");
|
||||||
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("that creature");
|
effect.setTargetPointer(new FixedTarget(targetCreature, game));
|
||||||
effect.setTargetPointer(new FixedTarget(targetCreature, game));
|
game.addEffect(effect, source);
|
||||||
game.addEffect(effect, source);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,15 @@
|
||||||
*/
|
*/
|
||||||
package mage.sets.commander;
|
package mage.sets.commander;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.DoIfClashWonEffect;
|
import mage.abilities.effects.common.DoIfClashWonEffect;
|
||||||
import mage.abilities.effects.common.PreventAllDamageByAllEffect;
|
|
||||||
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
||||||
|
import mage.abilities.effects.common.PreventAllDamageByAllEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
|
@ -43,7 +45,7 @@ import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTargets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -55,7 +57,6 @@ public class PollenLullaby extends CardImpl {
|
||||||
super(ownerId, 26, "Pollen Lullaby", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{W}");
|
super(ownerId, 26, "Pollen Lullaby", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{W}");
|
||||||
this.expansionSetCode = "CMD";
|
this.expansionSetCode = "CMD";
|
||||||
|
|
||||||
|
|
||||||
// Prevent all combat damage that would be dealt this turn. Clash with an opponent. If you win, creatures that player controls don't untap during the player's next untap step.
|
// Prevent all combat damage that would be dealt this turn. Clash with an opponent. If you win, creatures that player controls don't untap during the player's next untap step.
|
||||||
this.getSpellAbility().addEffect(new PreventAllDamageByAllEffect(Duration.EndOfTurn, true));
|
this.getSpellAbility().addEffect(new PreventAllDamageByAllEffect(Duration.EndOfTurn, true));
|
||||||
this.getSpellAbility().addEffect(new DoIfClashWonEffect(new PollenLullabyEffect(), true, null));
|
this.getSpellAbility().addEffect(new DoIfClashWonEffect(new PollenLullabyEffect(), true, null));
|
||||||
|
@ -86,10 +87,13 @@ class PollenLullabyEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
for (Permanent creature: game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), player.getId(), game)) {
|
List<Permanent> doNotUntapNextUntapStep = new ArrayList<>();
|
||||||
creature.tap(game);
|
for (Permanent creature : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), player.getId(), game)) {
|
||||||
|
doNotUntapNextUntapStep.add(creature);
|
||||||
|
}
|
||||||
|
if (!doNotUntapNextUntapStep.isEmpty()) {
|
||||||
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("This creature");
|
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("This creature");
|
||||||
effect.setTargetPointer(new FixedTarget(creature.getId()));
|
effect.setTargetPointer(new FixedTargets(doNotUntapNextUntapStep, game));
|
||||||
game.addEffect(effect, source);
|
game.addEffect(effect, source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -103,4 +107,3 @@ class PollenLullabyEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
*/
|
*/
|
||||||
package mage.sets.commander2014;
|
package mage.sets.commander2014;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.ObjectColor;
|
import mage.ObjectColor;
|
||||||
|
@ -46,7 +48,7 @@ import mage.filter.predicate.Predicates;
|
||||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTargets;
|
||||||
import mage.watchers.common.CastFromHandWatcher;
|
import mage.watchers.common.CastFromHandWatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,10 +107,14 @@ class BreachingLeviathanEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
|
List<Permanent> doNotUntapNextUntapStep = new ArrayList<>();
|
||||||
for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
|
for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
|
||||||
creature.tap(game);
|
creature.tap(game);
|
||||||
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect();
|
doNotUntapNextUntapStep.add(creature);
|
||||||
effect.setTargetPointer(new FixedTarget(creature.getId()));
|
}
|
||||||
|
if (!doNotUntapNextUntapStep.isEmpty()) {
|
||||||
|
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("This creature");
|
||||||
|
effect.setTargetPointer(new FixedTargets(doNotUntapNextUntapStep, game));
|
||||||
game.addEffect(effect, source);
|
game.addEffect(effect, source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -27,27 +27,25 @@
|
||||||
*/
|
*/
|
||||||
package mage.sets.darkascension;
|
package mage.sets.darkascension;
|
||||||
|
|
||||||
import mage.constants.CardType;
|
import java.util.ArrayList;
|
||||||
import mage.constants.Rarity;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.condition.common.FatefulHourCondition;
|
import mage.abilities.condition.common.FatefulHourCondition;
|
||||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||||
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.ReplacementEffectImpl;
|
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
||||||
import mage.abilities.effects.common.PreventAllDamageByAllEffect;
|
import mage.abilities.effects.common.PreventAllDamageByAllEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.PhaseStep;
|
import mage.constants.Rarity;
|
||||||
import mage.filter.common.FilterAttackingCreature;
|
import mage.filter.common.FilterAttackingCreature;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.target.targetpointer.FixedTargets;
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
|
||||||
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
|
||||||
import mage.target.targetpointer.FixedTarget;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -59,7 +57,6 @@ public class ClingingMists extends CardImpl {
|
||||||
super(ownerId, 109, "Clinging Mists", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{G}");
|
super(ownerId, 109, "Clinging Mists", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{G}");
|
||||||
this.expansionSetCode = "DKA";
|
this.expansionSetCode = "DKA";
|
||||||
|
|
||||||
|
|
||||||
// Prevent all combat damage that would be dealt this turn.
|
// Prevent all combat damage that would be dealt this turn.
|
||||||
this.getSpellAbility().addEffect(new PreventAllDamageByAllEffect(null, Duration.EndOfTurn, true));
|
this.getSpellAbility().addEffect(new PreventAllDamageByAllEffect(null, Duration.EndOfTurn, true));
|
||||||
|
|
||||||
|
@ -94,11 +91,15 @@ class ClingingMistsEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
for (Permanent creature: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
|
List<Permanent> doNotUntapNextUntapStep = new ArrayList<>();
|
||||||
|
for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
|
||||||
creature.tap(game);
|
creature.tap(game);
|
||||||
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect();
|
doNotUntapNextUntapStep.add(creature);
|
||||||
effect.setTargetPointer(new FixedTarget(creature.getId()));
|
}
|
||||||
game.addEffect(effect, source);
|
if (!doNotUntapNextUntapStep.isEmpty()) {
|
||||||
|
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("This creature");
|
||||||
|
effect.setTargetPointer(new FixedTargets(doNotUntapNextUntapStep, game));
|
||||||
|
game.addEffect(effect, source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,14 @@
|
||||||
*/
|
*/
|
||||||
package mage.sets.invasion;
|
package mage.sets.invasion;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.PreventAllDamageByAllEffect;
|
|
||||||
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
||||||
|
import mage.abilities.effects.common.PreventAllDamageByAllEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
|
@ -43,7 +45,7 @@ import mage.filter.predicate.permanent.AttackingPredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTargets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -55,7 +57,6 @@ public class Tangle extends CardImpl {
|
||||||
super(ownerId, 213, "Tangle", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{G}");
|
super(ownerId, 213, "Tangle", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{G}");
|
||||||
this.expansionSetCode = "INV";
|
this.expansionSetCode = "INV";
|
||||||
|
|
||||||
|
|
||||||
// Prevent all combat damage that would be dealt this turn.
|
// Prevent all combat damage that would be dealt this turn.
|
||||||
this.getSpellAbility().addEffect(new PreventAllDamageByAllEffect(Duration.EndOfTurn, true));
|
this.getSpellAbility().addEffect(new PreventAllDamageByAllEffect(Duration.EndOfTurn, true));
|
||||||
// Each attacking creature doesn't untap during its controller's next untap step.
|
// Each attacking creature doesn't untap during its controller's next untap step.
|
||||||
|
@ -99,9 +100,13 @@ class TangleEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
for (Permanent permanent :game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
|
List<Permanent> doNotUntapNextUntapStep = new ArrayList<>();
|
||||||
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect();
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
|
||||||
effect.setTargetPointer(new FixedTarget(permanent.getId()));
|
doNotUntapNextUntapStep.add(permanent);
|
||||||
|
}
|
||||||
|
if (!doNotUntapNextUntapStep.isEmpty()) {
|
||||||
|
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("This creature");
|
||||||
|
effect.setTargetPointer(new FixedTargets(doNotUntapNextUntapStep, game));
|
||||||
game.addEffect(effect, source);
|
game.addEffect(effect, source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
* permitted provided that the following conditions are met:
|
* permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
* conditions and the following disclaimer.
|
* conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
* provided with the distribution.
|
* provided with the distribution.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
@ -20,29 +20,30 @@
|
||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* The views and conclusions contained in the software and documentation are those of the
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
* authors and should not be interpreted as representing official policies, either expressed
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
* or implied, of BetaSteward_at_googlemail.com.
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package mage.sets.magic2010;
|
package mage.sets.magic2010;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.constants.CardType;
|
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.Rarity;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.TargetPlayer;
|
import mage.target.TargetPlayer;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTargets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -83,11 +84,16 @@ class SleepEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getFirstTarget());
|
Player player = game.getPlayer(source.getFirstTarget());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
for (Permanent creature: game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), player.getId(), game)) {
|
List<Permanent> doNotUntapNextUntapStep = new ArrayList<>();
|
||||||
|
for (Permanent creature : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), player.getId(), game)) {
|
||||||
creature.tap(game);
|
creature.tap(game);
|
||||||
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect();
|
doNotUntapNextUntapStep.add(creature);
|
||||||
effect.setTargetPointer(new FixedTarget(creature.getId()));
|
}
|
||||||
game.addEffect(effect, source);
|
if (!doNotUntapNextUntapStep.isEmpty()) {
|
||||||
|
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("", player.getId());
|
||||||
|
effect.setText("those creatures don't untap during that player's next untap step");
|
||||||
|
effect.setTargetPointer(new FixedTargets(doNotUntapNextUntapStep, game));
|
||||||
|
game.addEffect(effect, source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
*/
|
*/
|
||||||
package mage.sets.portalthreekingdoms;
|
package mage.sets.portalthreekingdoms;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
|
@ -43,7 +45,7 @@ import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetOpponent;
|
import mage.target.common.TargetOpponent;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTargets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -55,7 +57,6 @@ public class Exhaustion extends CardImpl {
|
||||||
super(ownerId, 42, "Exhaustion", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{U}");
|
super(ownerId, 42, "Exhaustion", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{U}");
|
||||||
this.expansionSetCode = "PTK";
|
this.expansionSetCode = "PTK";
|
||||||
|
|
||||||
|
|
||||||
// Creatures and lands target opponent controls don't untap during his or her next untap step.
|
// Creatures and lands target opponent controls don't untap during his or her next untap step.
|
||||||
this.getSpellAbility().addEffect(new ExhaustionEffect());
|
this.getSpellAbility().addEffect(new ExhaustionEffect());
|
||||||
this.getSpellAbility().addTarget(new TargetOpponent());
|
this.getSpellAbility().addTarget(new TargetOpponent());
|
||||||
|
@ -72,35 +73,39 @@ public class Exhaustion extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExhaustionEffect extends OneShotEffect {
|
class ExhaustionEffect extends OneShotEffect {
|
||||||
|
|
||||||
private static final FilterPermanent filter = new FilterPermanent();
|
private static final FilterPermanent filter = new FilterPermanent();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(Predicates.or(new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.LAND)));
|
filter.add(Predicates.or(new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.LAND)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ExhaustionEffect() {
|
ExhaustionEffect() {
|
||||||
super(Outcome.Detriment);
|
super(Outcome.Detriment);
|
||||||
this.staticText = "Creatures and lands target opponent controls don't untap during his or her next untap step.";
|
this.staticText = "Creatures and lands target opponent controls don't untap during his or her next untap step.";
|
||||||
}
|
}
|
||||||
|
|
||||||
ExhaustionEffect(final ExhaustionEffect effect) {
|
ExhaustionEffect(final ExhaustionEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExhaustionEffect copy() {
|
public ExhaustionEffect copy() {
|
||||||
return new ExhaustionEffect(this);
|
return new ExhaustionEffect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getFirstTarget());
|
Player player = game.getPlayer(source.getFirstTarget());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
|
List<Permanent> doNotUntapNextUntapStep = new ArrayList<>();
|
||||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, player.getId(), game)) {
|
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, player.getId(), game)) {
|
||||||
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect();
|
doNotUntapNextUntapStep.add(permanent);
|
||||||
effect.setTargetPointer(new FixedTarget(permanent.getId()));
|
}
|
||||||
game.addEffect(effect, source);
|
if (!doNotUntapNextUntapStep.isEmpty()) {
|
||||||
|
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("This creature");
|
||||||
|
effect.setTargetPointer(new FixedTargets(doNotUntapNextUntapStep, game));
|
||||||
|
game.addEffect(effect, source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,10 @@
|
||||||
*/
|
*/
|
||||||
package mage.sets.theros;
|
package mage.sets.theros;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -52,7 +54,7 @@ import mage.game.events.GameEvent;
|
||||||
import mage.game.events.GameEvent.EventType;
|
import mage.game.events.GameEvent.EventType;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTargets;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
|
@ -69,7 +71,7 @@ public class TritonTactics extends CardImpl {
|
||||||
// Up to two target creatures each get +0/+3 until end of turn. Untap those creatures.
|
// Up to two target creatures each get +0/+3 until end of turn. Untap those creatures.
|
||||||
// At this turn's next end of combat, tap each creature that was blocked by one of those
|
// At this turn's next end of combat, tap each creature that was blocked by one of those
|
||||||
// creatures this turn and it doesn't untap during its controller's next untap step.
|
// creatures this turn and it doesn't untap during its controller's next untap step.
|
||||||
Effect effect = new BoostTargetEffect(0,3, Duration.EndOfTurn);
|
Effect effect = new BoostTargetEffect(0, 3, Duration.EndOfTurn);
|
||||||
effect.setText("Up to two target creatures each get +0/+3 until end of turn");
|
effect.setText("Up to two target creatures each get +0/+3 until end of turn");
|
||||||
this.getSpellAbility().addEffect(effect);
|
this.getSpellAbility().addEffect(effect);
|
||||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2));
|
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2));
|
||||||
|
@ -78,7 +80,6 @@ public class TritonTactics extends CardImpl {
|
||||||
|
|
||||||
this.getSpellAbility().addWatcher(new BlockedCreaturesWatcher());
|
this.getSpellAbility().addWatcher(new BlockedCreaturesWatcher());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TritonTactics(final TritonTactics card) {
|
public TritonTactics(final TritonTactics card) {
|
||||||
|
@ -110,7 +111,7 @@ class TritonTacticsUntapTargetEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Set<String> targets = new HashSet<>();
|
Set<String> targets = new HashSet<>();
|
||||||
for (UUID target: targetPointer.getTargets(game, source)) {
|
for (UUID target : targetPointer.getTargets(game, source)) {
|
||||||
Permanent permanent = game.getPermanent(target);
|
Permanent permanent = game.getPermanent(target);
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
permanent.untap(game);
|
permanent.untap(game);
|
||||||
|
@ -189,17 +190,21 @@ class TritonTacticsEndOfCombatEffect extends OneShotEffect {
|
||||||
Object object = game.getState().getValue("blockedAttackers" + source.getSourceId());
|
Object object = game.getState().getValue("blockedAttackers" + source.getSourceId());
|
||||||
if (object != null && object instanceof Map) {
|
if (object != null && object instanceof Map) {
|
||||||
attackerMap = (Map<Integer, Set<String>>) object;
|
attackerMap = (Map<Integer, Set<String>>) object;
|
||||||
for (Set<String> attackerSet :attackerMap.values()) {
|
for (Set<String> attackerSet : attackerMap.values()) {
|
||||||
|
List<Permanent> doNotUntapNextUntapStep = new ArrayList<>();
|
||||||
for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) {
|
for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) {
|
||||||
if (attackerSet.contains(CardUtil.getCardZoneString(null, creature.getId(), game))) {
|
if (attackerSet.contains(CardUtil.getCardZoneString(null, creature.getId(), game))) {
|
||||||
// tap creature and add the not untap effect
|
// tap creature and add the not untap effect
|
||||||
creature.tap(game);
|
creature.tap(game);
|
||||||
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect();
|
doNotUntapNextUntapStep.add(creature);
|
||||||
effect.setTargetPointer(new FixedTarget(creature.getId()));
|
|
||||||
game.addEffect(effect, source);
|
|
||||||
game.informPlayers(new StringBuilder("Triton Tactics: ").append(creature.getName()).append(" doesn't untap during its controller's next untap step").toString());
|
game.informPlayers(new StringBuilder("Triton Tactics: ").append(creature.getName()).append(" doesn't untap during its controller's next untap step").toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!doNotUntapNextUntapStep.isEmpty()) {
|
||||||
|
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("This creature");
|
||||||
|
effect.setTargetPointer(new FixedTargets(doNotUntapNextUntapStep, game));
|
||||||
|
game.addEffect(effect, source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (attackerMap != null) {
|
if (attackerMap != null) {
|
||||||
|
|
|
@ -28,25 +28,18 @@
|
||||||
package mage.sets.zendikar;
|
package mage.sets.zendikar;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.DoIfCostPaid;
|
||||||
|
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
||||||
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Rarity;
|
import mage.constants.Rarity;
|
||||||
import mage.MageInt;
|
|
||||||
import mage.abilities.Ability;
|
|
||||||
import mage.abilities.common.AttacksTriggeredAbility;
|
|
||||||
import mage.abilities.costs.Cost;
|
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
|
||||||
import mage.abilities.effects.OneShotEffect;
|
|
||||||
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
|
||||||
import mage.cards.CardImpl;
|
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.players.Player;
|
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -66,7 +59,11 @@ public class LorthosTheTidemaker extends CardImpl {
|
||||||
this.toughness = new MageInt(8);
|
this.toughness = new MageInt(8);
|
||||||
|
|
||||||
// Whenever Lorthos, the Tidemaker attacks, you may pay {8}. If you do, tap up to eight target permanents. Those permanents don't untap during their controllers' next untap steps.
|
// Whenever Lorthos, the Tidemaker attacks, you may pay {8}. If you do, tap up to eight target permanents. Those permanents don't untap during their controllers' next untap steps.
|
||||||
AttacksTriggeredAbility ability = new AttacksTriggeredAbility(new LorthosTheTideMakerEffect(), true);
|
DoIfCostPaid effect = new DoIfCostPaid(new TapTargetEffect(), new GenericManaCost(8), "Pay {8} to tap up to 8 target permanents? (They don't untap during their controllers' next untap steps)");
|
||||||
|
AttacksTriggeredAbility ability = new AttacksTriggeredAbility(effect, false);
|
||||||
|
Effect effect2 = new DontUntapInControllersNextUntapStepTargetEffect();
|
||||||
|
effect2.setText("Those permanents don't untap during their controllers' next untap steps");
|
||||||
|
effect.addEffect(effect2);
|
||||||
ability.addTarget(new TargetPermanent(0, 8, filter, false));
|
ability.addTarget(new TargetPermanent(0, 8, filter, false));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
@ -80,44 +77,3 @@ public class LorthosTheTidemaker extends CardImpl {
|
||||||
return new LorthosTheTidemaker(this);
|
return new LorthosTheTidemaker(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LorthosTheTideMakerEffect extends OneShotEffect {
|
|
||||||
|
|
||||||
public LorthosTheTideMakerEffect() {
|
|
||||||
super(Outcome.Tap);
|
|
||||||
this.staticText = "you may pay {8}. If you do, tap up to eight target permanents. Those permanents don't untap during their controllers' next untap steps";
|
|
||||||
}
|
|
||||||
|
|
||||||
public LorthosTheTideMakerEffect(final LorthosTheTideMakerEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LorthosTheTideMakerEffect copy() {
|
|
||||||
return new LorthosTheTideMakerEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
|
||||||
if (player != null) {
|
|
||||||
Cost cost = new ManaCostsImpl("{8}");
|
|
||||||
if (player.chooseUse(Outcome.Tap, "Pay " + cost.getText() + " and " + staticText, source, game)) {
|
|
||||||
cost.clearPaid();
|
|
||||||
if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false, null)) {
|
|
||||||
for (UUID target : this.targetPointer.getTargets(game, source)) {
|
|
||||||
Permanent permanent = game.getPermanent(target);
|
|
||||||
if (permanent != null) {
|
|
||||||
permanent.tap(game);
|
|
||||||
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect();
|
|
||||||
effect.setTargetPointer(new FixedTarget(permanent.getId()));
|
|
||||||
game.addEffect(effect, source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.mage.test.combat;
|
package org.mage.test.combat;
|
||||||
|
|
||||||
|
|
||||||
import mage.constants.PhaseStep;
|
import mage.constants.PhaseStep;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
|
@ -35,11 +34,13 @@ public class AttackBlockRestrictionsTest extends CardTestPlayerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests attacking creature doesn't untap after being blocked by Wall of Frost
|
* Tests attacking creature doesn't untap after being blocked by Wall of
|
||||||
|
* Frost
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testWallofWrost() {
|
public void testWallofWrost() {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Wall of Frost");
|
// Whenever Wall of Frost blocks a creature, that creature doesn't untap during its controller's next untap step.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Wall of Frost"); // 0/7
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Craw Wurm");
|
addCard(Zone.BATTLEFIELD, playerB, "Craw Wurm");
|
||||||
|
|
||||||
attack(2, playerB, "Craw Wurm");
|
attack(2, playerB, "Craw Wurm");
|
||||||
|
@ -56,9 +57,8 @@ public class AttackBlockRestrictionsTest extends CardTestPlayerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests card that says that it can't block specific cards
|
* Tests card that says that it can't block specific cards Hunted Ghoul:
|
||||||
* Hunted Ghoul:
|
* Hunted Ghoul can't block Humans.
|
||||||
* Hunted Ghoul can't block Humans.
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testFilteredBlocking() {
|
public void testFilteredBlocking() {
|
||||||
|
@ -76,9 +76,8 @@ public class AttackBlockRestrictionsTest extends CardTestPlayerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests card that says that it can't block specific cards still can block others
|
* Tests card that says that it can't block specific cards still can block
|
||||||
* Hunted Ghoul:
|
* others Hunted Ghoul: Hunted Ghoul can't block Humans.
|
||||||
* Hunted Ghoul can't block Humans.
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testFilteredBlocking2() {
|
public void testFilteredBlocking2() {
|
||||||
|
@ -176,7 +175,8 @@ public class AttackBlockRestrictionsTest extends CardTestPlayerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests "Creatures with power less than Champion of Lambholt's power can't block creatures you control."
|
* Tests "Creatures with power less than Champion of Lambholt's power can't
|
||||||
|
* block creatures you control."
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testChampionOfLambholt() {
|
public void testChampionOfLambholt() {
|
||||||
|
@ -244,22 +244,22 @@ public class AttackBlockRestrictionsTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
assertCounterCount(playerA, CounterType.POISON, 1);
|
assertCounterCount(playerA, CounterType.POISON, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCantBeBlockedTormentedSoul() {
|
public void testCantBeBlockedTormentedSoul() {
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Tormented Soul");
|
addCard(Zone.BATTLEFIELD, playerB, "Tormented Soul");
|
||||||
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Memnite");
|
addCard(Zone.BATTLEFIELD, playerA, "Memnite");
|
||||||
|
|
||||||
attack(2, playerB, "Tormented Soul");
|
attack(2, playerB, "Tormented Soul");
|
||||||
block(2, playerA, "Tormented Soul", "Memnite");
|
block(2, playerA, "Tormented Soul", "Memnite");
|
||||||
|
|
||||||
setStopAt(2, PhaseStep.END_TURN);
|
setStopAt(2, PhaseStep.END_TURN);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertPermanentCount(playerA, "Memnite", 1);
|
assertPermanentCount(playerA, "Memnite", 1);
|
||||||
assertPermanentCount(playerB, "Tormented Soul", 1);
|
assertPermanentCount(playerB, "Tormented Soul", 1);
|
||||||
|
|
||||||
assertLife(playerA, 19);
|
assertLife(playerA, 19);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
*/
|
*/
|
||||||
package mage.abilities.effects.common;
|
package mage.abilities.effects.common;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
@ -45,8 +47,10 @@ import mage.game.permanent.Permanent;
|
||||||
*/
|
*/
|
||||||
public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousRuleModifyingEffectImpl {
|
public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousRuleModifyingEffectImpl {
|
||||||
|
|
||||||
private int validForTurnNum;
|
private UUID onlyIfControlledByPlayer;
|
||||||
private String targetName;
|
private String targetName;
|
||||||
|
// holds the info what target was already handled in Untap of its controller
|
||||||
|
private final Map<UUID, Boolean> handledTargetsDuringTurn = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attention: This effect won't work with targets controlled by different
|
* Attention: This effect won't work with targets controlled by different
|
||||||
|
@ -55,19 +59,30 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public DontUntapInControllersNextUntapStepTargetEffect() {
|
public DontUntapInControllersNextUntapStepTargetEffect() {
|
||||||
super(Duration.Custom, Outcome.Detriment, false, true);
|
this("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public DontUntapInControllersNextUntapStepTargetEffect(String targetName) {
|
public DontUntapInControllersNextUntapStepTargetEffect(String targetName) {
|
||||||
this();
|
this(targetName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param targetName used as target text for the generated rule text
|
||||||
|
* @param onlyIfControlledByPlayer the effect only works if the permanent is
|
||||||
|
* controlled by that controller, null = it works for all players
|
||||||
|
*/
|
||||||
|
public DontUntapInControllersNextUntapStepTargetEffect(String targetName, UUID onlyIfControlledByPlayer) {
|
||||||
|
super(Duration.Custom, Outcome.Detriment, false, true);
|
||||||
this.targetName = targetName;
|
this.targetName = targetName;
|
||||||
|
this.onlyIfControlledByPlayer = onlyIfControlledByPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DontUntapInControllersNextUntapStepTargetEffect(final DontUntapInControllersNextUntapStepTargetEffect effect) {
|
public DontUntapInControllersNextUntapStepTargetEffect(final DontUntapInControllersNextUntapStepTargetEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
this.validForTurnNum = effect.validForTurnNum;
|
|
||||||
this.targetName = effect.targetName;
|
this.targetName = effect.targetName;
|
||||||
|
this.handledTargetsDuringTurn.putAll(effect.handledTargetsDuringTurn);
|
||||||
|
this.onlyIfControlledByPlayer = effect.onlyIfControlledByPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -97,42 +112,40 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
// the check for turn number is needed if multiple effects are added to prevent untap in next untap step of controller
|
// the check if a permanent untap pahse is already handled is needed if multiple effects are added to prevent untap in next untap step of controller
|
||||||
// if we don't check for turn number, every untap step of a turn only one effect would be used instead of correctly only one time
|
// if we don't check it for every untap step of a turn only one effect would be consumed instead of all be valid for the next untap step
|
||||||
// to skip the untap effect.
|
|
||||||
|
|
||||||
// Discard effect if it's related to a previous turn
|
|
||||||
if (validForTurnNum > 0 && validForTurnNum < game.getTurnNum()) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// remember the turn of the untap step the effect has to be applied
|
|
||||||
if (GameEvent.EventType.UNTAP_STEP.equals(event.getType())) {
|
if (GameEvent.EventType.UNTAP_STEP.equals(event.getType())) {
|
||||||
UUID controllerId = null;
|
boolean allHandled = true;
|
||||||
for (UUID targetId : getTargetPointer().getTargets(game, source)) {
|
for (UUID targetId : getTargetPointer().getTargets(game, source)) {
|
||||||
Permanent permanent = game.getPermanent(targetId);
|
Permanent permanent = game.getPermanent(targetId);
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
controllerId = permanent.getControllerId();
|
if (game.getActivePlayerId().equals(permanent.getControllerId())
|
||||||
|
|| (game.getActivePlayerId().equals(onlyIfControlledByPlayer))) { // if effect works only for specific player, all permanents have to be set to handled in that players untap step
|
||||||
|
if (!handledTargetsDuringTurn.containsKey(targetId)) {
|
||||||
|
// it's the untep step of the current controller and the effect was not handled for this target yet, so do it now
|
||||||
|
handledTargetsDuringTurn.put(targetId, false);
|
||||||
|
allHandled = false;
|
||||||
|
} else if (!handledTargetsDuringTurn.get(targetId)) {
|
||||||
|
// if it was already ready to be handled on an previous Untap step set it to done if not already so
|
||||||
|
handledTargetsDuringTurn.put(targetId, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
allHandled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (controllerId == null) { // no more targets on the battlefield, effect can be discarded
|
if (allHandled) {
|
||||||
discard();
|
discard();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (game.getActivePlayerId().equals(controllerId)) {
|
|
||||||
if (validForTurnNum == game.getTurnNum()) { // the turn has a second untap step but the effect is already related to the first untap step
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
validForTurnNum = game.getTurnNum();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == EventType.UNTAP) {
|
if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == EventType.UNTAP) {
|
||||||
if (targetPointer.getTargets(game, source).contains(event.getTargetId())) {
|
if (handledTargetsDuringTurn.containsKey(event.getTargetId())
|
||||||
|
&& !handledTargetsDuringTurn.get(event.getTargetId())
|
||||||
|
&& getTargetPointer().getTargets(game, source).contains(event.getTargetId())) {
|
||||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||||
if (permanent != null && game.getActivePlayerId().equals(permanent.getControllerId())) {
|
if (permanent != null && game.getActivePlayerId().equals(permanent.getControllerId())) {
|
||||||
|
handledTargetsDuringTurn.put(event.getTargetId(), true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue