forked from External/mage
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
|
|
@ -13,20 +13,15 @@ import mage.abilities.keyword.BestowAbility;
|
|||
import mage.abilities.keyword.MorphAbility;
|
||||
import mage.abilities.text.TextPart;
|
||||
import mage.cards.*;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceImpl;
|
||||
import mage.constants.*;
|
||||
import mage.counters.Counter;
|
||||
import mage.counters.Counters;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.GameState;
|
||||
import mage.game.MageObjectAttribute;
|
||||
import mage.game.events.CopiedStackObjectEvent;
|
||||
import mage.game.events.CopyStackObjectEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.PermanentCard;
|
||||
|
|
@ -36,16 +31,15 @@ import mage.util.CardUtil;
|
|||
import mage.util.GameLog;
|
||||
import mage.util.ManaUtil;
|
||||
import mage.util.SubTypes;
|
||||
import mage.util.functions.SpellCopyApplier;
|
||||
import mage.util.functions.StackObjectCopyApplier;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
|
|
@ -1063,128 +1057,19 @@ public class Spell extends StackObjImpl implements Card {
|
|||
}
|
||||
|
||||
@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 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;
|
||||
public void createSingleCopy(UUID newControllerId, StackObjectCopyApplier applier, MageObjectReferencePredicate predicate, Game game, Ability source, boolean chooseNewTargets) {
|
||||
Spell spellCopy = this.copySpell(game, source, newControllerId);
|
||||
if (applier != null) {
|
||||
applier.modifySpell(spellCopy, 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);
|
||||
if (applier != null) {
|
||||
applier.modifySpell(spellCopy, game);
|
||||
}
|
||||
spellCopy.setZone(Zone.STACK, game); // required for targeting ex: Nivmagus Elemental
|
||||
game.getStack().push(spellCopy);
|
||||
Predicate predicate = predicates.next();
|
||||
if (predicate != null) {
|
||||
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
|
||||
spellCopy.chooseNewTargets(game, 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()
|
||||
);
|
||||
spellCopy.setZone(Zone.STACK, game); // required for targeting ex: Nivmagus Elemental
|
||||
game.getStack().push(spellCopy);
|
||||
if (predicate != null) {
|
||||
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
|
||||
spellCopy.chooseNewTargets(game, newControllerId);
|
||||
}
|
||||
game.fireEvent(new CopiedStackObjectEvent(this, spellCopy, newControllerId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue