Added framework method for copying a StackAbility without casting it.

Modified the effects doing so with the new method.
This commit is contained in:
emerald000 2016-04-17 23:55:11 -04:00
parent b9ab16d945
commit 8823839a42
34 changed files with 158 additions and 313 deletions

View file

@ -34,6 +34,7 @@ import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.game.stack.StackObject;
import mage.players.Player;
/**
@ -57,16 +58,16 @@ public class CopyTargetSpellEffect extends OneShotEffect {
spell = (Spell) game.getLastKnownInformation(targetPointer.getFirst(game, source), Zone.STACK);
}
if (spell != null) {
Spell copy = spell.copySpell(source.getControllerId());;
game.getStack().push(copy);
copy.chooseNewTargets(game, source.getControllerId());
StackObject newStackObject = spell.createCopyOnStack(game, source, source.getControllerId(), true);
Player player = game.getPlayer(source.getControllerId());
String activateMessage = copy.getActivatedMessage(game);
if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6);
}
if (!game.isSimulation()) {
game.informPlayers(player.getLogName() + activateMessage);
if (player != null && newStackObject != null && newStackObject instanceof Spell) {
String activateMessage = ((Spell) newStackObject).getActivatedMessage(game);
if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6);
}
if (!game.isSimulation()) {
game.informPlayers(player.getLogName() + activateMessage);
}
}
return true;
}

View file

@ -140,10 +140,7 @@ class EpicPushEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
if (spell != null) {
// don't change the targets of the in the origin copied spell
Spell copySpell = spell.copy();
game.getStack().push(copySpell);
copySpell.chooseNewTargets(game, source.getControllerId());
spell.createCopyOnStack(game, source, source.getControllerId(), true);
return true;
}

View file

@ -52,6 +52,7 @@ import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.common.TargetControlledPermanent;
@ -292,11 +293,9 @@ class ConspireEffect extends OneShotEffect {
if (controller != null && conspiredSpell != null) {
Card card = game.getCard(conspiredSpell.getSourceId());
if (card != null) {
Spell copy = conspiredSpell.copySpell(source.getControllerId());
game.getStack().push(copy);
copy.chooseNewTargets(game, source.getControllerId());
if (!game.isSimulation()) {
game.informPlayers(controller.getLogName() + copy.getActivatedMessage(game));
StackObject newStackObject = conspiredSpell.createCopyOnStack(game, source, source.getControllerId(), true);
if (newStackObject != null && newStackObject instanceof Spell && !game.isSimulation()) {
game.informPlayers(controller.getLogName() + ((Spell) newStackObject).getActivatedMessage(game));
}
return true;
}

View file

@ -109,9 +109,7 @@ class GravestormEffect extends OneShotEffect {
game.informPlayers("Gravestorm: " + spell.getName() + " will be copied " + gravestormCount + " time" + (gravestormCount > 1 ? "s" : ""));
}
for (int i = 0; i < gravestormCount; i++) {
Spell copy = spell.copySpell(source.getControllerId());
game.getStack().push(copy);
copy.chooseNewTargets(game, source.getControllerId());
spell.createCopyOnStack(game, source, source.getControllerId(), true);
}
}
}

View file

@ -247,11 +247,9 @@ class ReplicateCopyEffect extends OneShotEffect {
}
// create the copies
for (int i = 0; i < replicateCount; i++) {
Spell copy = spell.copySpell(source.getControllerId());
game.getStack().push(copy);
copy.chooseNewTargets(game, source.getControllerId());
if (!game.isSimulation()) {
game.informPlayers(controller.getLogName() + copy.getActivatedMessage(game));
StackObject newStackObject = spell.createCopyOnStack(game, source, source.getControllerId(), true);
if (newStackObject != null && newStackObject instanceof Spell && !game.isSimulation()) {
game.informPlayers(controller.getLogName() + ((Spell) newStackObject).getActivatedMessage(game));
}
}
return true;

View file

@ -109,9 +109,7 @@ class StormEffect extends OneShotEffect {
game.informPlayers("Storm: " + spell.getLogName() + " will be copied " + stormCount + " time" + (stormCount > 1 ? "s" : ""));
}
for (int i = 0; i < stormCount; i++) {
Spell copy = spell.copySpell(source.getControllerId());
game.getStack().push(copy);
copy.chooseNewTargets(game, source.getControllerId());
spell.createCopyOnStack(game, source, source.getControllerId(), true);
}
}
}

View file

@ -125,6 +125,8 @@ public class GameEvent implements Serializable {
*/
SPELL_CAST,
ACTIVATE_ABILITY, ACTIVATED_ABILITY,
TRIGGERED_ABILITY,
COPIED_STACKOBJECT,
/* ADD_MANA
targetId id of the ability that added the mana
sourceId sourceId of the ability that added the mana

View file

@ -56,6 +56,8 @@ import mage.constants.ZoneDetail;
import mage.counters.Counter;
import mage.counters.Counters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
@ -873,4 +875,14 @@ public class Spell extends StackObjImpl implements Card {
throw new UnsupportedOperationException("Not supported for Spell");
}
@Override
public StackObject createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets) {
Spell copy = this.copySpell(newControllerId);
game.getStack().push(copy);
if (chooseNewTargets) {
copy.chooseNewTargets(game, newControllerId);
}
game.fireEvent(new GameEvent(EventType.COPIED_STACKOBJECT, copy.getId(), this.getId(), newControllerId));
return copy;
}
}

View file

@ -580,4 +580,21 @@ public class StackAbility extends StackObjImpl implements Ability {
public void setCanFizzle(boolean canFizzle) {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public StackObject createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets) {
Ability newAbility = this.copy();
newAbility.newId();
StackAbility newStackAbility = new StackAbility(newAbility, newControllerId);
game.getStack().push(newStackAbility);
if (chooseNewTargets && newAbility.getTargets().size() > 0) {
Player controller = game.getPlayer(newControllerId);
if (controller.chooseUse(newAbility.getEffects().get(0).getOutcome(), "Choose new targets?", source, game)) {
newAbility.getTargets().clearChosen();
newAbility.getTargets().chooseTargets(newAbility.getEffects().get(0).getOutcome(), newControllerId, newAbility, false, game);
}
}
game.fireEvent(new GameEvent(GameEvent.EventType.COPIED_STACKOBJECT, newStackAbility.getId(), this.getId(), newControllerId));
return newStackAbility;
}
}

View file

@ -50,6 +50,8 @@ public interface StackObject extends MageObject, Controllable {
// int getConvertedManaCost();
boolean chooseNewTargets(Game game, UUID playerId, boolean forceChange, boolean onlyOneTarget, FilterPermanent filterNewTarget);
StackObject createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets);
@Override
StackObject copy();

View file

@ -1239,6 +1239,9 @@ public abstract class PlayerImpl implements Player, Serializable {
if (!ability.isUsesStack()) {
ability.resolve(game);
}
else {
game.fireEvent(new GameEvent(EventType.TRIGGERED_ABILITY, ability.getId(), ability.getSourceId(), ability.getControllerId()));
}
game.removeBookmark(bookmark);
return true;
}