Merge pull request #5867 from rscoates/master

Implement Tale's End.
This commit is contained in:
Oleg Agafonov 2019-06-29 15:52:56 +02:00 committed by GitHub
commit 6da95f3f6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 142 additions and 0 deletions

View file

@ -0,0 +1,35 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.effects.common.CounterTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetActivatedOrTriggeredAbilityOrLegendarySpell;
/**
*
* @author rscoates
*/
public final class TalesEnd extends CardImpl {
public TalesEnd(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Counter target activated ability, triggered ability, or legendary spell.
// Counter target activated or triggered ability.
this.getSpellAbility().addEffect(new CounterTargetEffect());
this.getSpellAbility().addTarget(new TargetActivatedOrTriggeredAbilityOrLegendarySpell());
}
private TalesEnd(final TalesEnd card) {
super(card);
}
@Override
public TalesEnd copy() {
return new TalesEnd(this);
}
}

View file

@ -297,6 +297,7 @@ public final class CoreSet2020 extends ExpansionSet {
cards.add(new SetCardInfo("Swamp", 271, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Swamp", 272, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Swiftwater Cliffs", 252, Rarity.COMMON, mage.cards.s.SwiftwaterCliffs.class));
cards.add(new SetCardInfo("Tale's End", 77, Rarity.RARE, mage.cards.t.TalesEnd.class));
cards.add(new SetCardInfo("Tectonic Rift", 161, Rarity.COMMON, mage.cards.t.TectonicRift.class));
cards.add(new SetCardInfo("Temple of Epiphany", 253, Rarity.RARE, mage.cards.t.TempleOfEpiphany.class));
cards.add(new SetCardInfo("Temple of Malady", 254, Rarity.RARE, mage.cards.t.TempleOfMalady.class));

View file

@ -0,0 +1,106 @@
package mage.target.common;
import mage.abilities.Ability;
import mage.constants.AbilityType;
import mage.constants.Zone;
import mage.filter.Filter;
import mage.filter.FilterStackObject;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.game.stack.StackObject;
import mage.target.TargetObject;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
public class TargetActivatedOrTriggeredAbilityOrLegendarySpell extends TargetObject {
protected final FilterStackObject filter;
public TargetActivatedOrTriggeredAbilityOrLegendarySpell() {
this(new FilterStackObject("activated ability, triggered ability, or legendary spell"));
}
public TargetActivatedOrTriggeredAbilityOrLegendarySpell(FilterStackObject filter) {
this.minNumberOfTargets = 1;
this.maxNumberOfTargets = 1;
this.zone = Zone.STACK;
this.targetName = filter.getMessage();
this.filter = filter;
}
public TargetActivatedOrTriggeredAbilityOrLegendarySpell(final TargetActivatedOrTriggeredAbilityOrLegendarySpell target) {
super(target);
this.filter = target.filter.copy();
}
@Override
public boolean canTarget(UUID id, Ability source, Game game) {
// rule 114.4. A spell or ability on the stack is an illegal target for itself.
if (source != null && source.getId().equals(id)) {
return false;
}
StackObject stackObject = game.getStack().getStackObject(id);
return isActivatedOrTriggeredAbilityOrLegendarySpell(stackObject) && source != null && filter.match(stackObject, source.getSourceId(), source.getControllerId(), game);
}
@Override
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
for (StackObject stackObject : game.getStack()) {
if (isActivatedOrTriggeredAbilityOrLegendarySpell(stackObject)
&& filter.match(stackObject, sourceId, sourceControllerId, game)) {
return true;
}
}
return false;
}
@Override
public boolean canChoose(UUID sourceControllerId, Game game) {
return game.getStack()
.stream()
.anyMatch(TargetActivatedOrTriggeredAbilityOrLegendarySpell::isActivatedOrTriggeredAbilityOrLegendarySpell);
}
@Override
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
return possibleTargets(sourceControllerId, game);
}
@Override
public Set<UUID> possibleTargets(UUID sourceControllerId, Game game) {
return game.getStack().stream()
.filter(TargetActivatedOrTriggeredAbilityOrLegendarySpell::isActivatedOrTriggeredAbilityOrLegendarySpell)
.map(stackObject -> stackObject.getStackAbility().getId())
.collect(Collectors.toSet());
}
@Override
public TargetActivatedOrTriggeredAbilityOrLegendarySpell copy() {
return new TargetActivatedOrTriggeredAbilityOrLegendarySpell(this);
}
@Override
public Filter getFilter() {
return filter;
}
static boolean isActivatedOrTriggeredAbilityOrLegendarySpell(StackObject stackObject) {
if (stackObject == null) {
return false;
}
if (stackObject instanceof Ability) {
Ability ability = (Ability) stackObject;
return ability.getAbilityType() == AbilityType.TRIGGERED
|| ability.getAbilityType() == AbilityType.ACTIVATED;
}
if (stackObject instanceof Spell) {
Spell spell = (Spell) stackObject;
return spell.isLegendary();
}
return false;
}
}