mirror of
https://github.com/correl/mage.git
synced 2024-11-28 19:19:55 +00:00
Reworking "as long as you control this" effects (WIP) (#8620)
* added WhileControlled duration, removed SourceOnBattlefieldControlUnchangedCondition * refactored effects which keep things tapped * a few additional missed cards * refactored cards which check for being controlled and tapped * [NEO] Implemented Kyodai, Soul of Kamigawa
This commit is contained in:
parent
0ca75806fe
commit
d030848552
36 changed files with 495 additions and 1239 deletions
|
@ -1,11 +1,8 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.abilities.keyword.IndestructibleAbility;
|
import mage.abilities.keyword.IndestructibleAbility;
|
||||||
|
@ -17,7 +14,8 @@ import mage.constants.SubType;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Loki
|
* @author Loki
|
||||||
|
@ -41,13 +39,10 @@ public final class AegisAngel extends CardImpl {
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
// When Aegis Angel enters the battlefield, another target permanent is indestructible for as long as you control Aegis Angel.
|
// When Aegis Angel enters the battlefield, another target permanent is indestructible for as long as you control Aegis Angel.
|
||||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
|
Ability ability = new EntersBattlefieldTriggeredAbility(new GainAbilityTargetEffect(
|
||||||
new GainAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.Custom),
|
IndestructibleAbility.getInstance(), Duration.WhileControlled
|
||||||
new SourceOnBattlefieldControlUnchangedCondition(),
|
), false);
|
||||||
"another target permanent is indestructible for as long as you control Aegis Angel");
|
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(effect, false);
|
|
||||||
ability.addTarget(new TargetPermanent(filter));
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,5 +54,4 @@ public final class AegisAngel extends CardImpl {
|
||||||
public AegisAngel copy() {
|
public AegisAngel copy() {
|
||||||
return new AegisAngel(this);
|
return new AegisAngel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,21 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.target.common.TargetArtifactPermanent;
|
import mage.target.common.TargetArtifactPermanent;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author nigelzor
|
* @author nigelzor
|
||||||
*/
|
*/
|
||||||
public final class Aladdin extends CardImpl {
|
public final class Aladdin extends CardImpl {
|
||||||
|
@ -32,14 +28,11 @@ public final class Aladdin extends CardImpl {
|
||||||
this.toughness = new MageInt(1);
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
// {1}{R}{R}, {tap}: Gain control of target artifact for as long as you control Aladdin.
|
// {1}{R}{R}, {tap}: Gain control of target artifact for as long as you control Aladdin.
|
||||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
|
Ability ability = new SimpleActivatedAbility(
|
||||||
new GainControlTargetEffect(Duration.Custom),
|
new GainControlTargetEffect(Duration.WhileControlled), new ManaCostsImpl<>("{1}{R}{R}")
|
||||||
new SourceOnBattlefieldControlUnchangedCondition(),
|
);
|
||||||
"Gain control of target artifact for as long as you control Aladdin");
|
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{1}{R}{R}"));
|
|
||||||
ability.addCost(new TapSourceCost());
|
ability.addCost(new TapSourceCost());
|
||||||
ability.addTarget(new TargetArtifactPermanent());
|
ability.addTarget(new TargetArtifactPermanent());
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
package mage.cards.d;
|
package mage.cards.d;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.CompoundCondition;
|
|
||||||
import mage.abilities.condition.common.SourceHasRemainedInSameZoneCondition;
|
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.OneShotEffect;
|
|
||||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
import mage.abilities.keyword.DeathtouchAbility;
|
import mage.abilities.keyword.DeathtouchAbility;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
@ -16,19 +10,13 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.players.Player;
|
|
||||||
import mage.target.common.TargetCreatureOrPlaneswalker;
|
import mage.target.common.TargetCreatureOrPlaneswalker;
|
||||||
import mage.util.CardUtil;
|
|
||||||
import mage.util.GameLog;
|
import java.util.UUID;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*/
|
*/
|
||||||
public final class DragonlordSilumgar extends CardImpl {
|
public final class DragonlordSilumgar extends CardImpl {
|
||||||
|
@ -48,11 +36,9 @@ public final class DragonlordSilumgar extends CardImpl {
|
||||||
this.addAbility(DeathtouchAbility.getInstance());
|
this.addAbility(DeathtouchAbility.getInstance());
|
||||||
|
|
||||||
// When Dragonlord Silumgar enters the battlefield, gain control of target creature or planeswalker for as long as you control Dragonlord Silumgar.
|
// When Dragonlord Silumgar enters the battlefield, gain control of target creature or planeswalker for as long as you control Dragonlord Silumgar.
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(new DragonlordSilumgarEffect(), false);
|
Ability ability = new EntersBattlefieldTriggeredAbility(new GainControlTargetEffect(Duration.WhileControlled));
|
||||||
ability.addTarget(new TargetCreatureOrPlaneswalker());
|
ability.addTarget(new TargetCreatureOrPlaneswalker());
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DragonlordSilumgar(final DragonlordSilumgar card) {
|
private DragonlordSilumgar(final DragonlordSilumgar card) {
|
||||||
|
@ -64,44 +50,3 @@ public final class DragonlordSilumgar extends CardImpl {
|
||||||
return new DragonlordSilumgar(this);
|
return new DragonlordSilumgar(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DragonlordSilumgarEffect extends OneShotEffect {
|
|
||||||
|
|
||||||
public DragonlordSilumgarEffect() {
|
|
||||||
super(Outcome.GainControl);
|
|
||||||
this.staticText = "gain control of target creature or planeswalker for as long as you control {this}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public DragonlordSilumgarEffect(final DragonlordSilumgarEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DragonlordSilumgarEffect copy() {
|
|
||||||
return new DragonlordSilumgarEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
|
||||||
Permanent target = game.getPermanent(getTargetPointer().getFirst(game, source));
|
|
||||||
if (controller != null && sourcePermanent != null) {
|
|
||||||
if (target != null && controller.getId().equals(sourcePermanent.getControllerId())) {
|
|
||||||
SourceHasRemainedInSameZoneCondition condition = new SourceHasRemainedInSameZoneCondition(sourcePermanent.getId());
|
|
||||||
|
|
||||||
game.addEffect(new ConditionalContinuousEffect(
|
|
||||||
new GainControlTargetEffect(Duration.Custom),
|
|
||||||
new CompoundCondition(new SourceOnBattlefieldControlUnchangedCondition(), condition),
|
|
||||||
null),
|
|
||||||
source);
|
|
||||||
if (!game.isSimulation()) {
|
|
||||||
game.informPlayers(sourcePermanent.getLogName() + ": " + controller.getLogName() + " gained control of " + target.getLogName());
|
|
||||||
}
|
|
||||||
sourcePermanent.addInfo("gained control of", CardUtil.addToolTipMarkTags("Gained control of: " + GameLog.getColoredObjectIdNameForTooltip(target)), game);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,34 +1,33 @@
|
||||||
|
|
||||||
package mage.cards.d;
|
package mage.cards.d;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObject;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
||||||
|
import mage.abilities.effects.common.DontUntapInControllersUntapStepTargetEffect;
|
||||||
import mage.abilities.effects.common.TapTargetEffect;
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.events.ZoneChangeEvent;
|
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.target.Target;
|
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.watchers.Watcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author BetaSteward
|
* @author BetaSteward
|
||||||
*/
|
*/
|
||||||
public final class DungeonGeists extends CardImpl {
|
public final class DungeonGeists extends CardImpl {
|
||||||
|
|
||||||
public DungeonGeists(UUID ownerId, CardSetInfo setInfo) {
|
public DungeonGeists(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");
|
||||||
this.subtype.add(SubType.SPIRIT);
|
this.subtype.add(SubType.SPIRIT);
|
||||||
|
|
||||||
this.power = new MageInt(3);
|
this.power = new MageInt(3);
|
||||||
|
@ -38,11 +37,9 @@ public final class DungeonGeists extends CardImpl {
|
||||||
|
|
||||||
// When Dungeon Geists enters the battlefield, tap target creature an opponent controls. That creature doesn't untap during its controller's untap step for as long as you control Dungeon Geists.
|
// When Dungeon Geists enters the battlefield, tap target creature an opponent controls. That creature doesn't untap during its controller's untap step for as long as you control Dungeon Geists.
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect(), false);
|
Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect(), false);
|
||||||
ability.addEffect(new DungeonGeistsEffect());
|
ability.addEffect(new DontUntapInControllersUntapStepTargetEffect(Duration.WhileControlled));
|
||||||
Target target = new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE);
|
ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE));
|
||||||
ability.addTarget(target);
|
this.addAbility(ability);
|
||||||
this.addAbility(ability, new DungeonGeistsWatcher());
|
|
||||||
// watcher needed to send normal events to Dungeon Geists ReplacementEffect
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DungeonGeists(final DungeonGeists card) {
|
private DungeonGeists(final DungeonGeists card) {
|
||||||
|
@ -54,101 +51,3 @@ public final class DungeonGeists extends CardImpl {
|
||||||
return new DungeonGeists(this);
|
return new DungeonGeists(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DungeonGeistsEffect extends ContinuousRuleModifyingEffectImpl {
|
|
||||||
|
|
||||||
public DungeonGeistsEffect() {
|
|
||||||
super(Duration.Custom, Outcome.Detriment, false, false);
|
|
||||||
this.staticText = "That creature doesn't untap during its controller's untap step for as long as you control {this}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public DungeonGeistsEffect(final DungeonGeistsEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DungeonGeistsEffect copy() {
|
|
||||||
return new DungeonGeistsEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checksEventType(GameEvent event, Game game) {
|
|
||||||
return event.getType() == GameEvent.EventType.UNTAP
|
|
||||||
|| event.getType() == GameEvent.EventType.ZONE_CHANGE
|
|
||||||
|| event.getType() == GameEvent.EventType.LOST_CONTROL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
|
||||||
// Source must be on the battlefield (it's neccessary to check here because if as response to the enter
|
|
||||||
// the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL
|
|
||||||
// event will happen before this effect is applied ever)
|
|
||||||
MageObject sourceObject = source.getSourceObjectIfItStillExists(game);
|
|
||||||
if (!(sourceObject instanceof Permanent) || !((Permanent) sourceObject).isControlledBy(source.getControllerId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
switch (event.getType()) {
|
|
||||||
case ZONE_CHANGE:
|
|
||||||
// end effect if source does a zone move
|
|
||||||
if (event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case UNTAP:
|
|
||||||
// prevent to untap the target creature
|
|
||||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getTargetId().equals(targetPointer.getFirst(game, source))) {
|
|
||||||
Permanent targetCreature = game.getPermanent(targetPointer.getFirst(game, source));
|
|
||||||
if (targetCreature != null) {
|
|
||||||
return targetCreature.isControlledBy(game.getActivePlayerId());
|
|
||||||
} else {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LOST_CONTROL:
|
|
||||||
// end effect if source control is changed
|
|
||||||
if (event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DungeonGeistsWatcher extends Watcher {
|
|
||||||
|
|
||||||
DungeonGeistsWatcher() {
|
|
||||||
super(WatcherScope.CARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void watch(GameEvent event, Game game) {
|
|
||||||
if (event.getType() == GameEvent.EventType.LOST_CONTROL
|
|
||||||
&& event.getPlayerId().equals(controllerId)
|
|
||||||
&& event.getTargetId().equals(sourceId)) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(sourceId)) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
//don't reset condition each turn - only when this leaves the battlefield
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
|
|
||||||
package mage.cards.h;
|
package mage.cards.h;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.common.SkipUntapOptionalAbility;
|
import mage.abilities.common.SkipUntapOptionalAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.common.SourceTappedCondition;
|
||||||
import mage.abilities.costs.common.SacrificeTargetCost;
|
import mage.abilities.costs.common.SacrificeTargetCost;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.costs.mana.GenericManaCost;
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
|
@ -15,15 +14,14 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Zone;
|
import mage.target.common.TargetControlledPermanent;
|
||||||
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
|
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.target.common.TargetControlledCreaturePermanent;
|
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author fireshoes
|
* @author fireshoes
|
||||||
*/
|
*/
|
||||||
public final class HelmOfPossession extends CardImpl {
|
public final class HelmOfPossession extends CardImpl {
|
||||||
|
@ -35,14 +33,13 @@ public final class HelmOfPossession extends CardImpl {
|
||||||
this.addAbility(new SkipUntapOptionalAbility());
|
this.addAbility(new SkipUntapOptionalAbility());
|
||||||
|
|
||||||
// {2}, {tap}, Sacrifice a creature: Gain control of target creature for as long as you control Helm of Possession and Helm of Possession remains tapped.
|
// {2}, {tap}, Sacrifice a creature: Gain control of target creature for as long as you control Helm of Possession and Helm of Possession remains tapped.
|
||||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
|
Ability ability = new SimpleActivatedAbility(new ConditionalContinuousEffect(
|
||||||
new GainControlTargetEffect(Duration.Custom),
|
new GainControlTargetEffect(Duration.WhileControlled), SourceTappedCondition.instance,
|
||||||
new HelmOfPossessionCondition(),
|
"gain control of target creature for as long as you control {this} and {this} remains tapped"
|
||||||
"Gain control of target creature for as long as you control {this} and {this} remains tapped");
|
), new GenericManaCost(2));
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(2));
|
|
||||||
ability.addCost(new TapSourceCost());
|
ability.addCost(new TapSourceCost());
|
||||||
|
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
|
||||||
ability.addTarget(new TargetCreaturePermanent());
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,22 +52,3 @@ public final class HelmOfPossession extends CardImpl {
|
||||||
return new HelmOfPossession(this);
|
return new HelmOfPossession(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HelmOfPossessionCondition implements Condition {
|
|
||||||
|
|
||||||
private UUID controllerId;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
if (controllerId == null) {
|
|
||||||
controllerId = source.getControllerId();
|
|
||||||
}
|
|
||||||
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
|
|
||||||
if (permanent != null) {
|
|
||||||
if (permanent.isTapped()) {
|
|
||||||
return controllerId.equals(source.getControllerId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
|
|
||||||
package mage.cards.h;
|
package mage.cards.h;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.common.SkipUntapOptionalAbility;
|
import mage.abilities.common.SkipUntapOptionalAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.common.SourceTappedCondition;
|
||||||
import mage.abilities.condition.common.SourceMatchesFilterCondition;
|
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||||
import mage.abilities.effects.Effect;
|
|
||||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
@ -18,31 +15,25 @@ import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.constants.TargetController;
|
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.predicate.permanent.TappedPredicate;
|
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*/
|
*/
|
||||||
public final class HivisOfTheScale extends CardImpl {
|
public final class HivisOfTheScale extends CardImpl {
|
||||||
|
|
||||||
private static final FilterPermanent filter = new FilterPermanent();
|
|
||||||
private static final FilterPermanent filterDragon = new FilterPermanent();
|
private static final FilterPermanent filterDragon = new FilterPermanent();
|
||||||
private static final String rule = "Gain control of target Dragon for as long as you control Hivis and Hivis remains tapped.";
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(TappedPredicate.TAPPED);
|
|
||||||
filter.add(TargetController.YOU.getControllerPredicate());
|
|
||||||
filterDragon.add(SubType.DRAGON.getPredicate());
|
filterDragon.add(SubType.DRAGON.getPredicate());
|
||||||
}
|
}
|
||||||
|
|
||||||
public HivisOfTheScale(UUID ownerId, CardSetInfo setInfo) {
|
public HivisOfTheScale(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
|
||||||
|
|
||||||
addSuperType(SuperType.LEGENDARY);
|
addSuperType(SuperType.LEGENDARY);
|
||||||
this.subtype.add(SubType.VIASHINO);
|
this.subtype.add(SubType.VIASHINO);
|
||||||
this.subtype.add(SubType.SHAMAN);
|
this.subtype.add(SubType.SHAMAN);
|
||||||
|
@ -51,14 +42,14 @@ public final class HivisOfTheScale extends CardImpl {
|
||||||
|
|
||||||
// You may choose not to untap Hivis of the Scale during your untap step.
|
// You may choose not to untap Hivis of the Scale during your untap step.
|
||||||
this.addAbility(new SkipUntapOptionalAbility());
|
this.addAbility(new SkipUntapOptionalAbility());
|
||||||
|
|
||||||
// {tap}: Gain control of target Dragon for as long as you control Hivis and Hivis remains tapped.
|
// {tap}: Gain control of target Dragon for as long as you control Hivis and Hivis remains tapped.
|
||||||
Condition condition = new SourceMatchesFilterCondition(filter);
|
Ability ability = new SimpleActivatedAbility(new ConditionalContinuousEffect(
|
||||||
Effect effect = new ConditionalContinuousEffect(new GainControlTargetEffect(Duration.Custom), condition, rule);
|
new GainControlTargetEffect(Duration.WhileControlled), SourceTappedCondition.instance,
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
|
"gain control of target Dragon for as long as you control {this} and {this} remains tapped"
|
||||||
|
), new TapSourceCost());
|
||||||
ability.addTarget(new TargetPermanent(filterDragon));
|
ability.addTarget(new TargetPermanent(filterDragon));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private HivisOfTheScale(final HivisOfTheScale card) {
|
private HivisOfTheScale(final HivisOfTheScale card) {
|
||||||
|
|
|
@ -4,22 +4,19 @@ import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
import mage.abilities.effects.common.DontUntapInControllersUntapStepTargetEffect;
|
||||||
import mage.abilities.effects.common.TapTargetEffect;
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
import mage.abilities.effects.common.cost.SpellsCostModificationThatTargetSourceEffect;
|
import mage.abilities.effects.common.cost.SpellsCostModificationThatTargetSourceEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.TargetController;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.game.events.ZoneChangeEvent;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.target.Target;
|
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.watchers.Watcher;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -40,15 +37,14 @@ public final class IcefallRegent extends CardImpl {
|
||||||
// When Icefall Regent enters the battlefield, tap target creature an opponent controls.
|
// When Icefall Regent enters the battlefield, tap target creature an opponent controls.
|
||||||
// That creature doesn't untap during its controller's untap step for as long as you control Icefall Regent.
|
// That creature doesn't untap during its controller's untap step for as long as you control Icefall Regent.
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect(), false);
|
Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect(), false);
|
||||||
ability.addEffect(new IcefallRegentEffect());
|
ability.addEffect(new DontUntapInControllersUntapStepTargetEffect(Duration.WhileControlled));
|
||||||
Target target = new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE);
|
ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE));
|
||||||
ability.addTarget(target);
|
this.addAbility(ability);
|
||||||
this.addAbility(ability, new IcefallRegentWatcher());
|
|
||||||
|
|
||||||
// Spells your opponents cast that target Icefall Regent cost {2} more to cast.
|
// Spells your opponents cast that target Icefall Regent cost {2} more to cast.
|
||||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
|
this.addAbility(new SimpleStaticAbility(new SpellsCostModificationThatTargetSourceEffect(
|
||||||
new SpellsCostModificationThatTargetSourceEffect(2, new FilterCard("Spells"), TargetController.OPPONENT))
|
2, new FilterCard("Spells"), TargetController.OPPONENT
|
||||||
);
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private IcefallRegent(final IcefallRegent card) {
|
private IcefallRegent(final IcefallRegent card) {
|
||||||
|
@ -60,96 +56,3 @@ public final class IcefallRegent extends CardImpl {
|
||||||
return new IcefallRegent(this);
|
return new IcefallRegent(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IcefallRegentEffect extends ContinuousRuleModifyingEffectImpl {
|
|
||||||
|
|
||||||
public IcefallRegentEffect() {
|
|
||||||
super(Duration.Custom, Outcome.Detriment, false, false);
|
|
||||||
this.staticText = "That creature doesn't untap during its controller's untap step for as long as you control {this}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public IcefallRegentEffect(final IcefallRegentEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IcefallRegentEffect copy() {
|
|
||||||
return new IcefallRegentEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checksEventType(GameEvent event, Game game) {
|
|
||||||
return event.getType() == GameEvent.EventType.LOST_CONTROL
|
|
||||||
|| event.getType() == GameEvent.EventType.ZONE_CHANGE
|
|
||||||
|| event.getType() == GameEvent.EventType.UNTAP;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
|
||||||
// Source must be on the battlefield (it's neccessary to check here because if as response to the enter
|
|
||||||
// the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL
|
|
||||||
// event will happen before this effect is applied ever)
|
|
||||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
|
||||||
if (sourcePermanent == null || !sourcePermanent.isControlledBy(source.getControllerId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (event.getType() == GameEvent.EventType.LOST_CONTROL) {
|
|
||||||
if (event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) {
|
|
||||||
if (event.getTargetId().equals(targetPointer.getFirst(game, source))) {
|
|
||||||
Permanent targetCreature = game.getPermanent(targetPointer.getFirst(game, source));
|
|
||||||
return targetCreature != null && game.isActivePlayer(targetCreature.getControllerId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class IcefallRegentWatcher extends Watcher {
|
|
||||||
|
|
||||||
IcefallRegentWatcher() {
|
|
||||||
super(WatcherScope.CARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void watch(GameEvent event, Game game) {
|
|
||||||
if (event.getType() == GameEvent.EventType.LOST_CONTROL
|
|
||||||
&& event.getPlayerId().equals(controllerId)
|
|
||||||
&& event.getTargetId().equals(sourceId)) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(sourceId)) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
//don't reset condition each turn - only when this leaves the battlefield
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
72
Mage.Sets/src/mage/cards/k/KyodaiSoulOfKamigawa.java
Normal file
72
Mage.Sets/src/mage/cards/k/KyodaiSoulOfKamigawa.java
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
package mage.cards.k;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||||
|
import mage.abilities.keyword.FlashAbility;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.keyword.IndestructibleAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.SuperType;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class KyodaiSoulOfKamigawa extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterPermanent filter = new FilterPermanent("another target permanent");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(AnotherPredicate.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KyodaiSoulOfKamigawa(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
|
||||||
|
|
||||||
|
this.addSuperType(SuperType.LEGENDARY);
|
||||||
|
this.subtype.add(SubType.DRAGON);
|
||||||
|
this.subtype.add(SubType.SPIRIT);
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// Flash
|
||||||
|
this.addAbility(FlashAbility.getInstance());
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// When Kyodai, Soul of Kamigawa enters the battlefield, another target permanent gains indestructible for as long as you control Kyodai.
|
||||||
|
Ability ability = new EntersBattlefieldTriggeredAbility(new GainAbilityTargetEffect(
|
||||||
|
IndestructibleAbility.getInstance(), Duration.WhileControlled
|
||||||
|
), false);
|
||||||
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// {W}{U}{B}{R}{G}: Kyodai, Soul of Kamigawa gets +5/+5 until end of turn.
|
||||||
|
this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect(
|
||||||
|
5, 5, Duration.EndOfTurn
|
||||||
|
), new ManaCostsImpl<>("{W}{U}{B}{R}{G}")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private KyodaiSoulOfKamigawa(final KyodaiSoulOfKamigawa card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KyodaiSoulOfKamigawa copy() {
|
||||||
|
return new KyodaiSoulOfKamigawa(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,8 @@
|
||||||
package mage.cards.m;
|
package mage.cards.m;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
@ -13,7 +10,8 @@ import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.target.common.TargetArtifactPermanent;
|
import mage.target.common.TargetArtifactPermanent;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Loki, JayDi85
|
* @author Loki, JayDi85
|
||||||
|
@ -29,14 +27,8 @@ public final class MasterThief extends CardImpl {
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
// When Master Thief enters the battlefield, gain control of target artifact for as long as you control Master Thief.
|
// When Master Thief enters the battlefield, gain control of target artifact for as long as you control Master Thief.
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(new ConditionalContinuousEffect(
|
Ability ability = new EntersBattlefieldTriggeredAbility(new GainControlTargetEffect(Duration.WhileControlled));
|
||||||
new GainControlTargetEffect(Duration.Custom),
|
|
||||||
new SourceOnBattlefieldControlUnchangedCondition(),
|
|
||||||
"gain control of target artifact for as long as you control {this}"),
|
|
||||||
false);
|
|
||||||
|
|
||||||
ability.addTarget(new TargetArtifactPermanent());
|
ability.addTarget(new TargetArtifactPermanent());
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
package mage.cards.m;
|
package mage.cards.m;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObject;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility;
|
||||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
import mage.abilities.effects.common.DontUntapInControllersUntapStepTargetEffect;
|
||||||
import mage.abilities.effects.common.TapTargetEffect;
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.game.events.ZoneChangeEvent;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.watchers.Watcher;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -39,9 +35,9 @@ public final class MerchantRaiders extends CardImpl {
|
||||||
new TapTargetEffect("tap up to one target creature"),
|
new TapTargetEffect("tap up to one target creature"),
|
||||||
filter, false, true
|
filter, false, true
|
||||||
);
|
);
|
||||||
ability.addEffect(new MerchantRaidersEffect());
|
ability.addEffect(new DontUntapInControllersUntapStepTargetEffect(Duration.WhileControlled));
|
||||||
ability.addTarget(new TargetCreaturePermanent(0, 1));
|
ability.addTarget(new TargetCreaturePermanent(0, 1));
|
||||||
this.addAbility(ability, new MerchantRaidersWatcher());
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MerchantRaiders(final MerchantRaiders card) {
|
private MerchantRaiders(final MerchantRaiders card) {
|
||||||
|
@ -53,98 +49,3 @@ public final class MerchantRaiders extends CardImpl {
|
||||||
return new MerchantRaiders(this);
|
return new MerchantRaiders(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MerchantRaidersEffect extends ContinuousRuleModifyingEffectImpl {
|
|
||||||
|
|
||||||
public MerchantRaidersEffect() {
|
|
||||||
super(Duration.Custom, Outcome.Detriment, false, false);
|
|
||||||
this.staticText = "That creature doesn't untap during its controller's untap step for as long as you control {this}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public MerchantRaidersEffect(final MerchantRaidersEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MerchantRaidersEffect copy() {
|
|
||||||
return new MerchantRaidersEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checksEventType(GameEvent event, Game game) {
|
|
||||||
return event.getType() == GameEvent.EventType.UNTAP
|
|
||||||
|| event.getType() == GameEvent.EventType.ZONE_CHANGE
|
|
||||||
|| event.getType() == GameEvent.EventType.LOST_CONTROL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
|
||||||
// Source must be on the battlefield (it's neccessary to check here because if as response to the enter
|
|
||||||
// the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL
|
|
||||||
// event will happen before this effect is applied ever)
|
|
||||||
MageObject sourceObject = source.getSourceObjectIfItStillExists(game);
|
|
||||||
if (!(sourceObject instanceof Permanent) || !((Permanent) sourceObject).isControlledBy(source.getControllerId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
switch (event.getType()) {
|
|
||||||
case ZONE_CHANGE:
|
|
||||||
// end effect if source does a zone move
|
|
||||||
if (!event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case UNTAP:
|
|
||||||
// prevent to untap the target creature
|
|
||||||
if (game.getTurn().getStepType() != PhaseStep.UNTAP
|
|
||||||
|| !event.getTargetId().equals(targetPointer.getFirst(game, source))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Permanent targetCreature = game.getPermanent(targetPointer.getFirst(game, source));
|
|
||||||
if (targetCreature != null) {
|
|
||||||
return targetCreature.isControlledBy(game.getActivePlayerId());
|
|
||||||
} else {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case LOST_CONTROL:
|
|
||||||
// end effect if source control is changed
|
|
||||||
if (event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MerchantRaidersWatcher extends Watcher {
|
|
||||||
|
|
||||||
MerchantRaidersWatcher() {
|
|
||||||
super(WatcherScope.CARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void watch(GameEvent event, Game game) {
|
|
||||||
if (event.getType() == GameEvent.EventType.LOST_CONTROL
|
|
||||||
&& event.getPlayerId().equals(controllerId)
|
|
||||||
&& event.getTargetId().equals(sourceId)) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
return;
|
|
||||||
} else if (event.getType() == GameEvent.EventType.ZONE_CHANGE
|
|
||||||
&& event.getTargetId().equals(sourceId)) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
package mage.cards.m;
|
package mage.cards.m;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.DelayedTriggeredAbility;
|
import mage.abilities.DelayedTriggeredAbility;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||||
import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect;
|
import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect;
|
||||||
|
@ -24,10 +21,10 @@ import mage.game.events.ZoneChangeEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTarget;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*/
|
*/
|
||||||
public final class MeriekeRiBerit extends CardImpl {
|
public final class MeriekeRiBerit extends CardImpl {
|
||||||
|
@ -43,16 +40,10 @@ public final class MeriekeRiBerit extends CardImpl {
|
||||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect()));
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect()));
|
||||||
|
|
||||||
// {tap}: Gain control of target creature for as long as you control Merieke Ri Berit. When Merieke Ri Berit leaves the battlefield or becomes untapped, destroy that creature. It can't be regenerated.
|
// {tap}: Gain control of target creature for as long as you control Merieke Ri Berit. When Merieke Ri Berit leaves the battlefield or becomes untapped, destroy that creature. It can't be regenerated.
|
||||||
ConditionalContinuousEffect MeriekeRiBeritGainControlEffect = new ConditionalContinuousEffect(
|
Ability ability = new SimpleActivatedAbility(new GainControlTargetEffect(Duration.WhileControlled), new TapSourceCost());
|
||||||
new GainControlTargetEffect(Duration.Custom),
|
|
||||||
new SourceOnBattlefieldControlUnchangedCondition(),
|
|
||||||
"Gain control of target creature for as long as you control {this}");
|
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, MeriekeRiBeritGainControlEffect, new TapSourceCost());
|
|
||||||
ability.addTarget(new TargetPermanent(new FilterCreaturePermanent("target creature")));
|
ability.addTarget(new TargetPermanent(new FilterCreaturePermanent("target creature")));
|
||||||
ability.addEffect(new MeriekeRiBeritCreateDelayedTriggerEffect());
|
ability.addEffect(new MeriekeRiBeritCreateDelayedTriggerEffect());
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MeriekeRiBerit(final MeriekeRiBerit card) {
|
private MeriekeRiBerit(final MeriekeRiBerit card) {
|
||||||
|
|
|
@ -9,8 +9,6 @@ import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -28,7 +26,7 @@ public final class MindFlayer extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// Dominate Monster — When Mind Flayer enters the battlefield, gain control of target creature for as long as you control Mind Flayer.
|
// Dominate Monster — When Mind Flayer enters the battlefield, gain control of target creature for as long as you control Mind Flayer.
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(new MindFlayerEffect());
|
Ability ability = new EntersBattlefieldTriggeredAbility(new GainControlTargetEffect(Duration.WhileControlled));
|
||||||
ability.addTarget(new TargetCreaturePermanent());
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
this.addAbility(ability.withFlavorWord("Dominate Monster"));
|
this.addAbility(ability.withFlavorWord("Dominate Monster"));
|
||||||
}
|
}
|
||||||
|
@ -42,33 +40,3 @@ public final class MindFlayer extends CardImpl {
|
||||||
return new MindFlayer(this);
|
return new MindFlayer(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MindFlayerEffect extends GainControlTargetEffect {
|
|
||||||
|
|
||||||
MindFlayerEffect() {
|
|
||||||
super(Duration.Custom, true);
|
|
||||||
staticText = "gain control of target creature for as long as you control {this}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private MindFlayerEffect(final MindFlayerEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MindFlayerEffect copy() {
|
|
||||||
return new MindFlayerEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
|
|
||||||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
|
||||||
if (sourcePermanent == null
|
|
||||||
|| permanent == null
|
|
||||||
|| !sourcePermanent.isControlledBy(source.getControllerId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return super.apply(game, source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
|
|
||||||
package mage.cards.o;
|
package mage.cards.o;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.common.DamageTargetEffect;
|
import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
import mage.abilities.effects.common.continuous.AddCardSubTypeTargetEffect;
|
import mage.abilities.effects.common.continuous.AddCardSubTypeTargetEffect;
|
||||||
|
@ -19,14 +16,13 @@ import mage.constants.*;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.filter.predicate.mageobject.CardIdPredicate;
|
|
||||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||||
|
import mage.filter.predicate.mageobject.CardIdPredicate;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author nantuko
|
* @author nantuko
|
||||||
*/
|
*/
|
||||||
public final class OliviaVoldaren extends CardImpl {
|
public final class OliviaVoldaren extends CardImpl {
|
||||||
|
@ -40,7 +36,7 @@ public final class OliviaVoldaren extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
public OliviaVoldaren(UUID ownerId, CardSetInfo setInfo) {
|
public OliviaVoldaren(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}");
|
||||||
addSuperType(SuperType.LEGENDARY);
|
addSuperType(SuperType.LEGENDARY);
|
||||||
this.subtype.add(SubType.VAMPIRE);
|
this.subtype.add(SubType.VAMPIRE);
|
||||||
|
|
||||||
|
@ -57,9 +53,9 @@ public final class OliviaVoldaren extends CardImpl {
|
||||||
|
|
||||||
// {1}{R}: Olivia Voldaren deals 1 damage to another target creature. That creature becomes a Vampire in addition to its other types. Put a +1/+1 counter on Olivia Voldaren.
|
// {1}{R}: Olivia Voldaren deals 1 damage to another target creature. That creature becomes a Vampire in addition to its other types. Put a +1/+1 counter on Olivia Voldaren.
|
||||||
Ability ability = new SimpleActivatedAbility(
|
Ability ability = new SimpleActivatedAbility(
|
||||||
Zone.BATTLEFIELD,
|
new DamageTargetEffect(1)
|
||||||
new DamageTargetEffect(1).setText("{this} deals 1 damage to another target creature"),
|
.setText("{this} deals 1 damage to another target creature"),
|
||||||
new ManaCostsImpl("{1}{R}")
|
new ManaCostsImpl<>("{1}{R}")
|
||||||
);
|
);
|
||||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||||
Effect effect = new AddCardSubTypeTargetEffect(SubType.VAMPIRE, Duration.WhileOnBattlefield);
|
Effect effect = new AddCardSubTypeTargetEffect(SubType.VAMPIRE, Duration.WhileOnBattlefield);
|
||||||
|
@ -69,9 +65,9 @@ public final class OliviaVoldaren extends CardImpl {
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
// {3}{B}{B}: Gain control of target Vampire for as long as you control Olivia Voldaren.
|
// {3}{B}{B}: Gain control of target Vampire for as long as you control Olivia Voldaren.
|
||||||
Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD,
|
Ability ability2 = new SimpleActivatedAbility(
|
||||||
new ConditionalContinuousEffect(new GainControlTargetEffect(Duration.Custom), new PermanentsOnTheBattlefieldCondition(filter2), rule),
|
new GainControlTargetEffect(Duration.WhileControlled), new ManaCostsImpl<>("{3}{B}{B}")
|
||||||
new ManaCostsImpl("{3}{B}{B}"));
|
);
|
||||||
ability2.addTarget(new TargetCreaturePermanent(vampireFilter));
|
ability2.addTarget(new TargetCreaturePermanent(vampireFilter));
|
||||||
this.addAbility(ability2);
|
this.addAbility(ability2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
package mage.cards.o;
|
package mage.cards.o;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.AttacksAndIsNotBlockedTriggeredAbility;
|
import mage.abilities.common.AttacksAndIsNotBlockedTriggeredAbility;
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.common.continuous.AssignNoCombatDamageSourceEffect;
|
import mage.abilities.effects.common.continuous.AssignNoCombatDamageSourceEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
@ -16,10 +13,10 @@ import mage.constants.SubType;
|
||||||
import mage.filter.common.FilterLandPermanent;
|
import mage.filter.common.FilterLandPermanent;
|
||||||
import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate;
|
import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public final class OrcishSquatters extends CardImpl {
|
public final class OrcishSquatters extends CardImpl {
|
||||||
|
@ -38,14 +35,9 @@ public final class OrcishSquatters extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// Whenever Orcish Squatters attacks and isn't blocked, you may gain control of target land defending player controls for as long as you control Orcish Squatters. If you do, Orcish Squatters assigns no combat damage this turn.
|
// Whenever Orcish Squatters attacks and isn't blocked, you may gain control of target land defending player controls for as long as you control Orcish Squatters. If you do, Orcish Squatters assigns no combat damage this turn.
|
||||||
Ability ability = new AttacksAndIsNotBlockedTriggeredAbility(new ConditionalContinuousEffect(
|
Ability ability = new AttacksAndIsNotBlockedTriggeredAbility(new GainControlTargetEffect(Duration.WhileControlled), true);
|
||||||
new GainControlTargetEffect(Duration.Custom),
|
|
||||||
new SourceOnBattlefieldControlUnchangedCondition(),
|
|
||||||
"gain control of target land defending player controls for as long as you control {this}"
|
|
||||||
), true);
|
|
||||||
ability.addEffect(new AssignNoCombatDamageSourceEffect(Duration.EndOfTurn, true));
|
ability.addEffect(new AssignNoCombatDamageSourceEffect(Duration.EndOfTurn, true));
|
||||||
ability.addTarget(new TargetPermanent(filter));
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
package mage.cards.q;
|
package mage.cards.q;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.common.DamageTargetEffect;
|
import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
@ -15,14 +12,13 @@ import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterControlledArtifactPermanent;
|
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.target.common.TargetAnyTarget;
|
import mage.target.common.TargetAnyTarget;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Styxo
|
* @author Styxo
|
||||||
*/
|
*/
|
||||||
public final class QuicksmithRebel extends CardImpl {
|
public final class QuicksmithRebel extends CardImpl {
|
||||||
|
@ -36,15 +32,10 @@ public final class QuicksmithRebel extends CardImpl {
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
// When Quicksmith Rebel enters the battlefield, target artifact you control gains "{T}: This artifact deals 2 damage to any target" for as long as you control Quicksmith Rebel.
|
// When Quicksmith Rebel enters the battlefield, target artifact you control gains "{T}: This artifact deals 2 damage to any target" for as long as you control Quicksmith Rebel.
|
||||||
Ability artifactAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new TapSourceCost());
|
Ability artifactAbility = new SimpleActivatedAbility(new DamageTargetEffect(2), new TapSourceCost());
|
||||||
artifactAbility.addTarget(new TargetAnyTarget());
|
artifactAbility.addTarget(new TargetAnyTarget());
|
||||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
|
Ability ability = new EntersBattlefieldTriggeredAbility(new GainAbilityTargetEffect(artifactAbility, Duration.WhileControlled).setText("target artifact you control gains \"{T}: This artifact deals 2 damage to any target\" for as long as you control {this}"));
|
||||||
new GainAbilityTargetEffect(artifactAbility, Duration.Custom),
|
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT));
|
||||||
new SourceOnBattlefieldControlUnchangedCondition(),
|
|
||||||
"target artifact you control gains \"{T}: This artifact deals 2 damage to any target\" for as long as you control {this}");
|
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(effect, false);
|
|
||||||
ability.addTarget(new TargetPermanent(new FilterControlledArtifactPermanent()));
|
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,24 @@
|
||||||
package mage.cards.q;
|
package mage.cards.q;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterControlledArtifactPermanent;
|
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
import mage.target.common.TargetAnyTarget;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Styxo
|
* @author Styxo
|
||||||
*/
|
*/
|
||||||
public final class QuicksmithSpy extends CardImpl {
|
public final class QuicksmithSpy extends CardImpl {
|
||||||
|
@ -35,14 +32,10 @@ public final class QuicksmithSpy extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// When Quicksmith Spy enters the battlefield, target artifact you control gains "{T}: Draw a card" for as long as you control Quicksmith Spy.
|
// When Quicksmith Spy enters the battlefield, target artifact you control gains "{T}: Draw a card" for as long as you control Quicksmith Spy.
|
||||||
Ability artifactAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new TapSourceCost());
|
Ability artifactAbility = new SimpleActivatedAbility(new DamageTargetEffect(2), new TapSourceCost());
|
||||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
|
artifactAbility.addTarget(new TargetAnyTarget());
|
||||||
new GainAbilityTargetEffect(artifactAbility, Duration.Custom),
|
Ability ability = new EntersBattlefieldTriggeredAbility(new GainAbilityTargetEffect(artifactAbility, Duration.WhileControlled).setText("target artifact you control gains \"{T}: Draw a card\" for as long as you control {this}"));
|
||||||
new SourceOnBattlefieldControlUnchangedCondition(),
|
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT));
|
||||||
"target artifact you control gains \"{T}: Draw a card\" for as long as you control {this}");
|
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(effect, false);
|
|
||||||
ability.addTarget(new TargetPermanent(new FilterControlledArtifactPermanent()));
|
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
package mage.cards.r;
|
package mage.cards.r;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.LandfallAbility;
|
import mage.abilities.common.LandfallAbility;
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*/
|
*/
|
||||||
public final class RoilElemental extends CardImpl {
|
public final class RoilElemental extends CardImpl {
|
||||||
|
@ -27,16 +26,12 @@ public final class RoilElemental extends CardImpl {
|
||||||
this.power = new MageInt(3);
|
this.power = new MageInt(3);
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
String rule = "you may gain control of target creature for as long as you control Roil Elemental";
|
|
||||||
|
|
||||||
// Flying
|
// Flying
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
// Landfall - Whenever a land enters the battlefield under your control, you may gain control of target creature for as long as you control Roil Elemental.
|
// Landfall - Whenever a land enters the battlefield under your control, you may gain control of target creature for as long as you control Roil Elemental.
|
||||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(new GainControlTargetEffect(Duration.Custom), new SourceOnBattlefieldControlUnchangedCondition(), rule);
|
Ability ability = new LandfallAbility(new GainControlTargetEffect(Duration.WhileControlled), true);
|
||||||
Ability ability = new LandfallAbility(Zone.BATTLEFIELD, effect, true);
|
|
||||||
ability.addTarget(new TargetCreaturePermanent());
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,30 @@
|
||||||
|
|
||||||
package mage.cards.r;
|
package mage.cards.r;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.common.SkipUntapOptionalAbility;
|
import mage.abilities.common.SkipUntapOptionalAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.common.SourceTappedCondition;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class RubiniaSoulsinger extends CardImpl {
|
public final class RubiniaSoulsinger extends CardImpl {
|
||||||
|
|
||||||
public RubiniaSoulsinger(UUID ownerId, CardSetInfo setInfo) {
|
public RubiniaSoulsinger(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{W}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{W}{U}");
|
||||||
addSuperType(SuperType.LEGENDARY);
|
addSuperType(SuperType.LEGENDARY);
|
||||||
this.subtype.add(SubType.FAERIE);
|
this.subtype.add(SubType.FAERIE);
|
||||||
|
|
||||||
|
@ -37,12 +33,12 @@ public final class RubiniaSoulsinger extends CardImpl {
|
||||||
|
|
||||||
// You may choose not to untap Rubinia Soulsinger during your untap step.
|
// You may choose not to untap Rubinia Soulsinger during your untap step.
|
||||||
this.addAbility(new SkipUntapOptionalAbility());
|
this.addAbility(new SkipUntapOptionalAbility());
|
||||||
|
|
||||||
// {tap}: Gain control of target creature for as long as you control Rubinia and Rubinia remains tapped.
|
// {tap}: Gain control of target creature for as long as you control Rubinia and Rubinia remains tapped.
|
||||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
|
Ability ability = new SimpleActivatedAbility(new ConditionalContinuousEffect(
|
||||||
new GainControlTargetEffect(Duration.OneUse),
|
new GainControlTargetEffect(Duration.WhileControlled), SourceTappedCondition.instance,
|
||||||
new RubiniaSoulsingerCondition(),
|
"gain control of target creature for as long as you control {this} and {this} remains tapped"
|
||||||
"Gain control of target creature for as long as you control Rubinia and Rubinia remains tapped");
|
), new TapSourceCost());
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
|
|
||||||
ability.addTarget(new TargetCreaturePermanent());
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
@ -56,22 +52,3 @@ public final class RubiniaSoulsinger extends CardImpl {
|
||||||
return new RubiniaSoulsinger(this);
|
return new RubiniaSoulsinger(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RubiniaSoulsingerCondition implements Condition {
|
|
||||||
|
|
||||||
private UUID controllerId;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
if (controllerId == null) {
|
|
||||||
controllerId = source.getControllerId();
|
|
||||||
}
|
|
||||||
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
|
|
||||||
if (permanent != null) {
|
|
||||||
if (permanent.isTapped()) {
|
|
||||||
return controllerId.equals(source.getControllerId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,9 +5,6 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.common.ControlsPermanentsControllerTriggeredAbility;
|
import mage.abilities.common.ControlsPermanentsControllerTriggeredAbility;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.common.SkipUntapOptionalAbility;
|
import mage.abilities.common.SkipUntapOptionalAbility;
|
||||||
import mage.abilities.condition.CompoundCondition;
|
|
||||||
import mage.abilities.condition.Condition;
|
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
|
||||||
import mage.abilities.condition.common.SourceTappedCondition;
|
import mage.abilities.condition.common.SourceTappedCondition;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||||
|
@ -17,11 +14,13 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.filter.common.FilterLandPermanent;
|
import mage.filter.predicate.ObjectSourcePlayer;
|
||||||
import mage.filter.predicate.mageobject.CardIdPredicate;
|
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||||
import mage.filter.predicate.permanent.ControllerControlsIslandPredicate;
|
import mage.game.Game;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -30,13 +29,15 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class Seasinger extends CardImpl {
|
public final class Seasinger extends CardImpl {
|
||||||
|
|
||||||
private static final String rule = "Gain control of target creature whose controller controls an Island for as long as you control Seasinger and Seasinger remains tapped";
|
private static final FilterPermanent filter
|
||||||
private static final FilterPermanent islandYouControl = new FilterPermanent("Island");
|
= new FilterPermanent("Island");
|
||||||
private static final FilterCreaturePermanent creatureWhoseControllerControlsIsland = new FilterCreaturePermanent("creature whose controller controls an island");
|
private static final FilterPermanent filter2
|
||||||
|
= new FilterCreaturePermanent("creature whose controler controls an Island");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
islandYouControl.add(SubType.ISLAND.getPredicate());
|
filter.add(SubType.ISLAND.getPredicate());
|
||||||
islandYouControl.add(TargetController.YOU.getControllerPredicate());
|
filter.add(TargetController.YOU.getControllerPredicate());
|
||||||
|
filter2.add(SeasingerPredicate.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Seasinger(UUID ownerId, CardSetInfo setInfo) {
|
public Seasinger(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
@ -46,26 +47,21 @@ public final class Seasinger extends CardImpl {
|
||||||
this.power = new MageInt(0);
|
this.power = new MageInt(0);
|
||||||
this.toughness = new MageInt(1);
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
FilterPermanent seasinger = new FilterPermanent();
|
|
||||||
seasinger.add(TargetController.YOU.getControllerPredicate());
|
|
||||||
seasinger.add(new CardIdPredicate(this.getId()));
|
|
||||||
Condition condition = new CompoundCondition(new PermanentsOnTheBattlefieldCondition(seasinger, ComparisonType.EQUAL_TO, 1), SourceTappedCondition.instance);
|
|
||||||
|
|
||||||
// When you control no Islands, sacrifice Seasinger.
|
// When you control no Islands, sacrifice Seasinger.
|
||||||
this.addAbility(new ControlsPermanentsControllerTriggeredAbility(
|
this.addAbility(new ControlsPermanentsControllerTriggeredAbility(
|
||||||
new FilterLandPermanent(SubType.ISLAND, "no Islands"), ComparisonType.EQUAL_TO, 0,
|
filter, ComparisonType.EQUAL_TO, 0, new SacrificeSourceEffect()
|
||||||
new SacrificeSourceEffect()));
|
));
|
||||||
|
|
||||||
// You may choose not to untap Seasinger during your untap step.
|
// You may choose not to untap Seasinger during your untap step.
|
||||||
this.addAbility(new SkipUntapOptionalAbility());
|
this.addAbility(new SkipUntapOptionalAbility());
|
||||||
|
|
||||||
// {tap}: Gain control of target creature whose controller controls an Island for as long as you control Seasinger and Seasinger remains tapped.
|
// {tap}: Gain control of target creature whose controller controls an Island for as long as you control Seasinger and Seasinger remains tapped.
|
||||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
|
Ability ability = new SimpleActivatedAbility(new ConditionalContinuousEffect(
|
||||||
new GainControlTargetEffect(Duration.Custom),
|
new GainControlTargetEffect(Duration.WhileControlled), SourceTappedCondition.instance,
|
||||||
condition, rule);
|
"gain control of target creature whose controller controls " +
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
|
"an Island for as long as you control {this} and {this} remains tapped"
|
||||||
creatureWhoseControllerControlsIsland.add(new ControllerControlsIslandPredicate());
|
), new TapSourceCost());
|
||||||
ability.addTarget(new TargetCreaturePermanent(creatureWhoseControllerControlsIsland));
|
ability.addTarget(new TargetPermanent(filter2));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,3 +74,13 @@ public final class Seasinger extends CardImpl {
|
||||||
return new Seasinger(this);
|
return new Seasinger(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SeasingerPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||||
|
instance;
|
||||||
|
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.ISLAND);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||||
|
return game.getBattlefield().contains(filter, input.getSourceId(), input.getObject().getControllerId(), game, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,37 +1,28 @@
|
||||||
|
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility;
|
import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility;
|
||||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
import mage.abilities.effects.common.DontUntapInControllersUntapStepTargetEffect;
|
||||||
import mage.abilities.effects.common.TapTargetEffect;
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
import mage.abilities.keyword.MonstrosityAbility;
|
import mage.abilities.keyword.MonstrosityAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.SubType;
|
||||||
import mage.constants.PhaseStep;
|
|
||||||
import mage.constants.WatcherScope;
|
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.game.events.ZoneChangeEvent;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.watchers.Watcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class ShipbreakerKraken extends CardImpl {
|
public final class ShipbreakerKraken extends CardImpl {
|
||||||
|
|
||||||
public ShipbreakerKraken(UUID ownerId, CardSetInfo setInfo) {
|
public ShipbreakerKraken(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}");
|
||||||
this.subtype.add(SubType.KRAKEN);
|
this.subtype.add(SubType.KRAKEN);
|
||||||
|
|
||||||
this.power = new MageInt(6);
|
this.power = new MageInt(6);
|
||||||
|
@ -39,11 +30,13 @@ public final class ShipbreakerKraken extends CardImpl {
|
||||||
|
|
||||||
// {6}{U}{U}: Monstrosity 4.
|
// {6}{U}{U}: Monstrosity 4.
|
||||||
this.addAbility(new MonstrosityAbility("{6}{U}{U}", 4));
|
this.addAbility(new MonstrosityAbility("{6}{U}{U}", 4));
|
||||||
|
|
||||||
// When Shipbreaker Kraken becomes monstrous, tap up to four target creatures. Those creatures don't untap during their controllers' untap steps for as long as you control Shipbreaker Kraken.
|
// When Shipbreaker Kraken becomes monstrous, tap up to four target creatures. Those creatures don't untap during their controllers' untap steps for as long as you control Shipbreaker Kraken.
|
||||||
Ability ability = new BecomesMonstrousSourceTriggeredAbility(new TapTargetEffect());
|
Ability ability = new BecomesMonstrousSourceTriggeredAbility(new TapTargetEffect());
|
||||||
ability.addTarget(new TargetCreaturePermanent(0,4));
|
ability.addTarget(new TargetCreaturePermanent(0, 4));
|
||||||
ability.addEffect(new ShipbreakerKrakenReplacementEffect());
|
ability.addEffect(new DontUntapInControllersUntapStepTargetEffect(Duration.WhileControlled)
|
||||||
this.addAbility(ability, new ShipbreakerKrakenWatcher());
|
.setText("Those creatures don't untap during their controllers' untap steps for as long as you control {this}"));
|
||||||
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ShipbreakerKraken(final ShipbreakerKraken card) {
|
private ShipbreakerKraken(final ShipbreakerKraken card) {
|
||||||
|
@ -55,95 +48,3 @@ public final class ShipbreakerKraken extends CardImpl {
|
||||||
return new ShipbreakerKraken(this);
|
return new ShipbreakerKraken(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ShipbreakerKrakenReplacementEffect extends ContinuousRuleModifyingEffectImpl {
|
|
||||||
|
|
||||||
public ShipbreakerKrakenReplacementEffect() {
|
|
||||||
super(Duration.Custom, Outcome.Detriment);
|
|
||||||
this.staticText = "Those creatures don't untap during their controllers' untap steps for as long as you control {this}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShipbreakerKrakenReplacementEffect(final ShipbreakerKrakenReplacementEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ShipbreakerKrakenReplacementEffect copy() {
|
|
||||||
return new ShipbreakerKrakenReplacementEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checksEventType(GameEvent event, Game game) {
|
|
||||||
return event.getType() == GameEvent.EventType.LOST_CONTROL ||
|
|
||||||
event.getType() == GameEvent.EventType.ZONE_CHANGE ||
|
|
||||||
event.getType() == GameEvent.EventType.UNTAP;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
|
||||||
// Source must be on the battlefield (it's neccessary to check here because if as response to the enter
|
|
||||||
// the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL
|
|
||||||
// event will happen before this effect is applied ever)
|
|
||||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
|
||||||
if (sourcePermanent == null || !sourcePermanent.isControlledBy(source.getControllerId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (event.getType() == GameEvent.EventType.LOST_CONTROL) {
|
|
||||||
if (event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) {
|
|
||||||
if (targetPointer.getTargets(game, source).contains(event.getTargetId())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ShipbreakerKrakenWatcher extends Watcher {
|
|
||||||
|
|
||||||
ShipbreakerKrakenWatcher () {
|
|
||||||
super(WatcherScope.CARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void watch(GameEvent event, Game game) {
|
|
||||||
if (event.getType() == GameEvent.EventType.LOST_CONTROL
|
|
||||||
&& event.getPlayerId().equals(controllerId)
|
|
||||||
&& event.getTargetId().equals(sourceId)) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(sourceId)) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent)event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
//don't reset condition each turn - only when this leaves the battlefield
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
package mage.cards.t;
|
package mage.cards.t;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EndOfCombatTriggeredAbility;
|
import mage.abilities.common.EndOfCombatTriggeredAbility;
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
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.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
|
@ -21,37 +17,37 @@ import mage.game.combat.CombatGroup;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTarget;
|
||||||
import mage.watchers.common.BlockedAttackerWatcher;
|
import mage.watchers.common.BlockedAttackerWatcher;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*
|
* <p>
|
||||||
* 5/1/2009 The ability grants you control of all creatures that are blocking it
|
* 5/1/2009 The ability grants you control of all creatures that are blocking it
|
||||||
* as the ability resolves. This will include any creatures that were put onto
|
* as the ability resolves. This will include any creatures that were put onto
|
||||||
* the battlefield blocking it.
|
* the battlefield blocking it.
|
||||||
*
|
* <p>
|
||||||
* 5/1/2009 Any blocking creatures that regenerated during combat will have been
|
* 5/1/2009 Any blocking creatures that regenerated during combat will have been
|
||||||
* removed from combat. Since such creatures are no longer in combat, they
|
* removed from combat. Since such creatures are no longer in combat, they
|
||||||
* cannot be blocking The Wretched, which means you won't be able to gain
|
* cannot be blocking The Wretched, which means you won't be able to gain
|
||||||
* control of them.
|
* control of them.
|
||||||
*
|
* <p>
|
||||||
* 5/1/2009 If The Wretched itself regenerated during combat, then it will have
|
* 5/1/2009 If The Wretched itself regenerated during combat, then it will have
|
||||||
* been removed from combat. Since it is no longer in combat, there cannot be
|
* been removed from combat. Since it is no longer in combat, there cannot be
|
||||||
* any creatures blocking it, which means you won't be able to gain control of
|
* any creatures blocking it, which means you won't be able to gain control of
|
||||||
* any creatures.
|
* any creatures.
|
||||||
*
|
* <p>
|
||||||
* 10/1/2009 The Wretched's ability triggers only if it's still on the
|
* 10/1/2009 The Wretched's ability triggers only if it's still on the
|
||||||
* battlefield when the end of combat step begins (after the combat damage
|
* battlefield when the end of combat step begins (after the combat damage
|
||||||
* step). For example, if it's blocked by a 7/7 creature and is destroyed, its
|
* step). For example, if it's blocked by a 7/7 creature and is destroyed, its
|
||||||
* ability won't trigger at all.
|
* ability won't trigger at all.
|
||||||
*
|
* <p>
|
||||||
* 10/1/2009 If The Wretched leaves the battlefield, you no longer control it,
|
* 10/1/2009 If The Wretched leaves the battlefield, you no longer control it,
|
||||||
* so the duration of its control-change effect ends.
|
* so the duration of its control-change effect ends.
|
||||||
*
|
* <p>
|
||||||
* 10/1/2009 If you lose control of The Wretched before its ability resolves,
|
* 10/1/2009 If you lose control of The Wretched before its ability resolves,
|
||||||
* you won't gain control of the creatures blocking it at all.
|
* you won't gain control of the creatures blocking it at all.
|
||||||
*
|
* <p>
|
||||||
* 10/1/2009 Once the ability resolves, it doesn't care whether the permanents
|
* 10/1/2009 Once the ability resolves, it doesn't care whether the permanents
|
||||||
* you gained control of remain creatures, only that they remain on the
|
* you gained control of remain creatures, only that they remain on the
|
||||||
* battlefield.
|
* battlefield.
|
||||||
|
@ -65,9 +61,7 @@ public final class TheWretched extends CardImpl {
|
||||||
this.toughness = new MageInt(5);
|
this.toughness = new MageInt(5);
|
||||||
|
|
||||||
// At end of combat, gain control of all creatures blocking The Wretched for as long as you control The Wretched.
|
// At end of combat, gain control of all creatures blocking The Wretched for as long as you control The Wretched.
|
||||||
Ability ability = new EndOfCombatTriggeredAbility(new TheWretchedEffect(), false);
|
this.addAbility(new EndOfCombatTriggeredAbility(new TheWretchedEffect(), false), new BlockedAttackerWatcher());
|
||||||
this.addAbility(ability, new BlockedAttackerWatcher());
|
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TheWretched(final TheWretched card) {
|
private TheWretched(final TheWretched card) {
|
||||||
|
@ -93,33 +87,27 @@ class TheWretchedEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent theWretched = (Permanent) source.getSourceObjectIfItStillExists(game);
|
Permanent theWretched = source.getSourcePermanentIfItStillExists(game);
|
||||||
if (theWretched == null) {
|
if (theWretched == null
|
||||||
return false;
|
|| theWretched.isRemovedFromCombat()
|
||||||
}
|
|| !theWretched.isAttacking()
|
||||||
if (theWretched.isRemovedFromCombat() || !theWretched.isAttacking()) {
|
|| !source.isControlledBy(theWretched.getControllerId())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check if control of source has changed since ability triggered????? (does it work is it neccessary???)
|
// Check if control of source has changed since ability triggered????? (does it work is it neccessary???)
|
||||||
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
|
|
||||||
if (permanent != null && !Objects.equals(permanent.getControllerId(), source.getControllerId())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (CombatGroup combatGroup : game.getCombat().getGroups()) {
|
for (CombatGroup combatGroup : game.getCombat().getGroups()) {
|
||||||
if (combatGroup.getAttackers().contains(source.getSourceId())) {
|
if (!combatGroup.getAttackers().contains(source.getSourceId())) {
|
||||||
for (UUID creatureId : combatGroup.getBlockers()) {
|
continue;
|
||||||
Permanent blocker = game.getPermanent(creatureId);
|
}
|
||||||
if (blocker != null
|
for (UUID creatureId : combatGroup.getBlockers()) {
|
||||||
&& blocker.getBlocking() > 0) {
|
Permanent blocker = game.getPermanent(creatureId);
|
||||||
ContinuousEffect effect = new ConditionalContinuousEffect(
|
if (blocker == null
|
||||||
new GainControlTargetEffect(Duration.Custom, source.getControllerId()),
|
|| blocker.getBlocking() <= 0) {
|
||||||
new SourceOnBattlefieldControlUnchangedCondition(), "");
|
continue;
|
||||||
effect.setTargetPointer(new FixedTarget(blocker.getId(), game));
|
|
||||||
game.addEffect(effect, source);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ContinuousEffect effect = new GainControlTargetEffect(Duration.WhileControlled, source.getControllerId());
|
||||||
|
effect.setTargetPointer(new FixedTarget(blocker.getId(), game));
|
||||||
|
game.addEffect(effect, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
package mage.cards.t;
|
package mage.cards.t;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.common.continuous.BoostAllEffect;
|
import mage.abilities.effects.common.continuous.BoostAllEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
@ -18,19 +15,15 @@ import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author MarcoMarin
|
* @author MarcoMarin
|
||||||
*/
|
*/
|
||||||
public final class ThrullChampion extends CardImpl {
|
public final class ThrullChampion extends CardImpl {
|
||||||
|
|
||||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Thrull creatures");
|
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.THRULL, "Thrull creatures");
|
||||||
|
|
||||||
static {
|
|
||||||
filter.add(SubType.THRULL.getPredicate());
|
|
||||||
}
|
|
||||||
|
|
||||||
public ThrullChampion(UUID ownerId, CardSetInfo setInfo) {
|
public ThrullChampion(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
|
||||||
|
@ -40,14 +33,11 @@ public final class ThrullChampion extends CardImpl {
|
||||||
|
|
||||||
// Thrull creatures get +1/+1.
|
// Thrull creatures get +1/+1.
|
||||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, false)));
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, false)));
|
||||||
|
|
||||||
// {tap}: Gain control of target Thrull for as long as you control Thrull Champion.
|
// {tap}: Gain control of target Thrull for as long as you control Thrull Champion.
|
||||||
ConditionalContinuousEffect ThrullChampionGainControlEffect = new ConditionalContinuousEffect(
|
Ability ability = new SimpleActivatedAbility(new GainControlTargetEffect(Duration.WhileControlled)
|
||||||
new GainControlTargetEffect(Duration.Custom),
|
.setText("gain control of target Thrull for as long as you control {this}"), new TapSourceCost());
|
||||||
new SourceOnBattlefieldControlUnchangedCondition(),
|
|
||||||
"Gain control of target Thrull for as long as you control {this}");
|
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, ThrullChampionGainControlEffect, new TapSourceCost());
|
|
||||||
ability.addTarget(new TargetPermanent(filter));
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,48 +1,43 @@
|
||||||
|
|
||||||
package mage.cards.t;
|
package mage.cards.t;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.ObjectColor;
|
import mage.ObjectColor;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
import mage.abilities.effects.common.DontUntapInControllersUntapStepTargetEffect;
|
||||||
import mage.abilities.effects.common.TapTargetEffect;
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.SubType;
|
||||||
import mage.constants.PhaseStep;
|
|
||||||
import mage.constants.TargetController;
|
import mage.constants.TargetController;
|
||||||
import mage.constants.WatcherScope;
|
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.filter.predicate.Predicates;
|
import mage.filter.predicate.Predicates;
|
||||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.game.events.ZoneChangeEvent;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.target.Target;
|
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.watchers.Watcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class TidebinderMage extends CardImpl {
|
public final class TidebinderMage extends CardImpl {
|
||||||
|
|
||||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("red or green creature an opponent controls");
|
private static final FilterCreaturePermanent filter
|
||||||
|
= new FilterCreaturePermanent("red or green creature an opponent controls");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(TargetController.OPPONENT.getControllerPredicate());
|
filter.add(TargetController.OPPONENT.getControllerPredicate());
|
||||||
filter.add(Predicates.or(new ColorPredicate(ObjectColor.RED), new ColorPredicate(ObjectColor.GREEN)));
|
filter.add(Predicates.or(
|
||||||
|
new ColorPredicate(ObjectColor.RED),
|
||||||
|
new ColorPredicate(ObjectColor.GREEN)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TidebinderMage(UUID ownerId, CardSetInfo setInfo) {
|
public TidebinderMage(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{U}");
|
||||||
this.subtype.add(SubType.MERFOLK);
|
this.subtype.add(SubType.MERFOLK);
|
||||||
this.subtype.add(SubType.WIZARD);
|
this.subtype.add(SubType.WIZARD);
|
||||||
|
|
||||||
|
@ -52,11 +47,9 @@ public final class TidebinderMage extends CardImpl {
|
||||||
// When Tidebinder Mage enters the battlefield, tap target red or green creature an opponent controls.
|
// When Tidebinder Mage enters the battlefield, tap target red or green creature an opponent controls.
|
||||||
// That creature doesn't untap during its controller's untap step for as long as you control Tidebinder Mage.
|
// That creature doesn't untap during its controller's untap step for as long as you control Tidebinder Mage.
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect(), false);
|
Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect(), false);
|
||||||
ability.addEffect(new TidebinderMageEffect());
|
ability.addEffect(new DontUntapInControllersUntapStepTargetEffect(Duration.WhileControlled));
|
||||||
Target target = new TargetCreaturePermanent(filter);
|
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||||
ability.addTarget(target);
|
this.addAbility(ability);
|
||||||
this.addAbility(ability, new TidebinderMageWatcher());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TidebinderMage(final TidebinderMage card) {
|
private TidebinderMage(final TidebinderMage card) {
|
||||||
|
@ -68,90 +61,3 @@ public final class TidebinderMage extends CardImpl {
|
||||||
return new TidebinderMage(this);
|
return new TidebinderMage(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TidebinderMageEffect extends ContinuousRuleModifyingEffectImpl {
|
|
||||||
|
|
||||||
public TidebinderMageEffect() {
|
|
||||||
super(Duration.OneUse, Outcome.Detriment, false, false);
|
|
||||||
this.staticText = "That creature doesn't untap during its controller's untap step for as long as you control {this}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public TidebinderMageEffect(final TidebinderMageEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TidebinderMageEffect copy() {
|
|
||||||
return new TidebinderMageEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
|
||||||
// Source must be on the battlefield (it's neccessary to check here because if as response to the enter
|
|
||||||
// the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL
|
|
||||||
// event will happen before this effect is applied ever)
|
|
||||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
|
||||||
if (sourcePermanent == null || !sourcePermanent.isControlledBy(source.getControllerId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (event.getType() == GameEvent.EventType.LOST_CONTROL) {
|
|
||||||
if (event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent)event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) {
|
|
||||||
if (event.getTargetId().equals(targetPointer.getFirst(game, source))) {
|
|
||||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
|
||||||
if (permanent != null && game.isActivePlayer(permanent.getControllerId())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TidebinderMageWatcher extends Watcher {
|
|
||||||
|
|
||||||
TidebinderMageWatcher () {
|
|
||||||
super(WatcherScope.CARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void watch(GameEvent event, Game game) {
|
|
||||||
if (event.getType() == GameEvent.EventType.LOST_CONTROL
|
|
||||||
&& event.getPlayerId().equals(controllerId)
|
|
||||||
&& event.getTargetId().equals(sourceId)) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(sourceId)) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent)event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
//don't reset condition each turn - only when this leaves the battlefield
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,35 +1,25 @@
|
||||||
|
|
||||||
package mage.cards.t;
|
package mage.cards.t;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.abilities.Ability;
|
|
||||||
import mage.abilities.common.SagaAbility;
|
import mage.abilities.common.SagaAbility;
|
||||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
|
||||||
import mage.abilities.effects.Effects;
|
import mage.abilities.effects.Effects;
|
||||||
|
import mage.abilities.effects.common.DontUntapInControllersUntapStepTargetEffect;
|
||||||
import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect;
|
import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect;
|
||||||
import mage.abilities.effects.common.TapTargetEffect;
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.PhaseStep;
|
|
||||||
import mage.constants.SagaChapter;
|
import mage.constants.SagaChapter;
|
||||||
import mage.constants.WatcherScope;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.filter.predicate.permanent.TappedPredicate;
|
import mage.filter.predicate.permanent.TappedPredicate;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.game.events.ZoneChangeEvent;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.watchers.Watcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public final class TimeOfIce extends CardImpl {
|
public final class TimeOfIce extends CardImpl {
|
||||||
|
@ -51,7 +41,7 @@ public final class TimeOfIce extends CardImpl {
|
||||||
// I, II — Tap target creature an opponent controls. It doesn't untap during its controller's untap step for as long as you control Time of Ice.
|
// I, II — Tap target creature an opponent controls. It doesn't untap during its controller's untap step for as long as you control Time of Ice.
|
||||||
Effects effects = new Effects();
|
Effects effects = new Effects();
|
||||||
effects.add(new TapTargetEffect());
|
effects.add(new TapTargetEffect());
|
||||||
effects.add(new TimeOfIceEffect());
|
effects.add(new DontUntapInControllersUntapStepTargetEffect(Duration.WhileControlled, "It"));
|
||||||
sagaAbility.addChapterEffect(
|
sagaAbility.addChapterEffect(
|
||||||
this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, effects,
|
this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, effects,
|
||||||
new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)
|
new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)
|
||||||
|
@ -59,7 +49,7 @@ public final class TimeOfIce extends CardImpl {
|
||||||
|
|
||||||
// III — Return all tapped creatures to their owners' hands.
|
// III — Return all tapped creatures to their owners' hands.
|
||||||
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ReturnToHandFromBattlefieldAllEffect(filter));
|
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ReturnToHandFromBattlefieldAllEffect(filter));
|
||||||
this.addAbility(sagaAbility, new TimeOfIceWatcher());
|
this.addAbility(sagaAbility);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimeOfIce(final TimeOfIce card) {
|
private TimeOfIce(final TimeOfIce card) {
|
||||||
|
@ -71,101 +61,3 @@ public final class TimeOfIce extends CardImpl {
|
||||||
return new TimeOfIce(this);
|
return new TimeOfIce(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TimeOfIceEffect extends ContinuousRuleModifyingEffectImpl {
|
|
||||||
|
|
||||||
public TimeOfIceEffect() {
|
|
||||||
super(Duration.Custom, Outcome.Detriment, false, false);
|
|
||||||
this.staticText = "That creature doesn't untap during its controller's untap step for as long as you control {this}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeOfIceEffect(final TimeOfIceEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeOfIceEffect copy() {
|
|
||||||
return new TimeOfIceEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checksEventType(GameEvent event, Game game) {
|
|
||||||
return event.getType() == GameEvent.EventType.UNTAP
|
|
||||||
|| event.getType() == GameEvent.EventType.ZONE_CHANGE
|
|
||||||
|| event.getType() == GameEvent.EventType.LOST_CONTROL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
|
||||||
// Source must be on the battlefield (it's neccessary to check here because if as response to the enter
|
|
||||||
// the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL
|
|
||||||
// event will happen before this effect is applied ever)
|
|
||||||
Permanent sourceObject = game.getPermanent(source.getSourceId());
|
|
||||||
if (sourceObject == null || sourceObject.getZoneChangeCounter(game) > source.getSourceObjectZoneChangeCounter() + 1) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
switch (event.getType()) {
|
|
||||||
case ZONE_CHANGE:
|
|
||||||
// end effect if source does a zone move
|
|
||||||
if (event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case UNTAP:
|
|
||||||
// prevent to untap the target creature
|
|
||||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getTargetId().equals(targetPointer.getFirst(game, source))) {
|
|
||||||
Permanent targetCreature = game.getPermanent(targetPointer.getFirst(game, source));
|
|
||||||
if (targetCreature != null) {
|
|
||||||
return targetCreature.isControlledBy(game.getActivePlayerId());
|
|
||||||
} else {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LOST_CONTROL:
|
|
||||||
// end effect if source control is changed
|
|
||||||
if (event.getTargetId().equals(source.getSourceId())) {
|
|
||||||
discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TimeOfIceWatcher extends Watcher {
|
|
||||||
|
|
||||||
TimeOfIceWatcher() {
|
|
||||||
super(WatcherScope.CARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void watch(GameEvent event, Game game) {
|
|
||||||
if (event.getType() == GameEvent.EventType.LOST_CONTROL
|
|
||||||
&& event.getPlayerId().equals(controllerId)
|
|
||||||
&& event.getTargetId().equals(sourceId)) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(sourceId)) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
|
||||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
|
||||||
condition = true;
|
|
||||||
game.replaceEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
//don't reset condition each turn - only when this leaves the battlefield
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,14 +4,11 @@ import mage.MageInt;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
|
||||||
import mage.abilities.effects.ContinuousRuleModifyingEffect;
|
|
||||||
import mage.abilities.effects.EntersBattlefieldEffect;
|
import mage.abilities.effects.EntersBattlefieldEffect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect;
|
import mage.abilities.effects.common.DontUntapInControllersUntapStepTargetEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
import mage.abilities.effects.common.TapTargetEffect;
|
||||||
import mage.abilities.keyword.DefenderAbility;
|
import mage.abilities.keyword.DefenderAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
@ -35,8 +32,8 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public final class WallOfStolenIdentity extends CardImpl {
|
public final class WallOfStolenIdentity extends CardImpl {
|
||||||
|
|
||||||
final static private String rule = "You may have Wall of Stolen Identity enter the battlefield as a copy of any "
|
final static private String rule = "You may have {this} enter the battlefield as a copy of any "
|
||||||
+ "creature on the battlefield, except it's a wall in addition to its other types and it has defender. "
|
+ "creature on the battlefield, except it's a Wall in addition to its other types and it has defender. "
|
||||||
+ "When you do, tap the copied creature and it doesn't untap during its "
|
+ "When you do, tap the copied creature and it doesn't untap during its "
|
||||||
+ "controller's untap step for as long as you control {this}";
|
+ "controller's untap step for as long as you control {this}";
|
||||||
|
|
||||||
|
@ -49,9 +46,9 @@ public final class WallOfStolenIdentity extends CardImpl {
|
||||||
this.toughness = new MageInt(0);
|
this.toughness = new MageInt(0);
|
||||||
|
|
||||||
// You may have Wall of Stolen Identity enter the battlefield as a copy of any creature on the battlefield, except it's a wall in addition to its other types and it has defender. When you do, tap the copied creature and it doesn't untap during its controller's untap step for as long as you control Wall of Stolen Identity.
|
// You may have Wall of Stolen Identity enter the battlefield as a copy of any creature on the battlefield, except it's a wall in addition to its other types and it has defender. When you do, tap the copied creature and it doesn't untap during its controller's untap step for as long as you control Wall of Stolen Identity.
|
||||||
Ability ability = new SimpleStaticAbility(
|
Ability ability = new SimpleStaticAbility(new EntersBattlefieldEffect(
|
||||||
new EntersBattlefieldEffect(new WallOfStolenIdentityCopyEffect(), rule, true)
|
new WallOfStolenIdentityCopyEffect(), rule, true
|
||||||
);
|
));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +64,7 @@ public final class WallOfStolenIdentity extends CardImpl {
|
||||||
|
|
||||||
class WallOfStolenIdentityCopyEffect extends OneShotEffect {
|
class WallOfStolenIdentityCopyEffect extends OneShotEffect {
|
||||||
|
|
||||||
private static final String rule2 = "When you do, tap the copied creature and it doesn't untap during its "
|
private static final String rule2 = "When you do, .";
|
||||||
+ "controller's untap step for as long as you control {this}.";
|
|
||||||
|
|
||||||
public WallOfStolenIdentityCopyEffect() {
|
public WallOfStolenIdentityCopyEffect() {
|
||||||
super(Outcome.Copy);
|
super(Outcome.Copy);
|
||||||
|
@ -115,18 +111,13 @@ class WallOfStolenIdentityCopyEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
copyFromPermanent.tap(source, game);
|
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
|
||||||
// Incredibly, you can't just add a fixed target to a continuousrulemodifyingeffect, thus the workaround.
|
new TapTargetEffect(), false, "tap the copied creature " +
|
||||||
ContinuousRuleModifyingEffect effect = new DontUntapInControllersUntapStepSourceEffect();
|
"and it doesn't untap during its controller's untap step for as long as you control {this}"
|
||||||
Ability ability = new SimpleStaticAbility(effect);
|
);
|
||||||
ContinuousEffect effect2 = new GainAbilityTargetEffect(ability, Duration.Custom);
|
ability.addEffect(new DontUntapInControllersUntapStepTargetEffect(Duration.WhileControlled));
|
||||||
ConditionalContinuousEffect conditionalEffect = new ConditionalContinuousEffect(
|
ability.getEffects().setTargetPointer(new FixedTarget(copyFromPermanent, game));
|
||||||
effect2, new WallOfStolenIdentityCondition(
|
game.fireReflexiveTriggeredAbility(ability, source);
|
||||||
source,
|
|
||||||
source.getControllerId(),
|
|
||||||
sourcePermanent.getZoneChangeCounter(game)), "");
|
|
||||||
conditionalEffect.setTargetPointer(new FixedTarget(target.getFirstTarget()));
|
|
||||||
game.addEffect(conditionalEffect, source);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,27 +126,3 @@ class WallOfStolenIdentityCopyEffect extends OneShotEffect {
|
||||||
return new WallOfStolenIdentityCopyEffect(this);
|
return new WallOfStolenIdentityCopyEffect(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WallOfStolenIdentityCondition implements Condition {
|
|
||||||
|
|
||||||
// Checks for when it leaves play or changes control
|
|
||||||
private final Ability ability;
|
|
||||||
private final UUID controllerId;
|
|
||||||
private final int zcc;
|
|
||||||
|
|
||||||
public WallOfStolenIdentityCondition(Ability ability, UUID controllerId, int zcc) {
|
|
||||||
this.ability = ability;
|
|
||||||
this.controllerId = controllerId;
|
|
||||||
this.zcc = zcc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Permanent permanentSource = game.getPermanent(ability.getSourceId());
|
|
||||||
if (permanentSource != null) {
|
|
||||||
return permanentSource.getZoneChangeCounter(game) == zcc + 1
|
|
||||||
&& permanentSource.getControllerId() == controllerId;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
package mage.cards.w;
|
package mage.cards.w;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
|
||||||
import mage.abilities.effects.Effect;
|
|
||||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
@ -16,12 +12,11 @@ import mage.constants.Zone;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTarget;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public final class Willbreaker extends CardImpl {
|
public final class Willbreaker extends CardImpl {
|
||||||
|
@ -34,11 +29,7 @@ public final class Willbreaker extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// Whenever a creature an opponent controls becomes the target of a spell or ability you control, gain control of that creature for as long as you control Willbreaker.
|
// Whenever a creature an opponent controls becomes the target of a spell or ability you control, gain control of that creature for as long as you control Willbreaker.
|
||||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
|
this.addAbility(new WillbreakerTriggeredAbility());
|
||||||
new GainControlTargetEffect(Duration.EndOfGame),
|
|
||||||
new SourceOnBattlefieldControlUnchangedCondition(), null);
|
|
||||||
effect.setText("gain control of that creature for as long as you control {this}");
|
|
||||||
this.addAbility(new WillbreakerTriggeredAbility(effect), new LostControlWatcher());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Willbreaker(final Willbreaker card) {
|
private Willbreaker(final Willbreaker card) {
|
||||||
|
@ -53,11 +44,11 @@ public final class Willbreaker extends CardImpl {
|
||||||
|
|
||||||
class WillbreakerTriggeredAbility extends TriggeredAbilityImpl {
|
class WillbreakerTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
public WillbreakerTriggeredAbility(Effect effect) {
|
WillbreakerTriggeredAbility() {
|
||||||
super(Zone.BATTLEFIELD, effect);
|
super(Zone.BATTLEFIELD, new GainControlTargetEffect(Duration.WhileControlled));
|
||||||
}
|
}
|
||||||
|
|
||||||
public WillbreakerTriggeredAbility(WillbreakerTriggeredAbility ability) {
|
private WillbreakerTriggeredAbility(final WillbreakerTriggeredAbility ability) {
|
||||||
super(ability);
|
super(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,25 +59,23 @@ class WillbreakerTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
if (isControlledBy(event.getPlayerId())) {
|
if (!isControlledBy(event.getPlayerId())) {
|
||||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
return false;
|
||||||
if (permanent != null
|
|
||||||
&& permanent.isCreature(game)) {
|
|
||||||
Player controller = game.getPlayer(getControllerId());
|
|
||||||
if (controller != null
|
|
||||||
&& controller.hasOpponent(permanent.getControllerId(), game)) {
|
|
||||||
// always call this method for FixedTargets in case it is blinked
|
|
||||||
getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||||
|
if (permanent == null || !permanent.isCreature(game)
|
||||||
|
|| !game.getOpponents(getControllerId()).contains(permanent.getControllerId())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// always call this method for FixedTargets in case it is blinked
|
||||||
|
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTriggerPhrase() {
|
public String getRule() {
|
||||||
return "Whenever a creature an opponent controls becomes the target of a spell or ability you control, ";
|
return "Whenever a creature an opponent controls becomes the target of a spell or ability you control, " +
|
||||||
|
"gain control of that creature for as long as you control {this}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
package mage.cards.w;
|
package mage.cards.w;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.common.SkipUntapOptionalAbility;
|
import mage.abilities.common.SkipUntapOptionalAbility;
|
||||||
import mage.abilities.condition.CompoundCondition;
|
|
||||||
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
|
|
||||||
import mage.abilities.condition.common.SourceTappedCondition;
|
import mage.abilities.condition.common.SourceTappedCondition;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||||
|
@ -17,13 +14,12 @@ import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author fireshoes
|
* @author fireshoes
|
||||||
*/
|
*/
|
||||||
public final class WillowSatyr extends CardImpl {
|
public final class WillowSatyr extends CardImpl {
|
||||||
|
@ -42,13 +38,13 @@ public final class WillowSatyr extends CardImpl {
|
||||||
|
|
||||||
// You may choose not to untap Willow Satyr during your untap step.
|
// You may choose not to untap Willow Satyr during your untap step.
|
||||||
this.addAbility(new SkipUntapOptionalAbility());
|
this.addAbility(new SkipUntapOptionalAbility());
|
||||||
|
|
||||||
// {tap}: Gain control of target legendary creature for as long as you control Willow Satyr and Willow Satyr remains tapped.
|
// {tap}: Gain control of target legendary creature for as long as you control Willow Satyr and Willow Satyr remains tapped.
|
||||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
|
Ability ability = new SimpleActivatedAbility(new ConditionalContinuousEffect(
|
||||||
new GainControlTargetEffect(Duration.Custom), new CompoundCondition(SourceTappedCondition.instance, new SourceOnBattlefieldControlUnchangedCondition()),
|
new GainControlTargetEffect(Duration.WhileControlled), SourceTappedCondition.instance,
|
||||||
"Gain control of target legendary creature for as long as you control {this} and {this} remains tapped");
|
"Gain control of target legendary creature for as long as you control {this} and {this} remains tapped"
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
|
), new TapSourceCost());
|
||||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||||
ability.addWatcher(new LostControlWatcher());
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ public final class KamigawaNeonDynasty extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Kaito Shizuki", 226, Rarity.MYTHIC, mage.cards.k.KaitoShizuki.class));
|
cards.add(new SetCardInfo("Kaito Shizuki", 226, Rarity.MYTHIC, mage.cards.k.KaitoShizuki.class));
|
||||||
cards.add(new SetCardInfo("Kappa Tech-Wrecker", 198, Rarity.UNCOMMON, mage.cards.k.KappaTechWrecker.class));
|
cards.add(new SetCardInfo("Kappa Tech-Wrecker", 198, Rarity.UNCOMMON, mage.cards.k.KappaTechWrecker.class));
|
||||||
cards.add(new SetCardInfo("Kodama of the West Tree", 199, Rarity.MYTHIC, mage.cards.k.KodamaOfTheWestTree.class));
|
cards.add(new SetCardInfo("Kodama of the West Tree", 199, Rarity.MYTHIC, mage.cards.k.KodamaOfTheWestTree.class));
|
||||||
|
cards.add(new SetCardInfo("Kyodai, Soul of Kamigawa", 23, Rarity.RARE, mage.cards.k.KyodaiSoulOfKamigawa.class));
|
||||||
cards.add(new SetCardInfo("Leech Gauntlet", 106, Rarity.UNCOMMON, mage.cards.l.LeechGauntlet.class));
|
cards.add(new SetCardInfo("Leech Gauntlet", 106, Rarity.UNCOMMON, mage.cards.l.LeechGauntlet.class));
|
||||||
cards.add(new SetCardInfo("Lion Sash", 26, Rarity.RARE, mage.cards.l.LionSash.class));
|
cards.add(new SetCardInfo("Lion Sash", 26, Rarity.RARE, mage.cards.l.LionSash.class));
|
||||||
cards.add(new SetCardInfo("Lizard Blades", 153, Rarity.RARE, mage.cards.l.LizardBlades.class));
|
cards.add(new SetCardInfo("Lizard Blades", 153, Rarity.RARE, mage.cards.l.LizardBlades.class));
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
package org.mage.test.cards.single.m12;
|
||||||
|
|
||||||
|
import mage.abilities.keyword.IndestructibleAbility;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public class AegisAngelTest extends CardTestPlayerBase {
|
||||||
|
private static final String angel = "Aegis Angel";
|
||||||
|
private static final String lion = "Silvercoat Lion";
|
||||||
|
private static final String murder = "Murder";
|
||||||
|
private static final String act = "Act of Treason";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGainsAbility() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 6);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, lion);
|
||||||
|
addCard(Zone.HAND, playerA, angel);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, angel);
|
||||||
|
addTarget(playerA, lion);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
|
assertAbility(playerA, lion, IndestructibleAbility.getInstance(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeepsAbility() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 6);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, lion);
|
||||||
|
addCard(Zone.HAND, playerA, angel);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, angel);
|
||||||
|
addTarget(playerA, lion);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(3, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
|
assertAbility(playerA, lion, IndestructibleAbility.getInstance(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAngelDiesBeforeEntering() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Scrubland", 9);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, lion);
|
||||||
|
addCard(Zone.HAND, playerA, angel);
|
||||||
|
addCard(Zone.HAND, playerA, murder);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, angel);
|
||||||
|
addTarget(playerA, lion);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, murder, angel);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, angel, 1);
|
||||||
|
assertGraveyardCount(playerA, murder, 1);
|
||||||
|
assertAbility(playerA, lion, IndestructibleAbility.getInstance(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAngelDiesAfterEntering() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Scrubland", 9);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, lion);
|
||||||
|
addCard(Zone.HAND, playerA, angel);
|
||||||
|
addCard(Zone.HAND, playerA, murder);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, angel);
|
||||||
|
addTarget(playerA, lion);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, murder, angel);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, angel, 1);
|
||||||
|
assertGraveyardCount(playerA, murder, 1);
|
||||||
|
assertAbility(playerA, lion, IndestructibleAbility.getInstance(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAngelLoseControl() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 6);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 6);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, lion);
|
||||||
|
addCard(Zone.HAND, playerA, angel);
|
||||||
|
addCard(Zone.HAND, playerB, act);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, angel);
|
||||||
|
addTarget(playerA, lion);
|
||||||
|
|
||||||
|
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, act, angel);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(2, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerB, act, 1);
|
||||||
|
assertPermanentCount(playerB, angel, 1);
|
||||||
|
assertAbility(playerA, lion, IndestructibleAbility.getInstance(), false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,43 +0,0 @@
|
||||||
package mage.abilities.condition.common;
|
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
|
||||||
import mage.abilities.condition.Condition;
|
|
||||||
import mage.game.Game;
|
|
||||||
import mage.watchers.common.LostControlWatcher;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This condition checks if ever since first call of the apply method the
|
|
||||||
* controller of the source has changed
|
|
||||||
*
|
|
||||||
* Monitoring the LOST_CONTROL event has the advantage that also all layered
|
|
||||||
* effects can correctly check for controller change because comparing old and
|
|
||||||
* new controller during their apply time does not take into account layered
|
|
||||||
* change control effects that will be applied later.
|
|
||||||
*
|
|
||||||
* This condition needs the LostControlWatcher, so be sure to add it to the card
|
|
||||||
* that uses the condition.
|
|
||||||
*
|
|
||||||
* @author LevelX2
|
|
||||||
*/
|
|
||||||
public class SourceOnBattlefieldControlUnchangedCondition implements Condition {
|
|
||||||
|
|
||||||
private Long checkingSince;
|
|
||||||
private int startingZoneChangeCounter;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
if (checkingSince == null) {
|
|
||||||
checkingSince = System.currentTimeMillis() - 1;
|
|
||||||
startingZoneChangeCounter = game.getState().getZoneChangeCounter(source.getSourceId());
|
|
||||||
}
|
|
||||||
if (game.getState().getZoneChangeCounter(source.getSourceId()) > startingZoneChangeCounter) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LostControlWatcher watcher = game.getState().getWatcher(LostControlWatcher.class);
|
|
||||||
if (watcher != null) {
|
|
||||||
return checkingSince > watcher.getOrderOfLastLostControl(source.getSourceId());
|
|
||||||
}
|
|
||||||
throw new UnsupportedOperationException("LostControlWatcher not found!");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -104,8 +104,13 @@ public class ConditionalContinuousEffect extends ContinuousEffectImpl {
|
||||||
if (!conditionState && effect.getDuration() == Duration.OneUse) {
|
if (!conditionState && effect.getDuration() == Duration.OneUse) {
|
||||||
used = true;
|
used = true;
|
||||||
}
|
}
|
||||||
if (!conditionState && effect.getDuration() == Duration.Custom) {
|
switch (effect.getDuration()) {
|
||||||
this.discard();
|
case OneUse:
|
||||||
|
used = true;
|
||||||
|
break;
|
||||||
|
case Custom:
|
||||||
|
case WhileControlled:
|
||||||
|
this.discard();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -123,11 +128,13 @@ public class ConditionalContinuousEffect extends ContinuousEffectImpl {
|
||||||
otherwiseEffect.setTargetPointer(this.targetPointer);
|
otherwiseEffect.setTargetPointer(this.targetPointer);
|
||||||
return otherwiseEffect.apply(game, source);
|
return otherwiseEffect.apply(game, source);
|
||||||
}
|
}
|
||||||
if (effect.getDuration() == Duration.OneUse) {
|
switch (effect.getDuration()) {
|
||||||
used = true;
|
case OneUse:
|
||||||
}
|
used = true;
|
||||||
if (effect.getDuration() == Duration.Custom) {
|
break;
|
||||||
this.discard();
|
case Custom:
|
||||||
|
case WhileControlled:
|
||||||
|
this.discard();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +183,8 @@ public class ConditionalContinuousEffect extends ContinuousEffectImpl {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all effects list, for tests only
|
* Return all effects list, for tests only
|
||||||
* @return
|
*
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<ContinuousEffect> getAllEffects() {
|
public List<ContinuousEffect> getAllEffects() {
|
||||||
List<ContinuousEffect> res = new ArrayList<>();
|
List<ContinuousEffect> res = new ArrayList<>();
|
||||||
|
|
|
@ -177,6 +177,7 @@ public class ContinuousEffects implements Serializable {
|
||||||
for (ContinuousEffect effect : layeredEffects) {
|
for (ContinuousEffect effect : layeredEffects) {
|
||||||
switch (effect.getDuration()) {
|
switch (effect.getDuration()) {
|
||||||
case WhileOnBattlefield:
|
case WhileOnBattlefield:
|
||||||
|
case WhileControlled:
|
||||||
case WhileOnStack:
|
case WhileOnStack:
|
||||||
case WhileInGraveyard:
|
case WhileInGraveyard:
|
||||||
Set<Ability> abilities = layeredEffects.getAbility(effect.getId());
|
Set<Ability> abilities = layeredEffects.getAbility(effect.getId());
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package mage.abilities.effects;
|
package mage.abilities.effects;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.MageSingleton;
|
import mage.abilities.MageSingleton;
|
||||||
|
@ -8,9 +7,12 @@ import mage.cards.Card;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param <T>
|
* @param <T>
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
@ -145,6 +147,12 @@ public class ContinuousEffectsList<T extends ContinuousEffect> extends ArrayList
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Custom:
|
case Custom:
|
||||||
|
case UntilYourNextTurn:
|
||||||
|
case UntilEndOfYourNextTurn:
|
||||||
|
// until your turn effects continue until real turn reached, their used it's own inactive method
|
||||||
|
// 514.2 Second, the following actions happen simultaneously: all damage marked on permanents
|
||||||
|
// (including phased-out permanents) is removed and all "until end of turn" and "this turn" effects end.
|
||||||
|
// This turn-based action doesn’t use the stack.
|
||||||
// custom effects must process it's own inactive method (override)
|
// custom effects must process it's own inactive method (override)
|
||||||
// custom effects may not end, if the source permanent of the effect has left the game
|
// custom effects may not end, if the source permanent of the effect has left the game
|
||||||
// 800.4a (only any effects which give that player control of any objects or players end)
|
// 800.4a (only any effects which give that player control of any objects or players end)
|
||||||
|
@ -156,18 +164,14 @@ public class ContinuousEffectsList<T extends ContinuousEffect> extends ArrayList
|
||||||
// end of turn discards on cleanup steps
|
// end of turn discards on cleanup steps
|
||||||
// 514.2
|
// 514.2
|
||||||
break;
|
break;
|
||||||
case UntilYourNextTurn:
|
case UntilSourceLeavesBattlefield:
|
||||||
case UntilEndOfYourNextTurn:
|
if (hasOwnerLeftGame || game.getState().getZone(ability.getSourceId()) != Zone.BATTLEFIELD) {
|
||||||
// until your turn effects continue until real turn reached, their used it's own inactive method
|
|
||||||
// 514.2 Second, the following actions happen simultaneously: all damage marked on permanents
|
|
||||||
// (including phased-out permanents) is removed and all "until end of turn" and "this turn" effects end.
|
|
||||||
// This turn-based action doesn’t use the stack.
|
|
||||||
if (effect.isInactive(ability, game)) {
|
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UntilSourceLeavesBattlefield:
|
case WhileControlled:
|
||||||
if (hasOwnerLeftGame || Zone.BATTLEFIELD != game.getState().getZone(ability.getSourceId())) {
|
Permanent permanent = ability.getSourcePermanentIfItStillExists(game);
|
||||||
|
if (hasOwnerLeftGame || permanent == null || !permanent.isControlledBy(ability.getControllerId())) {
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package mage.abilities.effects.common;
|
package mage.abilities.effects.common;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageObject;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.Mode;
|
import mage.abilities.Mode;
|
||||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
||||||
|
@ -12,18 +10,27 @@ import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class DontUntapInControllersUntapStepTargetEffect extends ContinuousRuleModifyingEffectImpl {
|
public class DontUntapInControllersUntapStepTargetEffect extends ContinuousRuleModifyingEffectImpl {
|
||||||
|
|
||||||
|
private final String targetName;
|
||||||
|
|
||||||
public DontUntapInControllersUntapStepTargetEffect(Duration duration) {
|
public DontUntapInControllersUntapStepTargetEffect(Duration duration) {
|
||||||
|
this(duration, "That creature");
|
||||||
|
}
|
||||||
|
|
||||||
|
public DontUntapInControllersUntapStepTargetEffect(Duration duration, String targetName) {
|
||||||
super(duration, Outcome.Detriment);
|
super(duration, Outcome.Detriment);
|
||||||
|
this.targetName = targetName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DontUntapInControllersUntapStepTargetEffect(final DontUntapInControllersUntapStepTargetEffect effect) {
|
public DontUntapInControllersUntapStepTargetEffect(final DontUntapInControllersUntapStepTargetEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
|
this.targetName = effect.targetName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -36,16 +43,6 @@ public class DontUntapInControllersUntapStepTargetEffect extends ContinuousRuleM
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
|
||||||
Permanent permanentToUntap = game.getPermanent((event.getTargetId()));
|
|
||||||
if (permanentToUntap != null && mageObject != null) {
|
|
||||||
return permanentToUntap.getIdName() + " doesn't untap (" + mageObject.getIdName() + ')';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checksEventType(GameEvent event, Game game) {
|
public boolean checksEventType(GameEvent event, Game game) {
|
||||||
return event.getType() == GameEvent.EventType.UNTAP;
|
return event.getType() == GameEvent.EventType.UNTAP;
|
||||||
|
@ -53,14 +50,16 @@ public class DontUntapInControllersUntapStepTargetEffect extends ContinuousRuleM
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP) {
|
if (game.getTurn().getStepType() != PhaseStep.UNTAP) {
|
||||||
for (UUID targetId : targetPointer.getTargets(game, source)) {
|
return false;
|
||||||
if (event.getTargetId().equals(targetId)) {
|
}
|
||||||
Permanent permanent = game.getPermanent(targetId);
|
for (UUID targetId : targetPointer.getTargets(game, source)) {
|
||||||
if (permanent != null && game.isActivePlayer(permanent.getControllerId())) {
|
if (!event.getTargetId().equals(targetId)) {
|
||||||
return true;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
Permanent permanent = game.getPermanent(targetId);
|
||||||
|
if (permanent != null && game.isActivePlayer(permanent.getControllerId())) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -68,11 +67,11 @@ public class DontUntapInControllersUntapStepTargetEffect extends ContinuousRuleM
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getText(Mode mode) {
|
public String getText(Mode mode) {
|
||||||
if (staticText != null) {
|
if (staticText != null && !staticText.isEmpty()) {
|
||||||
return staticText;
|
return staticText;
|
||||||
}
|
}
|
||||||
return "target " + mode.getTargets().get(0).getTargetName()
|
return targetName + " doesn't untap during its controller's untap step"
|
||||||
+ " doesn't untap during its controller's untap step" + (getDuration().toString().isEmpty() ? "" : " " + getDuration());
|
+ (getDuration().toString().isEmpty() ? "" : " ") + getDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ public enum Duration {
|
||||||
OneUse("", true, true),
|
OneUse("", true, true),
|
||||||
EndOfGame("for the rest of the game", false, false),
|
EndOfGame("for the rest of the game", false, false),
|
||||||
WhileOnBattlefield("", false, false),
|
WhileOnBattlefield("", false, false),
|
||||||
|
WhileControlled("for as long as you control {this}", true, false),
|
||||||
WhileOnStack("", false, true),
|
WhileOnStack("", false, true),
|
||||||
WhileInGraveyard("", false, false),
|
WhileInGraveyard("", false, false),
|
||||||
EndOfTurn("until end of turn", true, true),
|
EndOfTurn("until end of turn", true, true),
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package mage.watchers.common;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.constants.WatcherScope;
|
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.watchers.Watcher;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author LevelX2
|
|
||||||
*/
|
|
||||||
public class LostControlWatcher extends Watcher {
|
|
||||||
|
|
||||||
private final Map<UUID, Long> lastLostControl = new HashMap<>();
|
|
||||||
|
|
||||||
public LostControlWatcher() {
|
|
||||||
super(WatcherScope.GAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void watch(GameEvent event, Game game) {
|
|
||||||
if (event.getType() == GameEvent.EventType.LOST_CONTROL) {
|
|
||||||
lastLostControl.put(event.getTargetId(), System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
super.reset();
|
|
||||||
lastLostControl.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getOrderOfLastLostControl(UUID sourceId) {
|
|
||||||
return lastLostControl.getOrDefault(sourceId, new Long(0));
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue