mirror of
https://github.com/correl/mage.git
synced 2024-11-28 19:19:55 +00:00
updated copy implementation to work with stack objects
This commit is contained in:
parent
1352beee9f
commit
92007f0132
14 changed files with 206 additions and 218 deletions
|
@ -24,10 +24,11 @@ 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.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
|
import mage.game.stack.StackObject;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
import mage.util.functions.SpellCopyApplier;
|
import mage.util.functions.StackObjectCopyApplier;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -192,7 +193,7 @@ class BeamsplitterMagePredicate implements Predicate<Permanent> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BeamsplitterMageApplier implements SpellCopyApplier {
|
class BeamsplitterMageApplier implements StackObjectCopyApplier {
|
||||||
|
|
||||||
private final Iterator<MageObjectReferencePredicate> predicate;
|
private final Iterator<MageObjectReferencePredicate> predicate;
|
||||||
|
|
||||||
|
@ -203,7 +204,7 @@ class BeamsplitterMageApplier implements SpellCopyApplier {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void modifySpell(Spell spell, Game game) {
|
public void modifySpell(StackObject stackObject, Game game) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,8 +11,9 @@ import mage.filter.StaticFilters;
|
||||||
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
|
import mage.game.stack.StackObject;
|
||||||
import mage.target.TargetSpell;
|
import mage.target.TargetSpell;
|
||||||
import mage.util.functions.SpellCopyApplier;
|
import mage.util.functions.StackObjectCopyApplier;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -69,12 +70,12 @@ class DoubleMajorEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DoubleMajorApplier implements SpellCopyApplier {
|
enum DoubleMajorApplier implements StackObjectCopyApplier {
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void modifySpell(Spell spell, Game game) {
|
public void modifySpell(StackObject stackObject, Game game) {
|
||||||
spell.getSuperType().remove(SuperType.LEGENDARY);
|
stackObject.getSuperType().remove(SuperType.LEGENDARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,8 +11,9 @@ import mage.filter.StaticFilters;
|
||||||
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
|
import mage.game.stack.StackObject;
|
||||||
import mage.target.TargetSpell;
|
import mage.target.TargetSpell;
|
||||||
import mage.util.functions.SpellCopyApplier;
|
import mage.util.functions.StackObjectCopyApplier;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -70,12 +71,12 @@ class ForkEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ForkApplier implements SpellCopyApplier {
|
enum ForkApplier implements StackObjectCopyApplier {
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void modifySpell(Spell spell, Game game) {
|
public void modifySpell(StackObject stackObject, Game game) {
|
||||||
spell.getColor(game).setColor(ObjectColor.RED);
|
stackObject.getColor(game).setColor(ObjectColor.RED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,6 +16,7 @@ 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.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
|
import mage.game.stack.StackObject;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.util.TargetAddress;
|
import mage.util.TargetAddress;
|
||||||
|
@ -132,7 +133,7 @@ class InkTreaderNephilimEffect extends CopySpellForEachItCouldTargetEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<MageObjectReferencePredicate> getPossibleTargets(Spell spell, Player player, Ability source, Game game) {
|
protected List<MageObjectReferencePredicate> getPossibleTargets(StackObject stackObject, Player player, Ability source, Game game) {
|
||||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||||
return game.getBattlefield()
|
return game.getBattlefield()
|
||||||
.getActivePermanents(
|
.getActivePermanents(
|
||||||
|
@ -141,14 +142,14 @@ class InkTreaderNephilimEffect extends CopySpellForEachItCouldTargetEffect {
|
||||||
).stream()
|
).stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(p -> !p.equals(permanent))
|
.filter(p -> !p.equals(permanent))
|
||||||
.filter(p -> spell.canTarget(game, p.getId()))
|
.filter(p -> stackObject.canTarget(game, p.getId()))
|
||||||
.map(p -> new MageObjectReference(p, game))
|
.map(p -> new MageObjectReference(p, game))
|
||||||
.map(MageObjectReferencePredicate::new)
|
.map(MageObjectReferencePredicate::new)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Spell getSpell(Game game, Ability source) {
|
protected Spell getStackObject(Game game, Ability source) {
|
||||||
return (Spell) getValue("triggeringSpell");
|
return (Spell) getValue("triggeringSpell");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ 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.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
|
import mage.game.stack.StackObject;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.util.TargetAddress;
|
import mage.util.TargetAddress;
|
||||||
|
@ -133,7 +134,7 @@ class MirrorwingDragonCopySpellEffect extends CopySpellForEachItCouldTargetEffec
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Player getPlayer(Game game, Ability source) {
|
protected Player getPlayer(Game game, Ability source) {
|
||||||
Spell spell = getSpell(game, source);
|
Spell spell = getStackObject(game, source);
|
||||||
if (spell == null) {
|
if (spell == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +142,7 @@ class MirrorwingDragonCopySpellEffect extends CopySpellForEachItCouldTargetEffec
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<MageObjectReferencePredicate> getPossibleTargets(Spell spell, Player player, Ability source, Game game) {
|
protected List<MageObjectReferencePredicate> getPossibleTargets(StackObject stackObject, Player player, Ability source, Game game) {
|
||||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||||
return game.getBattlefield()
|
return game.getBattlefield()
|
||||||
.getActivePermanents(
|
.getActivePermanents(
|
||||||
|
@ -150,14 +151,14 @@ class MirrorwingDragonCopySpellEffect extends CopySpellForEachItCouldTargetEffec
|
||||||
).stream()
|
).stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(p -> !p.equals(permanent))
|
.filter(p -> !p.equals(permanent))
|
||||||
.filter(p -> spell.canTarget(game, p.getId()))
|
.filter(p -> stackObject.canTarget(game, p.getId()))
|
||||||
.map(p -> new MageObjectReference(p, game))
|
.map(p -> new MageObjectReference(p, game))
|
||||||
.map(MageObjectReferencePredicate::new)
|
.map(MageObjectReferencePredicate::new)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Spell getSpell(Game game, Ability source) {
|
protected Spell getStackObject(Game game, Ability source) {
|
||||||
return (Spell) getValue("triggeringSpell");
|
return (Spell) getValue("triggeringSpell");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.token.GolemToken;
|
import mage.game.permanent.token.GolemToken;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
|
import mage.game.stack.StackObject;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.util.TargetAddress;
|
import mage.util.TargetAddress;
|
||||||
|
@ -131,7 +132,7 @@ class PrecursorGolemCopySpellEffect extends CopySpellForEachItCouldTargetEffect
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Player getPlayer(Game game, Ability source) {
|
protected Player getPlayer(Game game, Ability source) {
|
||||||
Spell spell = getSpell(game, source);
|
Spell spell = getStackObject(game, source);
|
||||||
if (spell == null) {
|
if (spell == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +140,7 @@ class PrecursorGolemCopySpellEffect extends CopySpellForEachItCouldTargetEffect
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<MageObjectReferencePredicate> getPossibleTargets(Spell spell, Player player, Ability source, Game game) {
|
protected List<MageObjectReferencePredicate> getPossibleTargets(StackObject stackObject, Player player, Ability source, Game game) {
|
||||||
Permanent permanent = (Permanent) getValue("targetedGolem");
|
Permanent permanent = (Permanent) getValue("targetedGolem");
|
||||||
return game.getBattlefield()
|
return game.getBattlefield()
|
||||||
.getActivePermanents(
|
.getActivePermanents(
|
||||||
|
@ -147,14 +148,14 @@ class PrecursorGolemCopySpellEffect extends CopySpellForEachItCouldTargetEffect
|
||||||
).stream()
|
).stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(p -> !p.equals(permanent))
|
.filter(p -> !p.equals(permanent))
|
||||||
.filter(p -> spell.canTarget(game, p.getId()))
|
.filter(p -> stackObject.canTarget(game, p.getId()))
|
||||||
.map(p -> new MageObjectReference(p, game))
|
.map(p -> new MageObjectReference(p, game))
|
||||||
.map(MageObjectReferencePredicate::new)
|
.map(MageObjectReferencePredicate::new)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Spell getSpell(Game game, Ability source) {
|
protected Spell getStackObject(Game game, Ability source) {
|
||||||
return (Spell) getValue("triggeringSpell");
|
return (Spell) getValue("triggeringSpell");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import mage.filter.predicate.ObjectPlayerPredicate;
|
||||||
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
|
import mage.game.stack.StackObject;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.target.TargetSpell;
|
import mage.target.TargetSpell;
|
||||||
|
@ -119,9 +120,9 @@ class RadiateEffect extends CopySpellForEachItCouldTargetEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<MageObjectReferencePredicate> getPossibleTargets(Spell spell, Player player, Ability source, Game game) {
|
protected List<MageObjectReferencePredicate> getPossibleTargets(StackObject stackObject, Player player, Ability source, Game game) {
|
||||||
List<MageObjectReferencePredicate> predicates = new ArrayList<>();
|
List<MageObjectReferencePredicate> predicates = new ArrayList<>();
|
||||||
UUID targeted = spell
|
UUID targeted = ((Spell) stackObject)
|
||||||
.getSpellAbilities()
|
.getSpellAbilities()
|
||||||
.stream()
|
.stream()
|
||||||
.map(AbilityImpl::getTargets)
|
.map(AbilityImpl::getTargets)
|
||||||
|
@ -137,7 +138,7 @@ class RadiateEffect extends CopySpellForEachItCouldTargetEffect {
|
||||||
).stream()
|
).stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(p -> !p.equals(game.getPermanent(targeted)))
|
.filter(p -> !p.equals(game.getPermanent(targeted)))
|
||||||
.filter(p -> spell.canTarget(game, p.getId()))
|
.filter(p -> stackObject.canTarget(game, p.getId()))
|
||||||
.map(p -> new MageObjectReference(p, game))
|
.map(p -> new MageObjectReference(p, game))
|
||||||
.map(MageObjectReferencePredicate::new)
|
.map(MageObjectReferencePredicate::new)
|
||||||
.forEach(predicates::add);
|
.forEach(predicates::add);
|
||||||
|
@ -145,7 +146,7 @@ class RadiateEffect extends CopySpellForEachItCouldTargetEffect {
|
||||||
.getPlayersInRange(source.getControllerId(), game)
|
.getPlayersInRange(source.getControllerId(), game)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(uuid -> !uuid.equals(targeted))
|
.filter(uuid -> !uuid.equals(targeted))
|
||||||
.filter(uuid -> spell.canTarget(game, uuid))
|
.filter(uuid -> stackObject.canTarget(game, uuid))
|
||||||
.map(MageObjectReference::new)
|
.map(MageObjectReference::new)
|
||||||
.map(MageObjectReferencePredicate::new)
|
.map(MageObjectReferencePredicate::new)
|
||||||
.forEach(predicates::add);
|
.forEach(predicates::add);
|
||||||
|
@ -153,7 +154,7 @@ class RadiateEffect extends CopySpellForEachItCouldTargetEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Spell getSpell(Game game, Ability source) {
|
protected Spell getStackObject(Game game, Ability source) {
|
||||||
return game.getSpell(source.getFirstTarget());
|
return game.getSpell(source.getFirstTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ 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.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
|
import mage.game.stack.StackObject;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.util.TargetAddress;
|
import mage.util.TargetAddress;
|
||||||
|
@ -134,7 +135,7 @@ class ZadaHedronGrinderCopySpellEffect extends CopySpellForEachItCouldTargetEffe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<MageObjectReferencePredicate> getPossibleTargets(Spell spell, Player player, Ability source, Game game) {
|
protected List<MageObjectReferencePredicate> getPossibleTargets(StackObject stackObject, Player player, Ability source, Game game) {
|
||||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||||
return game.getBattlefield()
|
return game.getBattlefield()
|
||||||
.getActivePermanents(
|
.getActivePermanents(
|
||||||
|
@ -143,14 +144,14 @@ class ZadaHedronGrinderCopySpellEffect extends CopySpellForEachItCouldTargetEffe
|
||||||
).stream()
|
).stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(p -> !p.equals(permanent))
|
.filter(p -> !p.equals(permanent))
|
||||||
.filter(p -> spell.canTarget(game, p.getId()))
|
.filter(p -> stackObject.canTarget(game, p.getId()))
|
||||||
.map(p -> new MageObjectReference(p, game))
|
.map(p -> new MageObjectReference(p, game))
|
||||||
.map(MageObjectReferencePredicate::new)
|
.map(MageObjectReferencePredicate::new)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Spell getSpell(Game game, Ability source) {
|
protected Spell getStackObject(Game game, Ability source) {
|
||||||
return (Spell) getValue("triggeringSpell");
|
return (Spell) getValue("triggeringSpell");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.StackObject;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.util.functions.SpellCopyApplier;
|
import mage.util.functions.StackObjectCopyApplier;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -17,7 +17,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public abstract class CopySpellForEachItCouldTargetEffect extends OneShotEffect {
|
public abstract class CopySpellForEachItCouldTargetEffect extends OneShotEffect {
|
||||||
|
|
||||||
private static final class CopyApplier implements SpellCopyApplier {
|
private static final class CopyApplier implements StackObjectCopyApplier {
|
||||||
|
|
||||||
private final Iterator<MageObjectReferencePredicate> iterator;
|
private final Iterator<MageObjectReferencePredicate> iterator;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public abstract class CopySpellForEachItCouldTargetEffect extends OneShotEffect
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void modifySpell(Spell spell, Game game) {
|
public void modifySpell(StackObject stackObject, Game game) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -46,21 +46,21 @@ public abstract class CopySpellForEachItCouldTargetEffect extends OneShotEffect
|
||||||
super(effect);
|
super(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Spell getSpell(Game game, Ability source);
|
protected abstract StackObject getStackObject(Game game, Ability source);
|
||||||
|
|
||||||
protected abstract Player getPlayer(Game game, Ability source);
|
protected abstract Player getPlayer(Game game, Ability source);
|
||||||
|
|
||||||
protected abstract List<MageObjectReferencePredicate> getPossibleTargets(Spell spell, Player player, Ability source, Game game);
|
protected abstract List<MageObjectReferencePredicate> getPossibleTargets(StackObject stackObject, Player player, Ability source, Game game);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player actingPlayer = getPlayer(game, source);
|
Player actingPlayer = getPlayer(game, source);
|
||||||
Spell spell = getSpell(game, source);
|
StackObject stackObject = getStackObject(game, source);
|
||||||
if (actingPlayer == null || spell == null) {
|
if (actingPlayer == null || stackObject == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
List<MageObjectReferencePredicate> predicates = getPossibleTargets(spell, actingPlayer, source, game);
|
List<MageObjectReferencePredicate> predicates = getPossibleTargets(stackObject, actingPlayer, source, game);
|
||||||
spell.createCopyOnStack(
|
stackObject.createCopyOnStack(
|
||||||
game, source, actingPlayer.getId(), false,
|
game, source, actingPlayer.getId(), false,
|
||||||
predicates.size(), new CopyApplier(predicates)
|
predicates.size(), new CopyApplier(predicates)
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,20 +13,15 @@ import mage.abilities.keyword.BestowAbility;
|
||||||
import mage.abilities.keyword.MorphAbility;
|
import mage.abilities.keyword.MorphAbility;
|
||||||
import mage.abilities.text.TextPart;
|
import mage.abilities.text.TextPart;
|
||||||
import mage.cards.*;
|
import mage.cards.*;
|
||||||
import mage.choices.Choice;
|
|
||||||
import mage.choices.ChoiceImpl;
|
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.counters.Counter;
|
import mage.counters.Counter;
|
||||||
import mage.counters.Counters;
|
import mage.counters.Counters;
|
||||||
import mage.filter.FilterMana;
|
import mage.filter.FilterMana;
|
||||||
import mage.filter.predicate.Predicate;
|
|
||||||
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.GameState;
|
import mage.game.GameState;
|
||||||
import mage.game.MageObjectAttribute;
|
import mage.game.MageObjectAttribute;
|
||||||
import mage.game.events.CopiedStackObjectEvent;
|
import mage.game.events.CopiedStackObjectEvent;
|
||||||
import mage.game.events.CopyStackObjectEvent;
|
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.game.events.ZoneChangeEvent;
|
import mage.game.events.ZoneChangeEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.PermanentCard;
|
import mage.game.permanent.PermanentCard;
|
||||||
|
@ -36,16 +31,15 @@ import mage.util.CardUtil;
|
||||||
import mage.util.GameLog;
|
import mage.util.GameLog;
|
||||||
import mage.util.ManaUtil;
|
import mage.util.ManaUtil;
|
||||||
import mage.util.SubTypes;
|
import mage.util.SubTypes;
|
||||||
import mage.util.functions.SpellCopyApplier;
|
import mage.util.functions.StackObjectCopyApplier;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class Spell extends StackObjImpl implements Card {
|
public class Spell extends StackObjectImpl implements Card {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(Spell.class);
|
private static final Logger logger = Logger.getLogger(Spell.class);
|
||||||
|
|
||||||
|
@ -1063,114 +1057,13 @@ public class Spell extends StackObjImpl implements Card {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets) {
|
public void createSingleCopy(UUID newControllerId, StackObjectCopyApplier applier, MageObjectReferencePredicate predicate, Game game, Ability source, boolean chooseNewTargets) {
|
||||||
createCopyOnStack(game, source, newControllerId, chooseNewTargets, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets, int amount) {
|
|
||||||
createCopyOnStack(game, source, newControllerId, chooseNewTargets, amount, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class PredicateIterator implements Iterator<MageObjectReferencePredicate> {
|
|
||||||
private final SpellCopyApplier applier;
|
|
||||||
private final Player player;
|
|
||||||
private final int amount;
|
|
||||||
private final Game game;
|
|
||||||
private Map<String, MageObjectReferencePredicate> predicateMap = null;
|
|
||||||
private int anyCount = 0;
|
|
||||||
private int setCount = 0;
|
|
||||||
private Iterator<MageObjectReferencePredicate> iterator = null;
|
|
||||||
private Choice choice = null;
|
|
||||||
|
|
||||||
private PredicateIterator(Game game, UUID newControllerId, int amount, SpellCopyApplier applier) {
|
|
||||||
this.applier = applier;
|
|
||||||
this.player = game.getPlayer(newControllerId);
|
|
||||||
this.amount = amount;
|
|
||||||
this.game = game;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void makeMap() {
|
|
||||||
if (predicateMap != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
predicateMap = new HashMap<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < amount; i++) {
|
|
||||||
MageObjectReferencePredicate predicate = applier.getNextPredicate();
|
|
||||||
if (predicate == null) {
|
|
||||||
anyCount++;
|
|
||||||
String message = "Any target";
|
|
||||||
if (anyCount > 1) {
|
|
||||||
message += " (" + anyCount + ")";
|
|
||||||
}
|
|
||||||
predicateMap.put(message, predicate);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
setCount++;
|
|
||||||
predicateMap.put(predicate.getName(game), predicate);
|
|
||||||
}
|
|
||||||
if ((setCount == 1 && anyCount == 0) || setCount == 0) {
|
|
||||||
iterator = predicateMap.values().stream().collect(Collectors.toList()).iterator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void makeChoice() {
|
|
||||||
if (choice != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
choice = new ChoiceImpl(false);
|
|
||||||
choice.setMessage("Choose the order of copies to go on the stack");
|
|
||||||
choice.setSubMessage("Press cancel to put the rest in any order");
|
|
||||||
choice.setChoices(new HashSet<>(predicateMap.keySet()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MageObjectReferencePredicate next() {
|
|
||||||
if (player == null || applier == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
makeMap();
|
|
||||||
if (iterator != null) {
|
|
||||||
return iterator.hasNext() ? iterator.next() : null;
|
|
||||||
}
|
|
||||||
makeChoice();
|
|
||||||
if (choice.getChoices().size() < 2) {
|
|
||||||
iterator = choice.getChoices().stream().map(predicateMap::get).iterator();
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
choice.clearChoice();
|
|
||||||
player.choose(Outcome.AIDontUseIt, choice, game);
|
|
||||||
String chosen = choice.getChoice();
|
|
||||||
if (chosen == null) {
|
|
||||||
iterator = choice.getChoices().stream().map(predicateMap::get).iterator();
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
choice.getChoices().remove(chosen);
|
|
||||||
return predicateMap.get(chosen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets, int amount, SpellCopyApplier applier) {
|
|
||||||
GameEvent gameEvent = new CopyStackObjectEvent(source, this, newControllerId, amount);
|
|
||||||
if (game.replaceEvent(gameEvent)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Iterator<MageObjectReferencePredicate> predicates = new PredicateIterator(game, newControllerId, gameEvent.getAmount(), applier);
|
|
||||||
for (int i = 0; i < gameEvent.getAmount(); i++) {
|
|
||||||
Spell spellCopy = this.copySpell(game, source, newControllerId);
|
Spell spellCopy = this.copySpell(game, source, newControllerId);
|
||||||
if (applier != null) {
|
if (applier != null) {
|
||||||
applier.modifySpell(spellCopy, game);
|
applier.modifySpell(spellCopy, game);
|
||||||
}
|
}
|
||||||
spellCopy.setZone(Zone.STACK, game); // required for targeting ex: Nivmagus Elemental
|
spellCopy.setZone(Zone.STACK, game); // required for targeting ex: Nivmagus Elemental
|
||||||
game.getStack().push(spellCopy);
|
game.getStack().push(spellCopy);
|
||||||
Predicate predicate = predicates.next();
|
|
||||||
if (predicate != null) {
|
if (predicate != null) {
|
||||||
spellCopy.chooseNewTargets(game, newControllerId, true, false, predicate);
|
spellCopy.chooseNewTargets(game, newControllerId, true, false, predicate);
|
||||||
} else if (chooseNewTargets || applier != null) { // if applier is non-null but predicate is null then it's extra
|
} else if (chooseNewTargets || applier != null) { // if applier is non-null but predicate is null then it's extra
|
||||||
|
@ -1178,14 +1071,6 @@ public class Spell extends StackObjImpl implements Card {
|
||||||
}
|
}
|
||||||
game.fireEvent(new CopiedStackObjectEvent(this, spellCopy, newControllerId));
|
game.fireEvent(new CopiedStackObjectEvent(this, spellCopy, newControllerId));
|
||||||
}
|
}
|
||||||
Player player = game.getPlayer(newControllerId);
|
|
||||||
if (player != null) {
|
|
||||||
game.informPlayers(
|
|
||||||
player.getName() + " created " + CardUtil.numberToText(gameEvent.getAmount(), "a")
|
|
||||||
+ " cop" + (gameEvent.getAmount() == 1 ? "y" : "ies") + " of " + getIdName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAllCreatureTypes(Game game) {
|
public boolean isAllCreatureTypes(Game game) {
|
||||||
|
|
|
@ -20,9 +20,9 @@ import mage.abilities.text.TextPart;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.FrameStyle;
|
import mage.cards.FrameStyle;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
|
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.CopiedStackObjectEvent;
|
import mage.game.events.CopiedStackObjectEvent;
|
||||||
import mage.game.events.CopyStackObjectEvent;
|
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.events.ZoneChangeEvent;
|
import mage.game.events.ZoneChangeEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
@ -30,10 +30,9 @@ import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.target.Targets;
|
import mage.target.Targets;
|
||||||
import mage.target.targetadjustment.TargetAdjuster;
|
import mage.target.targetadjustment.TargetAdjuster;
|
||||||
import mage.util.CardUtil;
|
|
||||||
import mage.util.GameLog;
|
import mage.util.GameLog;
|
||||||
import mage.util.SubTypes;
|
import mage.util.SubTypes;
|
||||||
import mage.util.functions.SpellCopyApplier;
|
import mage.util.functions.StackObjectCopyApplier;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -44,7 +43,7 @@ import java.util.UUID;
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class StackAbility extends StackObjImpl implements Ability {
|
public class StackAbility extends StackObjectImpl implements Ability {
|
||||||
|
|
||||||
private static final ArrayList<CardType> emptyCardType = new ArrayList<>();
|
private static final ArrayList<CardType> emptyCardType = new ArrayList<>();
|
||||||
private static final List<String> emptyString = new ArrayList<>();
|
private static final List<String> emptyString = new ArrayList<>();
|
||||||
|
@ -598,44 +597,18 @@ public class StackAbility extends StackObjImpl implements Ability {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets) {
|
public void createSingleCopy(UUID newControllerId, StackObjectCopyApplier applier, MageObjectReferencePredicate predicate, Game game, Ability source, boolean chooseNewTargets) {
|
||||||
createCopyOnStack(game, source, newControllerId, chooseNewTargets, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets, int amount) {
|
|
||||||
createCopyOnStack(game, source, newControllerId, chooseNewTargets, amount, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets, int amount, SpellCopyApplier applier) {
|
|
||||||
StackAbility newStackAbility = null;
|
|
||||||
GameEvent gameEvent = new CopyStackObjectEvent(source, this, newControllerId, amount);
|
|
||||||
if (game.replaceEvent(gameEvent)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < gameEvent.getAmount(); i++) {
|
|
||||||
Ability newAbility = this.copy();
|
Ability newAbility = this.copy();
|
||||||
newAbility.newId();
|
newAbility.newId();
|
||||||
newStackAbility = new StackAbility(newAbility, newControllerId);
|
StackAbility newStackAbility = new StackAbility(newAbility, newControllerId);
|
||||||
game.getStack().push(newStackAbility);
|
game.getStack().push(newStackAbility);
|
||||||
if (chooseNewTargets && !newAbility.getTargets().isEmpty()) {
|
if (predicate != null) {
|
||||||
Player controller = game.getPlayer(newControllerId);
|
newStackAbility.chooseNewTargets(game, newControllerId, true, false, predicate);
|
||||||
Outcome outcome = newAbility.getEffects().getOutcome(newAbility);
|
} else if (chooseNewTargets || applier != null) { // if applier is non-null but predicate is null then it's extra
|
||||||
if (controller.chooseUse(outcome, "Choose new targets?", source, game)) {
|
newStackAbility.chooseNewTargets(game, newControllerId);
|
||||||
newAbility.getTargets().clearChosen();
|
|
||||||
newAbility.getTargets().chooseTargets(outcome, newControllerId, newAbility, false, game, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
game.fireEvent(new CopiedStackObjectEvent(this, newStackAbility, newControllerId));
|
game.fireEvent(new CopiedStackObjectEvent(this, newStackAbility, newControllerId));
|
||||||
}
|
}
|
||||||
Player player = game.getPlayer(newControllerId);
|
|
||||||
if (player != null) {
|
|
||||||
game.informPlayers(
|
|
||||||
player.getName() + " created " + CardUtil.numberToText(gameEvent.getAmount(), "a")
|
|
||||||
+ " cop" + (gameEvent.getAmount() == 1 ? "y" : "ies") + " of " + getIdName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAllCreatureTypes(Game game) {
|
public boolean isAllCreatureTypes(Game game) {
|
||||||
|
|
|
@ -5,9 +5,10 @@ import mage.abilities.Ability;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.constants.ZoneDetail;
|
import mage.constants.ZoneDetail;
|
||||||
import mage.filter.predicate.Predicate;
|
import mage.filter.predicate.Predicate;
|
||||||
|
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||||
import mage.game.Controllable;
|
import mage.game.Controllable;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.util.functions.SpellCopyApplier;
|
import mage.util.functions.StackObjectCopyApplier;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -35,7 +36,9 @@ public interface StackObject extends MageObject, Controllable {
|
||||||
|
|
||||||
void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets, int amount);
|
void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets, int amount);
|
||||||
|
|
||||||
void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets, int amount, SpellCopyApplier applier);
|
void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets, int amount, StackObjectCopyApplier applier);
|
||||||
|
|
||||||
|
void createSingleCopy(UUID newControllerId, StackObjectCopyApplier applier, MageObjectReferencePredicate predicate, Game game, Ability source, boolean chooseNewTargets);
|
||||||
|
|
||||||
boolean isTargetChanged();
|
boolean isTargetChanged();
|
||||||
|
|
||||||
|
|
|
@ -6,25 +6,144 @@ import mage.abilities.AbilitiesImpl;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.Mode;
|
import mage.abilities.Mode;
|
||||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||||
|
import mage.choices.Choice;
|
||||||
|
import mage.choices.ChoiceImpl;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.filter.predicate.Predicate;
|
import mage.filter.predicate.Predicate;
|
||||||
|
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
import mage.game.events.CopyStackObjectEvent;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.target.TargetAmount;
|
import mage.target.TargetAmount;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
import mage.util.functions.StackObjectCopyApplier;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.Objects;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public abstract class StackObjImpl implements StackObject {
|
public abstract class StackObjectImpl implements StackObject {
|
||||||
|
|
||||||
protected boolean targetChanged; // for Psychic Battle
|
protected boolean targetChanged; // for Psychic Battle
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets) {
|
||||||
|
createCopyOnStack(game, source, newControllerId, chooseNewTargets, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets, int amount) {
|
||||||
|
createCopyOnStack(game, source, newControllerId, chooseNewTargets, amount, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class PredicateIterator implements Iterator<MageObjectReferencePredicate> {
|
||||||
|
private final StackObjectCopyApplier applier;
|
||||||
|
private final Player player;
|
||||||
|
private final int amount;
|
||||||
|
private final Game game;
|
||||||
|
private Map<String, MageObjectReferencePredicate> predicateMap = null;
|
||||||
|
private int anyCount = 0;
|
||||||
|
private int setCount = 0;
|
||||||
|
private Iterator<MageObjectReferencePredicate> iterator = null;
|
||||||
|
private Choice choice = null;
|
||||||
|
|
||||||
|
private PredicateIterator(Game game, UUID newControllerId, int amount, StackObjectCopyApplier applier) {
|
||||||
|
this.applier = applier;
|
||||||
|
this.player = game.getPlayer(newControllerId);
|
||||||
|
this.amount = amount;
|
||||||
|
this.game = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void makeMap() {
|
||||||
|
if (predicateMap != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
predicateMap = new HashMap<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < amount; i++) {
|
||||||
|
MageObjectReferencePredicate predicate = applier.getNextPredicate();
|
||||||
|
if (predicate == null) {
|
||||||
|
anyCount++;
|
||||||
|
String message = "Any target";
|
||||||
|
if (anyCount > 1) {
|
||||||
|
message += " (" + anyCount + ")";
|
||||||
|
}
|
||||||
|
predicateMap.put(message, predicate);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
setCount++;
|
||||||
|
predicateMap.put(predicate.getName(game), predicate);
|
||||||
|
}
|
||||||
|
if ((setCount == 1 && anyCount == 0) || setCount == 0) {
|
||||||
|
iterator = predicateMap.values().stream().collect(Collectors.toList()).iterator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void makeChoice() {
|
||||||
|
if (choice != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
choice = new ChoiceImpl(false);
|
||||||
|
choice.setMessage("Choose the order of copies to go on the stack");
|
||||||
|
choice.setSubMessage("Press cancel to put the rest in any order");
|
||||||
|
choice.setChoices(new HashSet<>(predicateMap.keySet()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MageObjectReferencePredicate next() {
|
||||||
|
if (player == null || applier == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
makeMap();
|
||||||
|
if (iterator != null) {
|
||||||
|
return iterator.hasNext() ? iterator.next() : null;
|
||||||
|
}
|
||||||
|
makeChoice();
|
||||||
|
if (choice.getChoices().size() < 2) {
|
||||||
|
iterator = choice.getChoices().stream().map(predicateMap::get).iterator();
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
choice.clearChoice();
|
||||||
|
player.choose(Outcome.AIDontUseIt, choice, game);
|
||||||
|
String chosen = choice.getChoice();
|
||||||
|
if (chosen == null) {
|
||||||
|
iterator = choice.getChoices().stream().map(predicateMap::get).iterator();
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
choice.getChoices().remove(chosen);
|
||||||
|
return predicateMap.get(chosen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets, int amount, StackObjectCopyApplier applier) {
|
||||||
|
GameEvent gameEvent = new CopyStackObjectEvent(source, this, newControllerId, amount);
|
||||||
|
if (game.replaceEvent(gameEvent)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Iterator<MageObjectReferencePredicate> predicates = new PredicateIterator(game, newControllerId, gameEvent.getAmount(), applier);
|
||||||
|
for (int i = 0; i < gameEvent.getAmount(); i++) {
|
||||||
|
createSingleCopy(newControllerId, applier, predicates.next(), game, source, chooseNewTargets);
|
||||||
|
}
|
||||||
|
Player player = game.getPlayer(newControllerId);
|
||||||
|
if (player == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
game.informPlayers(
|
||||||
|
player.getName() + " created " + CardUtil.numberToText(gameEvent.getAmount(), "a")
|
||||||
|
+ " cop" + (gameEvent.getAmount() == 1 ? "y" : "ies") + " of " + getIdName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Choose new targets for a stack Object
|
* Choose new targets for a stack Object
|
||||||
*
|
*
|
|
@ -2,16 +2,16 @@ package mage.util.functions;
|
||||||
|
|
||||||
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.StackObject;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public interface SpellCopyApplier extends Serializable {
|
public interface StackObjectCopyApplier extends Serializable {
|
||||||
|
|
||||||
void modifySpell(Spell spell, Game game);
|
void modifySpell(StackObject stackObject, Game game);
|
||||||
|
|
||||||
MageObjectReferencePredicate getNextPredicate();
|
MageObjectReferencePredicate getNextPredicate();
|
||||||
}
|
}
|
Loading…
Reference in a new issue