[SNC] Implemented Endless Detour

This commit is contained in:
Evan Kranzler 2022-04-19 18:40:45 -04:00
parent 342eabbfa7
commit 9ead88bacb
19 changed files with 261 additions and 428 deletions

View file

@ -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";
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}