* Fixed some target pointer handling.

This commit is contained in:
LevelX2 2018-02-22 17:46:23 +01:00
parent 88dd301f82
commit c02c5a175b
14 changed files with 140 additions and 108 deletions

View file

@ -94,9 +94,12 @@ class ActOfAuthorityEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent targetPermanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); Permanent targetPermanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (targetPermanent != null && new ExileTargetEffect().apply(game, source)) { if (targetPermanent != null && new ExileTargetEffect().apply(game, source)) {
Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
if (sourcePermanent != null) {
ContinuousEffect effect = new ActOfAuthorityGainControlEffect(Duration.Custom, targetPermanent.getControllerId()); ContinuousEffect effect = new ActOfAuthorityGainControlEffect(Duration.Custom, targetPermanent.getControllerId());
effect.setTargetPointer(new FixedTarget(source.getSourceId())); effect.setTargetPointer(new FixedTarget(sourcePermanent, game));
game.addEffect(effect, source); game.addEffect(effect, source);
}
return true; return true;
} }
return false; return false;

View file

@ -109,7 +109,7 @@ class AdarkarValkyrieEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
DelayedTriggeredAbility delayedAbility = new AdarkarValkyrieDelayedTriggeredAbility(new FixedTarget(this.getTargetPointer().getFirst(game, source))); DelayedTriggeredAbility delayedAbility = new AdarkarValkyrieDelayedTriggeredAbility(getTargetPointer().getFixedTarget(game, source));
game.addDelayedTriggeredAbility(delayedAbility, source); game.addDelayedTriggeredAbility(delayedAbility, source);
return false; return false;
} }

View file

@ -45,7 +45,7 @@ import mage.target.targetpointer.FixedTarget;
/** /**
* *
* @author KholdFuzion * @author KholdFuzion
*
*/ */
public class AnkhOfMishra extends CardImpl { public class AnkhOfMishra extends CardImpl {
@ -104,6 +104,6 @@ class AnkhOfMishraAbility extends TriggeredAbilityImpl {
@Override @Override
public String getRule() { public String getRule() {
return "Whenever a land enters the battlefield, Ankh of Mishra deals 2 damage to that land's controller."; return "Whenever a land enters the battlefield, {this} deals 2 damage to that land's controller.";
} }
} }

View file

@ -29,6 +29,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -79,6 +80,7 @@ public class ArbiterOfTheIdeal extends CardImpl {
class ArbiterOfTheIdealEffect extends OneShotEffect { class ArbiterOfTheIdealEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard(); private static final FilterCard filter = new FilterCard();
static { static {
filter.add(Predicates.or( filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.ARTIFACT),
@ -102,32 +104,25 @@ class ArbiterOfTheIdealEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (player == null) { MageObject sourceObject = source.getSourceObject(game);
if (controller == null || sourceObject == null) {
return false; return false;
} }
Card card = controller.getLibrary().getFromTop(game);
if (player.getLibrary().hasCards()) {
Card card = player.getLibrary().getFromTop(game);
Cards cards = new CardsImpl();
cards.add(card);
player.revealCards("Arbiter of the Ideal", cards, game);
if (card != null) { if (card != null) {
if (filter.match(card, game) && player.chooseUse(outcome, new StringBuilder("Put ").append(card.getName()).append("onto battlefield?").toString(), source, game)) { controller.revealCards(sourceObject.getIdName(), new CardsImpl(card), game);
card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId()); if (filter.match(card, game) && controller.chooseUse(outcome, "Put " + card.getName() + "onto battlefield?", source, game)) {
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
Permanent permanent = game.getPermanent(card.getId()); Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) { if (permanent != null) {
permanent.addCounters(new Counter("Manifestation"), source, game); permanent.addCounters(new Counter("Manifestation"), source, game);
ContinuousEffect effect = new AddCardTypeTargetEffect(Duration.Custom, CardType.ENCHANTMENT); ContinuousEffect effect = new AddCardTypeTargetEffect(Duration.Custom, CardType.ENCHANTMENT);
effect.setTargetPointer(new FixedTarget(permanent.getId())); effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source); game.addEffect(effect, source);
} }
} }
} }
return true; return true;
} }
return false;
}
} }

View file

@ -29,23 +29,18 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect; import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
/** /**
* @author Loki * @author Loki
@ -75,8 +70,9 @@ public class ArchonOfRedemption extends CardImpl {
} }
class ArchonOfRedemptionTriggeredAbility extends TriggeredAbilityImpl { class ArchonOfRedemptionTriggeredAbility extends TriggeredAbilityImpl {
ArchonOfRedemptionTriggeredAbility() { ArchonOfRedemptionTriggeredAbility() {
super(Zone.BATTLEFIELD, new ArchonOfRedemptionEffect(), true); super(Zone.BATTLEFIELD, null, true);
} }
ArchonOfRedemptionTriggeredAbility(final ArchonOfRedemptionTriggeredAbility ability) { ArchonOfRedemptionTriggeredAbility(final ArchonOfRedemptionTriggeredAbility ability) {
@ -95,15 +91,13 @@ class ArchonOfRedemptionTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
UUID targetId = event.getTargetId(); Permanent permanent = game.getPermanent(event.getTargetId());
Permanent permanent = game.getPermanent(targetId); if (permanent.getControllerId().equals(getControllerId())
if (permanent.getControllerId().equals(this.controllerId)
&& permanent.isCreature() && permanent.isCreature()
&& (targetId.equals(this.getSourceId()) && (permanent.getId().equals(getSourceId())
|| (permanent.getAbilities().contains(FlyingAbility.getInstance()) && !targetId.equals(this.getSourceId())))) { || (permanent.getAbilities().contains(FlyingAbility.getInstance())))) {
for (Effect effect : this.getEffects()) { this.getEffects().clear();
effect.setTargetPointer(new FixedTarget(event.getTargetId())); this.addEffect(new GainLifeEffect(permanent.getPower().getValue()));
}
return true; return true;
} }
return false; return false;
@ -111,35 +105,6 @@ class ArchonOfRedemptionTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public String getRule() { public String getRule() {
return "Whenever {this} or another creature with flying enters the battlefield under your control, you may gain life equal to that creature's power"; return "Whenever {this} or another creature with flying enters the battlefield under your control, you may gain life equal to that creature's power.";
}
}
class ArchonOfRedemptionEffect extends OneShotEffect {
ArchonOfRedemptionEffect() {
super(Outcome.GainLife);
}
ArchonOfRedemptionEffect(final ArchonOfRedemptionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent p = game.getPermanent(targetPointer.getFirst(game, source));
Player player = game.getPlayer(source.getControllerId());
if (p == null) {
p = (Permanent) game.getLastKnownInformation(targetPointer.getFirst(game, source), Zone.BATTLEFIELD);
}
if (p != null && player != null) {
player.gainLife(p.getPower().getValue(), game);
return true;
}
return false;
}
@Override
public ArchonOfRedemptionEffect copy() {
return new ArchonOfRedemptionEffect(this);
} }
} }

View file

@ -104,11 +104,8 @@ class ArrogantBloodlordTriggeredAbility extends TriggeredAbilityImpl {
&& Objects.equals(blocked, arrogantBloodlord)) { && Objects.equals(blocked, arrogantBloodlord)) {
return true; return true;
} }
if (blocker != null && Objects.equals(blocker, arrogantBloodlord) return blocker != null && Objects.equals(blocker, arrogantBloodlord)
&& game.getPermanent(event.getTargetId()).getPower().getValue() < 2) { && game.getPermanent(event.getTargetId()).getPower().getValue() < 2;
return true;
}
return false;
} }
@Override @Override
@ -133,7 +130,7 @@ class ArrogantBloodlordEffect extends OneShotEffect {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) { if (permanent != null) {
AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()); AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect());
delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(source.getSourceId())); delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game));
game.addDelayedTriggeredAbility(delayedAbility, source); game.addDelayedTriggeredAbility(delayedAbility, source);
return true; return true;
} }

View file

@ -45,6 +45,7 @@ import mage.constants.Zone;
import mage.game.Controllable; import mage.game.Controllable;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.Target; import mage.target.Target;
import mage.target.Targets; import mage.target.Targets;
@ -535,6 +536,17 @@ public interface Ability extends Controllable, Serializable {
*/ */
MageObject getSourceObjectIfItStillExists(Game game); MageObject getSourceObjectIfItStillExists(Game game);
/**
* Returns the permanent that actually existed while the ability triggerd or
* an ability was activated only if it has not changed zone meanwhile. If
* not set yet, the current permanent if one exists will be retrieved from
* the game and returned.
*
* @param game
* @return
*/
Permanent getSourcePermanentIfItStillExists(Game game);
String getTargetDescription(Targets targets, Game game); String getTargetDescription(Targets targets, Game game);
void setCanFizzle(boolean canFizzle); void setCanFizzle(boolean canFizzle);

View file

@ -1211,6 +1211,19 @@ public abstract class AbilityImpl implements Ability {
return null; return null;
} }
@Override
public Permanent getSourcePermanentIfItStillExists(Game game) {
if (sourceObject == null) {
setSourceObject(game.getObject(getSourceId()), game);
}
if (sourceObject instanceof Permanent) {
if (game.getState().getZoneChangeCounter(getSourceId()) == getSourceObjectZoneChangeCounter()) {
return (Permanent) sourceObject;
}
}
return null;
}
@Override @Override
public int getSourceObjectZoneChangeCounter() { public int getSourceObjectZoneChangeCounter() {
return sourceObjectZoneChangeCounter; return sourceObjectZoneChangeCounter;

View file

@ -50,6 +50,7 @@ import mage.constants.*;
import mage.game.Game; import mage.game.Game;
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.players.Player; import mage.players.Player;
import mage.target.Target; import mage.target.Target;
import mage.target.Targets; import mage.target.Targets;
@ -529,12 +530,17 @@ public class StackAbility extends StackObjImpl implements Ability {
@Override @Override
public MageObject getSourceObject(Game game) { public MageObject getSourceObject(Game game) {
return game.getBaseObject(getSourceId()); return this.ability.getSourceObject(game);
} }
@Override @Override
public MageObject getSourceObjectIfItStillExists(Game game) { public MageObject getSourceObjectIfItStillExists(Game game) {
throw new UnsupportedOperationException("Not supported."); return this.ability.getSourceObjectIfItStillExists(game);
}
@Override
public Permanent getSourcePermanentIfItStillExists(Game game) {
return this.ability.getSourcePermanentIfItStillExists(game);
} }
@Override @Override

View file

@ -82,4 +82,16 @@ public class FirstTargetPointer implements TargetPointer {
public TargetPointer copy() { public TargetPointer copy() {
return new FirstTargetPointer(this); return new FirstTargetPointer(this);
} }
@Override
public FixedTarget getFixedTarget(Game game, Ability source) {
this.init(game, source);
UUID firstId = getFirst(game, source);
if (firstId != null) {
return new FixedTarget(firstId, game.getState().getZoneChangeCounter(firstId));
}
return null;
}
} }

View file

@ -1,15 +1,14 @@
package mage.target.targetpointer; package mage.target.targetpointer;
import mage.abilities.Ability;
import mage.cards.Card;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability;
import mage.cards.Card;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
public class FixedTarget implements TargetPointer { public class FixedTarget implements TargetPointer {
@ -65,10 +64,7 @@ public class FixedTarget implements TargetPointer {
public void init(Game game, Ability source) { public void init(Game game, Ability source) {
if (!initialized) { if (!initialized) {
initialized = true; initialized = true;
Card card = game.getCard(targetId); this.zoneChangeCounter = game.getState().getZoneChangeCounter(targetId);
if (card != null) {
this.zoneChangeCounter = card.getZoneChangeCounter(game);
}
} }
} }
@ -121,4 +117,10 @@ public class FixedTarget implements TargetPointer {
return permanent; return permanent;
} }
@Override
public FixedTarget getFixedTarget(Game game, Ability source) {
init(game, source);
return this;
}
} }

View file

@ -1,11 +1,10 @@
package mage.target.targetpointer; package mage.target.targetpointer;
import java.util.*;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.cards.Card; import mage.cards.Card;
import mage.game.Game; import mage.game.Game;
import java.util.*;
public class SecondTargetPointer implements TargetPointer { public class SecondTargetPointer implements TargetPointer {
private Map<UUID, Integer> zoneChangeCounter = new HashMap<>(); private Map<UUID, Integer> zoneChangeCounter = new HashMap<>();
@ -72,4 +71,15 @@ public class SecondTargetPointer implements TargetPointer {
public TargetPointer copy() { public TargetPointer copy() {
return new SecondTargetPointer(this); return new SecondTargetPointer(this);
} }
@Override
public FixedTarget getFixedTarget(Game game, Ability source) {
this.init(game, source);
UUID firstId = getFirst(game, source);
if (firstId != null) {
return new FixedTarget(firstId, game.getState().getZoneChangeCounter(firstId));
}
return null;
}
} }

View file

@ -7,8 +7,14 @@ import mage.abilities.Ability;
import mage.game.Game; import mage.game.Game;
public interface TargetPointer extends Serializable { public interface TargetPointer extends Serializable {
void init(Game game, Ability source); void init(Game game, Ability source);
List<UUID> getTargets(Game game, Ability source); List<UUID> getTargets(Game game, Ability source);
UUID getFirst(Game game, Ability source); UUID getFirst(Game game, Ability source);
TargetPointer copy(); TargetPointer copy();
FixedTarget getFixedTarget(Game game, Ability source);
} }

View file

@ -84,4 +84,15 @@ public class ThirdTargetPointer implements TargetPointer {
public TargetPointer copy() { public TargetPointer copy() {
return new ThirdTargetPointer(this); return new ThirdTargetPointer(this);
} }
@Override
public FixedTarget getFixedTarget(Game game, Ability source) {
this.init(game, source);
UUID firstId = getFirst(game, source);
if (firstId != null) {
return new FixedTarget(firstId, game.getState().getZoneChangeCounter(firstId));
}
return null;
}
} }