* Copy activated ability - fixed that it raise error on triggering on copied permanents;

This commit is contained in:
Oleg Agafonov 2019-12-18 18:16:16 +04:00
parent 23ef0e4269
commit ff1299cca9
2 changed files with 107 additions and 11 deletions

View file

@ -29,6 +29,7 @@ import mage.filter.Filter;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.filter.predicate.permanent.ControllerIdPredicate;
@ -45,7 +46,6 @@ import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
import mage.game.stack.Spell;
import mage.game.stack.SpellStack;
import mage.game.stack.StackAbility;
import mage.game.stack.StackObject;
import mage.game.turn.Phase;
import mage.game.turn.Step;
@ -69,7 +69,6 @@ import java.io.IOException;
import java.io.Serializable;
import java.util.*;
import java.util.Map.Entry;
import mage.filter.common.FilterControlledPermanent;
public abstract class GameImpl implements Game, Serializable {
@ -452,7 +451,17 @@ public abstract class GameImpl implements Game, Serializable {
public Spell getSpellOrLKIStack(UUID spellId) {
Spell spell = state.getStack().getSpell(spellId);
if (spell == null) {
spell = (Spell) this.getLastKnownInformation(spellId, Zone.STACK);
MageObject obj = this.getLastKnownInformation(spellId, Zone.STACK);
if (obj instanceof Spell) {
spell = (Spell) obj;
} else {
if (obj != null) {
// copied activated abilities is StackAbility (not spell) and must be ignored here
// if not then java.lang.ClassCastException: mage.game.stack.StackAbility cannot be cast to mage.game.stack.Spell
// see SyrCarahTheBoldTest as example
// logger.error("getSpellOrLKIStack got non spell id - " + obj.getClass().getName() + " - " + obj.getName(), new Throwable());
}
}
}
return spell;
}
@ -1471,7 +1480,7 @@ public abstract class GameImpl implements Game, Serializable {
/**
* @param emblem
* @param sourceObject
* @param toPlayerId controller and owner of the emblem
* @param toPlayerId controller and owner of the emblem
*/
@Override
public void addEmblem(Emblem emblem, MageObject sourceObject, UUID toPlayerId) {
@ -1489,8 +1498,8 @@ public abstract class GameImpl implements Game, Serializable {
/**
* @param plane
* @param sourceObject
* @param toPlayerId controller and owner of the plane (may only be one per
* game..)
* @param toPlayerId controller and owner of the plane (may only be one per
* game..)
* @return boolean - whether the plane was added successfully or not
*/
@Override
@ -1719,7 +1728,7 @@ public abstract class GameImpl implements Game, Serializable {
break;
}
// triggered abilities that don't use the stack have to be executed first (e.g. Banisher Priest Return exiled creature
for (Iterator<TriggeredAbility> it = abilities.iterator(); it.hasNext();) {
for (Iterator<TriggeredAbility> it = abilities.iterator(); it.hasNext(); ) {
TriggeredAbility triggeredAbility = it.next();
if (!triggeredAbility.isUsesStack()) {
state.removeTriggeredAbility(triggeredAbility);
@ -2454,7 +2463,7 @@ public abstract class GameImpl implements Game, Serializable {
}
//20100423 - 800.4a
Set<Card> toOutside = new HashSet<>();
for (Iterator<Permanent> it = getBattlefield().getAllPermanents().iterator(); it.hasNext();) {
for (Iterator<Permanent> it = getBattlefield().getAllPermanents().iterator(); it.hasNext(); ) {
Permanent perm = it.next();
if (perm.isOwnedBy(playerId)) {
if (perm.getAttachedTo() != null) {
@ -2497,7 +2506,7 @@ public abstract class GameImpl implements Game, Serializable {
player.moveCards(toOutside, Zone.OUTSIDE, null, this);
// triggered abilities that don't use the stack have to be executed
List<TriggeredAbility> abilities = state.getTriggered(player.getId());
for (Iterator<TriggeredAbility> it = abilities.iterator(); it.hasNext();) {
for (Iterator<TriggeredAbility> it = abilities.iterator(); it.hasNext(); ) {
TriggeredAbility triggeredAbility = it.next();
if (!triggeredAbility.isUsesStack()) {
state.removeTriggeredAbility(triggeredAbility);
@ -2517,7 +2526,7 @@ public abstract class GameImpl implements Game, Serializable {
// Remove cards from the player in all exile zones
for (ExileZone exile : this.getExile().getExileZones()) {
for (Iterator<UUID> it = exile.iterator(); it.hasNext();) {
for (Iterator<UUID> it = exile.iterator(); it.hasNext(); ) {
Card card = this.getCard(it.next());
if (card != null && card.isOwnedBy(playerId)) {
it.remove();
@ -2527,7 +2536,7 @@ public abstract class GameImpl implements Game, Serializable {
//Remove all commander/emblems/plane the player controls
boolean addPlaneAgain = false;
for (Iterator<CommandObject> it = this.getState().getCommand().iterator(); it.hasNext();) {
for (Iterator<CommandObject> it = this.getState().getCommand().iterator(); it.hasNext(); ) {
CommandObject obj = it.next();
if (obj.isControlledBy(playerId)) {
if (obj instanceof Emblem) {