Refactor implementation of spell copies for cards like Twinning Staff as well as refactor handling of target changing (WIP) (#7662)

* refactored createCopyOnStack to be void

* added new interface for modifying copied spellsspells

* update implementation of Fork to use new applier

* reworked epic effect

* add applier to spell copy code

* updated implementation of Beamsplitter Mage

* updated cards which copy for each possible target

* added support for additional copies having targets changed

* fixed/ignored failing tests

* updated target changing to prevent unnecessary choosing

* added test for Twinning Staff

* updated implementation of spell copy applier

* added new method for choosing order of copies on stack

* fixed test failures

* [TSR] various text fixes

* fixed a test failure

* [SLD] fixed Rick, Steadfast Leader only counting Human creatures

* updated test framework to handle skips without affecting starting player choice

* fixed another test failure

* updated copy messaging for consistency

* added copy messaging to stack abilities
This commit is contained in:
Evan Kranzler 2021-03-12 12:47:49 -05:00 committed by GitHub
parent b51915f6e8
commit 9c56a98dc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 972 additions and 1092 deletions

View file

@ -1,58 +1,47 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.stack.StackObject;
/**
* @author BetaSteward_at_googlemail.com
*
*/
public class ChooseNewTargetsTargetEffect extends OneShotEffect {
private boolean forceChange;
private boolean onlyOneTarget;
private FilterPermanent filterNewTarget;
private final boolean forceChange;
private final boolean onlyOneTarget;
public ChooseNewTargetsTargetEffect() {
this(false, false);
}
public ChooseNewTargetsTargetEffect(boolean forceChange, boolean onlyOneTarget) {
this(forceChange, onlyOneTarget, null);
}
/**
*
* @param forceChange forces the user to choose another target (only targets
* with maxtargets = 1 supported)
* @param onlyOneTarget only one target can be selected for the change
* @param forceChange forces the user to choose another target (only targets
* with maxtargets = 1 supported)
* @param onlyOneTarget only one target can be selected for the change
* @param filterNewTarget restriction to the new target
*/
public ChooseNewTargetsTargetEffect(boolean forceChange, boolean onlyOneTarget, FilterPermanent filterNewTarget) {
public ChooseNewTargetsTargetEffect(boolean forceChange, boolean onlyOneTarget) {
super(Outcome.Benefit);
this.forceChange = forceChange;
this.onlyOneTarget = onlyOneTarget;
this.filterNewTarget = filterNewTarget;
}
public ChooseNewTargetsTargetEffect(final ChooseNewTargetsTargetEffect effect) {
super(effect);
this.forceChange = effect.forceChange;
this.onlyOneTarget = effect.onlyOneTarget;
this.filterNewTarget = effect.filterNewTarget;
}
@Override
public boolean apply(Game game, Ability source) {
StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget());
if (stackObject != null) {
return stackObject.chooseNewTargets(game, source.getControllerId(), forceChange, onlyOneTarget, filterNewTarget);
return stackObject.chooseNewTargets(game, source.getControllerId(), forceChange, onlyOneTarget, null);
}
return false;
}