mirror of
https://github.com/correl/mage.git
synced 2024-11-14 19:19:32 +00:00
[SNC] Implemented Endless Detour
This commit is contained in:
parent
342eabbfa7
commit
9ead88bacb
19 changed files with 261 additions and 428 deletions
|
@ -542,7 +542,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
// Angel of Serenity trigger
|
||||
if (target.getOriginalTarget() instanceof TargetCardInGraveyardOrBattlefield) {
|
||||
if (target.getOriginalTarget() instanceof TargetCardInGraveyardBattlefieldOrStack) {
|
||||
Cards cards = new CardsImpl(possibleTargets);
|
||||
List<Card> possibleCards = new ArrayList<>(cards.getCards(game));
|
||||
for (Card card : possibleCards) {
|
||||
|
@ -1043,7 +1043,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
return target.isChosen();
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetCardInGraveyardOrBattlefield) {
|
||||
if (target.getOriginalTarget() instanceof TargetCardInGraveyardBattlefieldOrStack) {
|
||||
List<Card> cards = new ArrayList<>();
|
||||
for (Player player : game.getPlayers().values()) {
|
||||
cards.addAll(player.getGraveyard().getCards(game));
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
|
||||
import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.common.FilterSpellOrPermanent;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetSpellOrPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -25,7 +21,7 @@ public final class AetherGust extends CardImpl {
|
|||
|
||||
private static final FilterSpellOrPermanent filter
|
||||
= new FilterSpellOrPermanent("spell or permanent that's red or green");
|
||||
private static final Predicate predicate = Predicates.or(
|
||||
private static final Predicate<MageObject> predicate = Predicates.or(
|
||||
new ColorPredicate(ObjectColor.RED),
|
||||
new ColorPredicate(ObjectColor.GREEN)
|
||||
);
|
||||
|
@ -39,8 +35,11 @@ public final class AetherGust extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
|
||||
|
||||
// Choose target spell or permanent that's red or green. Its owner puts it on the top or bottom of their library.
|
||||
this.getSpellAbility().addEffect(new AetherGustEffect());
|
||||
this.getSpellAbility().addTarget(new TargetSpellOrPermanent(1, 1, filter, false));
|
||||
this.getSpellAbility().addEffect(new PutOnTopOrBottomLibraryTargetEffect(
|
||||
"choose target spell or permanent that's red or green. " +
|
||||
"Its owner puts it on the top or bottom of their library"
|
||||
));
|
||||
this.getSpellAbility().addTarget(new TargetSpellOrPermanent(filter));
|
||||
}
|
||||
|
||||
private AetherGust(final AetherGust card) {
|
||||
|
@ -52,34 +51,3 @@ public final class AetherGust extends CardImpl {
|
|||
return new AetherGust(this);
|
||||
}
|
||||
}
|
||||
|
||||
class AetherGustEffect extends OneShotEffect {
|
||||
|
||||
AetherGustEffect() {
|
||||
super(Outcome.Removal);
|
||||
staticText = "Choose target spell or permanent that's red or green. " +
|
||||
"Its owner puts it on the top or bottom of their library.";
|
||||
}
|
||||
|
||||
private AetherGustEffect(final AetherGustEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AetherGustEffect copy() {
|
||||
return new AetherGustEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(game.getOwnerId(source.getFirstTarget()));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.chooseUse(Outcome.Detriment, "Put the targeted object on the top or bottom of your library?",
|
||||
"", "Top", "Bottom", source, game)) {
|
||||
return new PutOnLibraryTargetEffect(true).apply(game, source);
|
||||
}
|
||||
return new PutOnLibraryTargetEffect(false).apply(game, source);
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ import mage.constants.CardType;
|
|||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||
import mage.target.common.TargetCardInGraveyardOrBattlefield;
|
||||
import mage.target.common.TargetCardInGraveyardBattlefieldOrStack;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
|
@ -49,7 +49,7 @@ public final class AngelOfSerenity extends CardImpl {
|
|||
Ability ability = new EntersBattlefieldTriggeredAbility(
|
||||
new ExileTargetForSourceEffect().setText(rule), true
|
||||
);
|
||||
ability.addTarget(new TargetCardInGraveyardOrBattlefield(
|
||||
ability.addTarget(new TargetCardInGraveyardBattlefieldOrStack(
|
||||
0, 3, filterCreatureCard, filterCreaturePermanent
|
||||
));
|
||||
this.addAbility(ability);
|
||||
|
|
|
@ -17,7 +17,7 @@ import mage.filter.StaticFilters;
|
|||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.permanent.token.DarettiConstructToken;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCardInGraveyardOrBattlefield;
|
||||
import mage.target.common.TargetCardInGraveyardBattlefieldOrStack;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -65,7 +65,7 @@ public final class DarettiIngeniousIconoclast extends CardImpl {
|
|||
.setText("Choose target artifact card in a graveyard or artifact on the battlefield. " +
|
||||
"Create three tokens that are copies of it"), -6
|
||||
);
|
||||
ability.addTarget(new TargetCardInGraveyardOrBattlefield(1, 1,
|
||||
ability.addTarget(new TargetCardInGraveyardBattlefieldOrStack(1, 1,
|
||||
StaticFilters.FILTER_CARD_ARTIFACT, StaticFilters.FILTER_PERMANENT_ARTIFACT));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
|
|
@ -3,16 +3,12 @@ package mage.cards.d;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.ExploitCreatureTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
|
||||
import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect;
|
||||
import mage.abilities.keyword.ExploitAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -33,7 +29,9 @@ public final class DiverSkaab extends CardImpl {
|
|||
this.addAbility(new ExploitAbility());
|
||||
|
||||
// When Diver Skaab exploits a creature, target creature's owner puts it on the top or bottom of their library.
|
||||
Ability ability = new ExploitCreatureTriggeredAbility(new DiverSkaabEffect());
|
||||
Ability ability = new ExploitCreatureTriggeredAbility(new PutOnTopOrBottomLibraryTargetEffect(
|
||||
"target creature's owner puts it on the top or bottom of their library"
|
||||
));
|
||||
ability.addTarget(new TargetCreaturePermanent());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
@ -47,33 +45,3 @@ public final class DiverSkaab extends CardImpl {
|
|||
return new DiverSkaab(this);
|
||||
}
|
||||
}
|
||||
|
||||
class DiverSkaabEffect extends OneShotEffect {
|
||||
|
||||
DiverSkaabEffect() {
|
||||
super(Outcome.Removal);
|
||||
staticText = "target creature's owner puts it on the top or bottom of their library";
|
||||
}
|
||||
|
||||
private DiverSkaabEffect(final DiverSkaabEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiverSkaabEffect copy() {
|
||||
return new DiverSkaabEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(game.getOwnerId(source.getFirstTarget()));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.chooseUse(Outcome.Detriment, "Put the targeted object on the top or bottom of your library?",
|
||||
"", "Top", "Bottom", source, game)) {
|
||||
return new PutOnLibraryTargetEffect(true).apply(game, source);
|
||||
}
|
||||
return new PutOnLibraryTargetEffect(false).apply(game, source);
|
||||
}
|
||||
}
|
||||
|
|
36
Mage.Sets/src/mage/cards/e/EndlessDetour.java
Normal file
36
Mage.Sets/src/mage/cards/e/EndlessDetour.java
Normal file
|
@ -0,0 +1,36 @@
|
|||
package mage.cards.e;
|
||||
|
||||
import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.target.common.TargetCardInGraveyardBattlefieldOrStack;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class EndlessDetour extends CardImpl {
|
||||
|
||||
public EndlessDetour(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}{W}{U}");
|
||||
|
||||
// The owner of target spell, nonland permanent, or card in a graveyard puts it on the top or bottom of their library.
|
||||
this.getSpellAbility().addEffect(new PutOnTopOrBottomLibraryTargetEffect());
|
||||
this.getSpellAbility().addTarget(new TargetCardInGraveyardBattlefieldOrStack(
|
||||
1, 1, StaticFilters.FILTER_CARD, StaticFilters.FILTER_PERMANENT_NON_LAND,
|
||||
StaticFilters.FILTER_SPELL, "spell, nonland permanent, or card in a graveyard"
|
||||
));
|
||||
}
|
||||
|
||||
private EndlessDetour(final EndlessDetour card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EndlessDetour copy() {
|
||||
return new EndlessDetour(this);
|
||||
}
|
||||
}
|
|
@ -2,19 +2,15 @@ package mage.cards.m;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.common.TapTargetCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
|
||||
import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect;
|
||||
import mage.abilities.keyword.ChannelAbility;
|
||||
import mage.abilities.mana.ColorlessManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.permanent.TappedPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.common.TargetNonlandPermanent;
|
||||
|
||||
|
@ -45,7 +41,7 @@ public final class MoonsnarePrototype extends CardImpl {
|
|||
this.addAbility(ability);
|
||||
|
||||
// Channel — {4}{U}, Discard Moonsnare Prototype: The owner of target nonland permanent puts it on the top or bottom of their library.
|
||||
ability = new ChannelAbility("{4}{U}", new MoonsnarePrototypeEffect());
|
||||
ability = new ChannelAbility("{4}{U}", new PutOnTopOrBottomLibraryTargetEffect());
|
||||
ability.addTarget(new TargetNonlandPermanent());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
@ -59,33 +55,3 @@ public final class MoonsnarePrototype extends CardImpl {
|
|||
return new MoonsnarePrototype(this);
|
||||
}
|
||||
}
|
||||
|
||||
class MoonsnarePrototypeEffect extends OneShotEffect {
|
||||
|
||||
MoonsnarePrototypeEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "the owner of target nonland permanent puts it on the top or bottom of their library";
|
||||
}
|
||||
|
||||
private MoonsnarePrototypeEffect(final MoonsnarePrototypeEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MoonsnarePrototypeEffect copy() {
|
||||
return new MoonsnarePrototypeEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(game.getOwnerId(source.getFirstTarget()));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.chooseUse(Outcome.Detriment, "Put the targeted object on the top or bottom of your library?",
|
||||
"", "Top", "Bottom", source, game)) {
|
||||
return new PutOnLibraryTargetEffect(true).apply(game, source);
|
||||
}
|
||||
return new PutOnLibraryTargetEffect(false).apply(game, source);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package mage.cards.p;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
|
||||
import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect;
|
||||
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
||||
import mage.abilities.effects.common.RollDieWithResultTableEffect;
|
||||
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||
|
@ -10,9 +8,6 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetOpponentsCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -36,7 +31,9 @@ public final class PowerOfPersuasion extends CardImpl {
|
|||
effect.addTableEntry(1, 9, new ReturnToHandTargetEffect().setText("return it to its owner's hand"));
|
||||
|
||||
// 10-19 | Its owner puts it on the top of bottom of their library.
|
||||
effect.addTableEntry(10, 19, new PowerOfPersuasionEffect());
|
||||
effect.addTableEntry(10, 19, new PutOnTopOrBottomLibraryTargetEffect(
|
||||
"its owner puts it on the top of bottom of their library"
|
||||
));
|
||||
|
||||
// 20 | Gain control of it until the end of your next turn.
|
||||
effect.addTableEntry(20, 20, new GainControlTargetEffect(
|
||||
|
@ -53,33 +50,3 @@ public final class PowerOfPersuasion extends CardImpl {
|
|||
return new PowerOfPersuasion(this);
|
||||
}
|
||||
}
|
||||
|
||||
class PowerOfPersuasionEffect extends OneShotEffect {
|
||||
|
||||
PowerOfPersuasionEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "its owner puts it on the top or bottom of their library";
|
||||
}
|
||||
|
||||
private PowerOfPersuasionEffect(final PowerOfPersuasionEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PowerOfPersuasionEffect copy() {
|
||||
return new PowerOfPersuasionEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(game.getOwnerId(source.getFirstTarget()));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.chooseUse(Outcome.Detriment, "Put the targeted object on the top or bottom of your library?",
|
||||
"", "Top", "Bottom", source, game)) {
|
||||
return new PutOnLibraryTargetEffect(true).apply(game, source);
|
||||
}
|
||||
return new PutOnLibraryTargetEffect(false).apply(game, source);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
|
||||
import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.token.ZombieDecayedToken;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -24,7 +19,9 @@ public final class RevengeOfTheDrowned extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}");
|
||||
|
||||
// Target creature's owner puts it on the top or bottom of their library. You create a 2/2 black Zombie creature token with decayed.
|
||||
this.getSpellAbility().addEffect(new RevengeOfTheDrownedEffect());
|
||||
this.getSpellAbility().addEffect(new PutOnTopOrBottomLibraryTargetEffect(
|
||||
"target creature's owner puts it on the top or bottom of their library"
|
||||
));
|
||||
this.getSpellAbility().addEffect(new CreateTokenEffect(new ZombieDecayedToken()).concatBy("You"));
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
}
|
||||
|
@ -38,33 +35,3 @@ public final class RevengeOfTheDrowned extends CardImpl {
|
|||
return new RevengeOfTheDrowned(this);
|
||||
}
|
||||
}
|
||||
|
||||
class RevengeOfTheDrownedEffect extends OneShotEffect {
|
||||
|
||||
RevengeOfTheDrownedEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "target creature's owner puts it on the top or bottom of their library.";
|
||||
}
|
||||
|
||||
private RevengeOfTheDrownedEffect(final RevengeOfTheDrownedEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RevengeOfTheDrownedEffect copy() {
|
||||
return new RevengeOfTheDrownedEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(game.getOwnerId(source.getFirstTarget()));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.chooseUse(Outcome.Detriment, "Put the targeted object on the top or bottom of your library?",
|
||||
"", "Top", "Bottom", source, game)) {
|
||||
return new PutOnLibraryTargetEffect(true).apply(game, source);
|
||||
}
|
||||
return new PutOnLibraryTargetEffect(false).apply(game, source);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
|
||||
import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect;
|
||||
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetNonlandPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -28,7 +23,7 @@ public final class RunAshore extends CardImpl {
|
|||
this.getSpellAbility().getModes().setMaxModes(2);
|
||||
|
||||
// • The owner of target nonland permanent puts it on the top or bottom of their library.
|
||||
this.getSpellAbility().addEffect(new RunAshoreEffect());
|
||||
this.getSpellAbility().addEffect(new PutOnTopOrBottomLibraryTargetEffect());
|
||||
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
|
||||
|
||||
// • Return target nonland permanent to its owner's hand.
|
||||
|
@ -46,33 +41,3 @@ public final class RunAshore extends CardImpl {
|
|||
return new RunAshore(this);
|
||||
}
|
||||
}
|
||||
|
||||
class RunAshoreEffect extends OneShotEffect {
|
||||
|
||||
RunAshoreEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "The owner of target nonland permanent puts it on the top or bottom of their library.";
|
||||
}
|
||||
|
||||
private RunAshoreEffect(final RunAshoreEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RunAshoreEffect copy() {
|
||||
return new RunAshoreEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(game.getOwnerId(source.getFirstTarget()));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.chooseUse(Outcome.Detriment, "Put the targeted object on the top or bottom of your library?",
|
||||
"", "Top", "Bottom", source, game)) {
|
||||
return new PutOnLibraryTargetEffect(true).apply(game, source);
|
||||
}
|
||||
return new PutOnLibraryTargetEffect(false).apply(game, source);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
|
||||
import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetNonlandPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
*/
|
||||
public final class RunOutOfTown extends CardImpl {
|
||||
|
@ -23,7 +17,7 @@ public final class RunOutOfTown extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}");
|
||||
|
||||
// The owner of target nonland permanent puts it on the top or bottom of their library.
|
||||
this.getSpellAbility().addEffect(new RunOutOfTownEffect());
|
||||
this.getSpellAbility().addEffect(new PutOnTopOrBottomLibraryTargetEffect());
|
||||
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
|
||||
}
|
||||
|
||||
|
@ -36,33 +30,3 @@ public final class RunOutOfTown extends CardImpl {
|
|||
return new RunOutOfTown(this);
|
||||
}
|
||||
}
|
||||
|
||||
class RunOutOfTownEffect extends OneShotEffect {
|
||||
|
||||
public RunOutOfTownEffect() {
|
||||
super(Outcome.Removal);
|
||||
this.staticText = "The owner of target nonland permanent puts it on the top or bottom of their library";
|
||||
}
|
||||
|
||||
private RunOutOfTownEffect(final RunOutOfTownEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RunOutOfTownEffect copy() {
|
||||
return new RunOutOfTownEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(game.getOwnerId(source.getFirstTarget()));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.chooseUse(Outcome.Detriment, "Put the targeted object on the top or bottom of your library?",
|
||||
"", "Top", "Bottom", source, game)) {
|
||||
return new PutOnLibraryTargetEffect(true).apply(game, source);
|
||||
}
|
||||
return new PutOnLibraryTargetEffect(false).apply(game, source);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import mage.game.ExileZone;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInGraveyardOrBattlefield;
|
||||
import mage.target.common.TargetCardInGraveyardBattlefieldOrStack;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -60,7 +60,7 @@ class SaviorOfOllenbockTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
SaviorOfOllenbockTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new ExileTargetForSourceEffect());
|
||||
this.addTarget(new TargetCardInGraveyardOrBattlefield(
|
||||
this.addTarget(new TargetCardInGraveyardBattlefieldOrStack(
|
||||
0, 1,
|
||||
StaticFilters.FILTER_CARD_CREATURE,
|
||||
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE
|
||||
|
|
|
@ -5,22 +5,18 @@ import mage.ObjectColor;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.costs.common.ExileFromHandCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
|
||||
import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect;
|
||||
import mage.abilities.keyword.EvokeAbility;
|
||||
import mage.abilities.keyword.FlashAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetSpell;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
|
||||
|
@ -57,7 +53,10 @@ public final class Subtlety extends CardImpl {
|
|||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// When Subtlety enters the battlefield, choose up to one target creature spell or planeswalker spell. Its owner puts it on the top or bottom of their library.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new SubtletyEffect());
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new PutOnTopOrBottomLibraryTargetEffect(
|
||||
"choose up to one target creature spell or planeswalker spell. " +
|
||||
"Its owner puts it on the top or bottom of their library"
|
||||
));
|
||||
ability.addTarget(new TargetSpell(0, 1, filter));
|
||||
this.addAbility(ability);
|
||||
|
||||
|
@ -74,34 +73,3 @@ public final class Subtlety extends CardImpl {
|
|||
return new Subtlety(this);
|
||||
}
|
||||
}
|
||||
|
||||
class SubtletyEffect extends OneShotEffect {
|
||||
|
||||
SubtletyEffect() {
|
||||
super(Outcome.Removal);
|
||||
staticText = "choose up to one target creature spell or planeswalker spell. " +
|
||||
"Its owner puts it on the top or bottom of their library";
|
||||
}
|
||||
|
||||
private SubtletyEffect(final SubtletyEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubtletyEffect copy() {
|
||||
return new SubtletyEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(game.getOwnerId(source.getFirstTarget()));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.chooseUse(Outcome.Detriment, "Put the targeted spell on the top or bottom of your library?",
|
||||
"", "Top", "Bottom", source, game)) {
|
||||
return new PutOnLibraryTargetEffect(true).apply(game, source);
|
||||
}
|
||||
return new PutOnLibraryTargetEffect(false).apply(game, source);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ public final class StreetsOfNewCapenna extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Echo Inspector", 40, Rarity.COMMON, mage.cards.e.EchoInspector.class));
|
||||
cards.add(new SetCardInfo("Elegant Entourage", 143, Rarity.UNCOMMON, mage.cards.e.ElegantEntourage.class));
|
||||
cards.add(new SetCardInfo("Elspeth Resplendent", 11, Rarity.MYTHIC, mage.cards.e.ElspethResplendent.class));
|
||||
cards.add(new SetCardInfo("Endless Detour", 183, Rarity.RARE, mage.cards.e.EndlessDetour.class));
|
||||
cards.add(new SetCardInfo("Errant, Street Artist", 41, Rarity.RARE, mage.cards.e.ErrantStreetArtist.class));
|
||||
cards.add(new SetCardInfo("Evolving Door", 144, Rarity.RARE, mage.cards.e.EvolvingDoor.class));
|
||||
cards.add(new SetCardInfo("Exhibition Magician", 106, Rarity.COMMON, mage.cards.e.ExhibitionMagician.class));
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
package org.mage.test.cards.single.m20;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
@ -8,10 +6,8 @@ import org.junit.Test;
|
|||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jgray1206
|
||||
*/
|
||||
|
||||
public class AetherGustTest extends CardTestPlayerBase {
|
||||
|
||||
/* Aether Gust - Instant {1}{U}
|
||||
|
@ -70,5 +66,4 @@ public class AetherGustTest extends CardTestPlayerBase {
|
|||
assertLibraryCount(playerA, 1);
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2461,7 +2461,7 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
// card in battlefield
|
||||
if (target instanceof TargetCardInGraveyardOrBattlefield) {
|
||||
if (target instanceof TargetCardInGraveyardBattlefieldOrStack) {
|
||||
TargetCard targetFull = (TargetCard) target;
|
||||
for (String targetDefinition : targets) {
|
||||
checkTargetDefinitionMarksSupport(target, targetDefinition, "^");
|
||||
|
@ -2489,7 +2489,7 @@ public class TestPlayer implements Player {
|
|||
if (target.getOriginalTarget() instanceof TargetCardInOpponentsGraveyard
|
||||
|| target.getOriginalTarget() instanceof TargetCardInYourGraveyard
|
||||
|| target.getOriginalTarget() instanceof TargetCardInGraveyard
|
||||
|| target.getOriginalTarget() instanceof TargetCardInGraveyardOrBattlefield
|
||||
|| target.getOriginalTarget() instanceof TargetCardInGraveyardBattlefieldOrStack
|
||||
|| (target.getOriginalTarget() instanceof TargetCard && target.getOriginalTarget().getZone() == Zone.GRAVEYARD)) {
|
||||
targetCardZonesChecked.add(Zone.GRAVEYARD);
|
||||
TargetCard targetFull = (TargetCard) target.getOriginalTarget();
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class PutOnTopOrBottomLibraryTargetEffect extends OneShotEffect {
|
||||
|
||||
public PutOnTopOrBottomLibraryTargetEffect() {
|
||||
this("");
|
||||
}
|
||||
|
||||
public PutOnTopOrBottomLibraryTargetEffect(String text) {
|
||||
super(Outcome.Benefit);
|
||||
staticText = text;
|
||||
}
|
||||
|
||||
private PutOnTopOrBottomLibraryTargetEffect(final PutOnTopOrBottomLibraryTargetEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PutOnTopOrBottomLibraryTargetEffect copy() {
|
||||
return new PutOnTopOrBottomLibraryTargetEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(game.getOwnerId(source.getFirstTarget()));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
boolean onTop = player.chooseUse(
|
||||
Outcome.Detriment, "Put the targeted object on the top or bottom of your library?",
|
||||
null, "Top", "Bottom", source, game
|
||||
);
|
||||
return new PutOnLibraryTargetEffect(onTop).apply(game, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
if (staticText != null && !staticText.isEmpty()) {
|
||||
return staticText;
|
||||
}
|
||||
return "the owner of target " + mode.getTargets().get(0).getTargetName() +
|
||||
" puts it on the top or bottom of their library";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
package mage.target.common;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.ComparisonType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.game.stack.StackObject;
|
||||
import mage.target.TargetCard;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class TargetCardInGraveyardBattlefieldOrStack extends TargetCard {
|
||||
|
||||
private static final FilterSpell defaultSpellFilter = new FilterSpell();
|
||||
|
||||
static {
|
||||
defaultSpellFilter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, -1));
|
||||
}
|
||||
|
||||
protected final FilterPermanent filterPermanent;
|
||||
protected final FilterSpell filterSpell;
|
||||
|
||||
public TargetCardInGraveyardBattlefieldOrStack(int minNumTargets, int maxNumTargets, FilterCard filterGraveyard, FilterPermanent filterBattlefield) {
|
||||
this(minNumTargets, maxNumTargets, filterGraveyard, filterBattlefield, defaultSpellFilter, null);
|
||||
}
|
||||
|
||||
public TargetCardInGraveyardBattlefieldOrStack(int minNumTargets, int maxNumTargets, FilterCard filterGraveyard, FilterPermanent filterBattlefield, FilterSpell filterSpell, String targetName) {
|
||||
super(minNumTargets, maxNumTargets, Zone.GRAVEYARD, filterGraveyard); // zone for card in graveyard, don't change
|
||||
this.filterPermanent = filterBattlefield;
|
||||
this.filterSpell = filterSpell;
|
||||
this.targetName = targetName != null ? targetName : filter.getMessage()
|
||||
+ " in a graveyard "
|
||||
+ (maxNumTargets > 1 ? " and/or " : " or ")
|
||||
+ this.filterPermanent.getMessage()
|
||||
+ " on the battlefield";
|
||||
}
|
||||
|
||||
public TargetCardInGraveyardBattlefieldOrStack(final TargetCardInGraveyardBattlefieldOrStack target) {
|
||||
super(target);
|
||||
this.filterPermanent = target.filterPermanent;
|
||||
this.filterSpell = target.filterSpell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canChoose(UUID sourceControllerId, Ability source, Game game) {
|
||||
if (super.canChoose(sourceControllerId, source, game)) {
|
||||
return true;
|
||||
}
|
||||
MageObject targetSource = game.getObject(source);
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filterPermanent, sourceControllerId, source, game)) {
|
||||
if (notTarget || permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (StackObject stackObject : game.getStack()) {
|
||||
if (stackObject instanceof Spell
|
||||
&& game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getControllerId())
|
||||
&& filterSpell.match(stackObject, sourceControllerId, source, game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTarget(UUID id, Ability source, Game game) {
|
||||
return this.canTarget(source.getControllerId(), id, source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
|
||||
if (super.canTarget(playerId, id, source, game)) { // in graveyard first
|
||||
return true;
|
||||
}
|
||||
Permanent permanent = game.getPermanent(id);
|
||||
if (permanent != null) {
|
||||
return filterPermanent.match(permanent, playerId, source, game);
|
||||
}
|
||||
Spell spell = game.getSpell(id);
|
||||
return spell != null && filterSpell.match(spell, playerId, source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTarget(UUID id, Game game) {
|
||||
return this.canTarget(null, id, null, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> possibleTargets(UUID sourceControllerId, Game game) {
|
||||
return this.possibleTargets(sourceControllerId, (Ability) null, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> possibleTargets(UUID sourceControllerId, Ability source, Game game) {
|
||||
Set<UUID> possibleTargets = super.possibleTargets(sourceControllerId, source, game); // in graveyard first
|
||||
MageObject targetSource = game.getObject(source);
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filterPermanent, sourceControllerId, source, game)) {
|
||||
if (notTarget || permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) {
|
||||
possibleTargets.add(permanent.getId());
|
||||
}
|
||||
}
|
||||
for (StackObject stackObject : game.getStack()) {
|
||||
if (stackObject instanceof Spell
|
||||
&& game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getControllerId())
|
||||
&& filterSpell.match(stackObject, sourceControllerId, source, game)) {
|
||||
possibleTargets.add(stackObject.getId());
|
||||
}
|
||||
}
|
||||
return possibleTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetCardInGraveyardBattlefieldOrStack copy() {
|
||||
return new TargetCardInGraveyardBattlefieldOrStack(this);
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
package mage.target.common;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.TargetCard;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class TargetCardInGraveyardOrBattlefield extends TargetCard {
|
||||
|
||||
protected final FilterPermanent filterBattlefield;
|
||||
|
||||
public TargetCardInGraveyardOrBattlefield(int minNumTargets, int maxNumTargets, FilterCard filterGraveyard, FilterPermanent filterBattlefield) {
|
||||
super(minNumTargets, maxNumTargets, Zone.GRAVEYARD, filterGraveyard); // zone for card in graveyard, don't change
|
||||
this.filterBattlefield = filterBattlefield;
|
||||
this.targetName = filter.getMessage()
|
||||
+ " in a graveyard "
|
||||
+ (maxNumTargets > 1 ? " and/or " : " or ")
|
||||
+ this.filterBattlefield.getMessage()
|
||||
+ " on the battlefield";
|
||||
}
|
||||
|
||||
public TargetCardInGraveyardOrBattlefield(final TargetCardInGraveyardOrBattlefield target) {
|
||||
super(target);
|
||||
this.filterBattlefield = target.filterBattlefield;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canChoose(UUID sourceControllerId, Ability source, Game game) {
|
||||
if (!super.canChoose(sourceControllerId, source, game)) {
|
||||
MageObject targetSource = game.getObject(source);
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filterBattlefield, sourceControllerId, game)) {
|
||||
if ((notTarget || permanent.canBeTargetedBy(targetSource, sourceControllerId, game))
|
||||
&& filterBattlefield.match(permanent, sourceControllerId, source, game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTarget(UUID id, Ability source, Game game) {
|
||||
if (!super.canTarget(id, source, game)) { // in graveyard first
|
||||
Permanent permanent = game.getPermanent(id);
|
||||
if (permanent != null) {
|
||||
return filterBattlefield.match(permanent, source.getControllerId(), source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
|
||||
if (!super.canTarget(playerId, id, source, game)) { // in graveyard first
|
||||
Permanent permanent = game.getPermanent(id);
|
||||
if (permanent != null) {
|
||||
return filterBattlefield.match(permanent, playerId, source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTarget(UUID id, Game game) {
|
||||
if (!super.canTarget(id, game)) { // in graveyard first
|
||||
Permanent permanent = game.getPermanent(id);
|
||||
if (permanent != null) {
|
||||
return filterBattlefield.match(permanent, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> possibleTargets(UUID sourceControllerId, Game game) {
|
||||
Set<UUID> possibleTargets = super.possibleTargets(sourceControllerId, game); // in graveyard first
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filterBattlefield, sourceControllerId, game)) {
|
||||
if (filterBattlefield.match(permanent, sourceControllerId, null, game)) {
|
||||
possibleTargets.add(permanent.getId());
|
||||
}
|
||||
}
|
||||
return possibleTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> possibleTargets(UUID sourceControllerId, Ability source, Game game) {
|
||||
Set<UUID> possibleTargets = super.possibleTargets(sourceControllerId, source, game); // in graveyard first
|
||||
MageObject targetSource = game.getObject(source);
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filterBattlefield, sourceControllerId, source, game)) {
|
||||
if ((notTarget || permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) && filterBattlefield.match(permanent, sourceControllerId, source, game)) {
|
||||
possibleTargets.add(permanent.getId());
|
||||
}
|
||||
}
|
||||
return possibleTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetCardInGraveyardOrBattlefield copy() {
|
||||
return new TargetCardInGraveyardOrBattlefield(this);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue