[C20] Fixed Haldan, Avid Arcanist's ability applying to all spells (magefree/mage#7585) (#7589)

This commit is contained in:
Alexander Novotny 2021-02-16 17:03:11 -08:00 committed by GitHub
parent 57dfba99b7
commit d167808dc8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 19 deletions

View file

@ -48,19 +48,7 @@ public final class HaldanAvidArcanist extends CardImpl {
@Override
public HaldanAvidArcanist copy() {
return new HaldanAvidArcanist(this);
}
static boolean checkCard(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (!PakoArcaneRetriever.checkWatcher(affectedControllerId, game.getCard(objectId), game)
|| !source.isControlledBy(affectedControllerId)
|| game.getState().getZone(objectId) != Zone.EXILED) {
return false;
}
Card card = game.getCard(objectId);
return card != null
&& !card.isCreature()
&& card.getCounters(game).containsKey(CounterType.FETCH);
}
}
}
class HaldanAvidArcanistCastFromExileEffect extends AsThoughEffectImpl {
@ -86,7 +74,13 @@ class HaldanAvidArcanistCastFromExileEffect extends AsThoughEffectImpl {
@Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
return HaldanAvidArcanist.checkCard(sourceId, source, affectedControllerId, game);
Card card = game.getCard(sourceId);
if (card == null || !source.isControlledBy(affectedControllerId)
|| game.getState().getZone(sourceId) != Zone.EXILED
|| !PakoArcaneRetriever.checkWatcher(affectedControllerId, card, game)) {
return false;
}
return !card.isCreature() && card.getCounters(game).containsKey(CounterType.FETCH);
}
}
@ -113,7 +107,17 @@ class HaldanAvidArcanistSpendAnyManaEffect extends AsThoughEffectImpl implements
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return true;
// The card may be on the stack, in which case it will not have a fetch counter
// on it. In this case, we will have to rely on the watcher to tell us whether
// or not it is a valid card to apply the effect to.
Zone zone;
Card card = game.getCard(objectId);
if (card == null || !source.isControlledBy(affectedControllerId)
|| (zone = game.getState().getZone(objectId)) != Zone.EXILED && zone != Zone.STACK
|| !PakoArcaneRetriever.checkWatcher(affectedControllerId, card, game)) {
return false;
}
return !card.isCreature() && (card.getCounters(game).containsKey(CounterType.FETCH) || zone == Zone.STACK);
}
@Override

View file

@ -124,13 +124,23 @@ class PakoArcaneRetrieverWatcher extends Watcher {
}
void addCard(UUID playerId, Card card, Game game) {
playerMap.computeIfAbsent(playerId, u -> new HashSet()).add(new MageObjectReference(card, game));
playerMap.computeIfAbsent(playerId, u -> new HashSet<MageObjectReference>())
.add(new MageObjectReference(card, game));
}
boolean checkCard(UUID playerId, Card card, Game game) {
return card != null && playerMap
.computeIfAbsent(playerId, u -> new HashSet<>())
if (card == null)
return false;
// If the card has been moved onto the stack (e.g. by attempting to cast), the
// number of zone change counters will be 1 more than when the pako effect
// exiled it and the watcher took a reference.
// https://github.com/magefree/mage/issues/7585
final int zoneChangeDifference = game.getState().getZone(card.getId()) == Zone.STACK ? 1 : 0;
return playerMap.computeIfAbsent(playerId, u -> new HashSet<MageObjectReference>())
.stream()
.anyMatch(mageObjectReference -> mageObjectReference.refersTo(card.getId(), game));
.anyMatch(ref -> ref.getSourceId().equals(card.getId())
&& ref.getZoneChangeCounter() == (game.getState().getZoneChangeCounter(card.getId())
- zoneChangeDifference));
}
}