mirror of
https://github.com/correl/mage.git
synced 2025-01-12 19:25:44 +00:00
made some abilities properly copiable
This commit is contained in:
parent
1468f89ce6
commit
4e5dea5097
2 changed files with 85 additions and 96 deletions
|
@ -1,54 +1,62 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.MageItem;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.ChooseNewTargetsTargetEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterStackObject;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.stack.StackObject;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetStackObject;
|
||||
import mage.target.Targets;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class SilverWyvern extends CardImpl {
|
||||
|
||||
|
||||
private static final FilterStackObject filter = new FilterStackObject();
|
||||
|
||||
static {
|
||||
filter.add(SilverWyvernPredicate.instance);
|
||||
}
|
||||
|
||||
public SilverWyvern(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
|
||||
this.subtype.add(SubType.DRAKE);
|
||||
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
// {U}: Change the target of target spell or ability that targets only Silver Wyvern. The new target must be a creature.
|
||||
Effect effect = new ChooseNewTargetsTargetEffect(true, true);
|
||||
effect.setText("Change the target of target spell or ability that targets only {this}. The new target must be a creature");
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{U}"));
|
||||
FilterStackObject filter = new FilterStackObject();
|
||||
filter.add(new TargetsOnlySourcePredicate(getId()));
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
new ChooseNewTargetsTargetEffect(true, true)
|
||||
.setText("Change the target of target spell or ability that targets only {this}. " +
|
||||
"The new target must be a creature"),
|
||||
new ManaCostsImpl("{U}")
|
||||
);
|
||||
ability.addTarget(new TargetStackObject(filter));
|
||||
this.addAbility(ability);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public SilverWyvern(final SilverWyvern card) {
|
||||
private SilverWyvern(final SilverWyvern card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
|
@ -58,35 +66,21 @@ public final class SilverWyvern extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class TargetsOnlySourcePredicate implements Predicate<MageObject> {
|
||||
|
||||
private final UUID sourceId;
|
||||
|
||||
public TargetsOnlySourcePredicate(UUID sourceId) {
|
||||
this.sourceId = sourceId;
|
||||
}
|
||||
enum SilverWyvernPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<StackObject>> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(MageObject input, Game game) {
|
||||
StackObject stackObject = game.getStack().getStackObject(input.getId());
|
||||
if (stackObject != null) {
|
||||
Targets spellTargets = stackObject.getStackAbility().getTargets();
|
||||
int numberOfTargets = 0;
|
||||
for (Target target : spellTargets) {
|
||||
if (target.getFirstTarget() == null || !target.getFirstTarget().toString().equals(sourceId.toString())) { // UUID != UUID does not work - it's always false
|
||||
return false;
|
||||
}
|
||||
numberOfTargets += target.getTargets().size();
|
||||
}
|
||||
if (numberOfTargets == 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "target spell or ability that targets only source";
|
||||
public boolean apply(ObjectSourcePlayer<StackObject> input, Game game) {
|
||||
Stream<UUID> stream = input.getObject()
|
||||
.getStackAbility()
|
||||
.getTargets()
|
||||
.stream()
|
||||
.map(Target::getTargets)
|
||||
.flatMap(Collection::stream)
|
||||
.map(game::getPermanent)
|
||||
.filter(Objects::nonNull)
|
||||
.map(MageItem::getId);
|
||||
return stream.allMatch(input.getSourceId()::equals)
|
||||
&& stream.anyMatch(input.getSourceId()::equals);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.MageItem;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ColoredManaCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
|
@ -17,50 +13,68 @@ import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
|||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.game.stack.StackObject;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetSpell;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author emerald000
|
||||
*/
|
||||
public final class Torchling extends CardImpl {
|
||||
|
||||
private static final FilterSpell filter = new FilterSpell();
|
||||
|
||||
static {
|
||||
filter.add(TorchlingPredicate.instance);
|
||||
}
|
||||
|
||||
public Torchling(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
|
||||
this.subtype.add(SubType.SHAPESHIFTER);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// {R}: Untap Torchling.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new ColoredManaCost(ColoredManaSymbol.R)));
|
||||
this.addAbility(new SimpleActivatedAbility(new UntapSourceEffect(), new ColoredManaCost(ColoredManaSymbol.R)));
|
||||
|
||||
// {R}: Target creature blocks Torchling this turn if able.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MustBeBlockedByTargetSourceEffect(), new ColoredManaCost(ColoredManaSymbol.R));
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
new MustBeBlockedByTargetSourceEffect(), new ColoredManaCost(ColoredManaSymbol.R)
|
||||
);
|
||||
ability.addTarget(new TargetCreaturePermanent());
|
||||
this.addAbility(ability);
|
||||
|
||||
// {R}: Change the target of target spell that targets only Torchling.
|
||||
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ChooseNewTargetsTargetEffect(true, true), new ColoredManaCost(ColoredManaSymbol.R));
|
||||
FilterSpell filter = new FilterSpell("spell that targets only " + this.getName());
|
||||
filter.add(new TorchlingTargetPredicate(this.getId()));
|
||||
ability = new SimpleActivatedAbility(
|
||||
new ChooseNewTargetsTargetEffect(true, true)
|
||||
.setText("change the target of target spell that targets only {this}"),
|
||||
new ColoredManaCost(ColoredManaSymbol.R)
|
||||
);
|
||||
ability.addTarget(new TargetSpell(filter));
|
||||
this.addAbility(ability);
|
||||
|
||||
// {1}: Torchling gets +1/-1 until end of turn.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, -1, Duration.EndOfTurn), new GenericManaCost(1)));
|
||||
this.addAbility(new SimpleActivatedAbility(
|
||||
new BoostSourceEffect(1, -1, Duration.EndOfTurn), new GenericManaCost(1)
|
||||
));
|
||||
|
||||
// {1}: Torchling gets -1/+1 until end of turn.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(-1, 1, Duration.EndOfTurn), new GenericManaCost(1)));
|
||||
this.addAbility(new SimpleActivatedAbility(
|
||||
new BoostSourceEffect(-1, 1, Duration.EndOfTurn), new GenericManaCost(1)
|
||||
));
|
||||
}
|
||||
|
||||
public Torchling(final Torchling card) {
|
||||
|
@ -73,40 +87,21 @@ public final class Torchling extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class TorchlingTargetPredicate implements Predicate<MageObject> {
|
||||
|
||||
private final UUID sourceId;
|
||||
|
||||
TorchlingTargetPredicate(UUID sourceId) {
|
||||
this.sourceId = sourceId;
|
||||
}
|
||||
enum TorchlingPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<StackObject>> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(MageObject input, Game game) {
|
||||
Spell spell = game.getStack().getSpell(input.getId());
|
||||
if (spell != null) {
|
||||
int numberOfTargets = 0;
|
||||
for (SpellAbility spellAbility : spell.getSpellAbilities()) {
|
||||
for (UUID modeId : spellAbility.getModes().getSelectedModes()) {
|
||||
Mode mode = spellAbility.getModes().get(modeId);
|
||||
for (Target target : mode.getTargets()) {
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
if (!targetId.equals(sourceId)) {
|
||||
return false;
|
||||
} else {
|
||||
numberOfTargets++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return numberOfTargets > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "target spell that targets only {this}";
|
||||
public boolean apply(ObjectSourcePlayer<StackObject> input, Game game) {
|
||||
Stream<UUID> stream = input.getObject()
|
||||
.getStackAbility()
|
||||
.getTargets()
|
||||
.stream()
|
||||
.map(Target::getTargets)
|
||||
.flatMap(Collection::stream)
|
||||
.map(game::getPermanent)
|
||||
.filter(Objects::nonNull)
|
||||
.map(MageItem::getId);
|
||||
return stream.allMatch(input.getSourceId()::equals)
|
||||
&& stream.anyMatch(input.getSourceId()::equals);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue