mirror of
https://github.com/magefree/mage.git
synced 2026-01-09 12:22:10 -08:00
* Rally the Ancestors - Fixed that creatures cards were moved to exile also if already in the graveyard. Problem was that the zoneChangeCounter was not raised as a permanent card left the battlefield. So some more fixes were neccessary for implementations that are based on this fixed zoneChangeCounter of permanents leaving the battlefield. I guess there will be some more bugs caused by this change but I guess this is the correct way to go.
This commit is contained in:
parent
dbbbbc0279
commit
faa2b0a0bf
18 changed files with 77 additions and 37 deletions
|
|
@ -76,7 +76,11 @@ public abstract class DelayedTriggeredAbility extends TriggeredAbilityImpl {
|
|||
return triggerOnlyOnce;
|
||||
}
|
||||
|
||||
public void init(Game game) {};
|
||||
public void init(Game game) {
|
||||
for (Effect effect: this.getEffects()) {
|
||||
effect.getTargetPointer().init(game, this);
|
||||
}
|
||||
};
|
||||
|
||||
public boolean isInactive(Game game) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -61,14 +61,6 @@ public class AtTheBeginOfNextEndStepDelayedTriggeredAbility extends DelayedTrigg
|
|||
this.targetController = ability.targetController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Game game) {
|
||||
super.init(game);
|
||||
for (Effect effect: this.getEffects()) {
|
||||
effect.getTargetPointer().init(game, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == EventType.END_TURN_STEP_PRE) {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,8 @@ class ReturnExiledPermanentsEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
ExileZone exile = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
// because source already changed zone we have to get previous related exile zone
|
||||
ExileZone exile = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source.getSourceId(), true));
|
||||
if (exile != null) {
|
||||
LinkedList<UUID> cards = new LinkedList<>(exile);
|
||||
for (UUID cardId : cards) {
|
||||
|
|
|
|||
|
|
@ -74,10 +74,12 @@ public class ManifestEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Ability newSource = source.copy();
|
||||
newSource.setWorksFaceDown(true);
|
||||
List<Card> cards = controller.getLibrary().getTopCards(game, amount);
|
||||
for (Card card: cards) {
|
||||
card.setFaceDown(true);
|
||||
controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId());
|
||||
controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId());
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
permanent.setManifested(true);
|
||||
|
|
@ -90,7 +92,7 @@ public class ManifestEffect extends OneShotEffect {
|
|||
}
|
||||
ContinuousEffect effect = new BecomesFaceDownCreatureEffect(manaCosts, true, Duration.Custom, FaceDownType.MANIFESTED);
|
||||
effect.setTargetPointer(new FixedTarget(card.getId()));
|
||||
game.addEffect(effect, source);
|
||||
game.addEffect(effect, newSource);
|
||||
}
|
||||
}
|
||||
game.applyEffects(); // to apply before ETB triggered or replace Effects are executed
|
||||
|
|
|
|||
|
|
@ -78,10 +78,12 @@ public class ManifestTargetPlayerEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
if (targetPlayer != null) {
|
||||
Ability newSource = source.copy();
|
||||
newSource.setWorksFaceDown(true);
|
||||
List<Card> cards = targetPlayer.getLibrary().getTopCards(game, amount);
|
||||
for (Card card: cards) {
|
||||
card.setFaceDown(true);
|
||||
targetPlayer.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId());
|
||||
targetPlayer.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId());
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
permanent.setManifested(true);
|
||||
|
|
@ -94,7 +96,7 @@ public class ManifestTargetPlayerEffect extends OneShotEffect {
|
|||
}
|
||||
ContinuousEffect effect = new BecomesFaceDownCreatureEffect(manaCosts, true, Duration.Custom, FaceDownType.MANIFESTED);
|
||||
effect.setTargetPointer(new FixedTarget(card.getId()));
|
||||
game.addEffect(effect, source);
|
||||
game.addEffect(effect, newSource);
|
||||
} }
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
|
|||
ruleText = sb.toString();
|
||||
|
||||
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BecomesFaceDownCreatureEffect(morphCosts, FaceDownType.MORPHED));
|
||||
ability.setWorksFaceDown(true);
|
||||
ability.setRuleVisible(false);
|
||||
card.addAbility(ability);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -36,9 +37,9 @@ public class UndyingAbility extends DiesTriggeredAbility {
|
|||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (super.checkTrigger(event, game)) {
|
||||
Permanent p = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
|
||||
if (!p.getCounters().containsKey(CounterType.P1P1) || p.getCounters().getCount(CounterType.P1P1) == 0) {
|
||||
game.getState().setValue(new StringBuilder("undying").append(getSourceId()).toString(), new FixedTarget(p.getId()));
|
||||
Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
|
||||
if (!permanent.getCounters().containsKey(CounterType.P1P1) || permanent.getCounters().getCount(CounterType.P1P1) == 0) {
|
||||
game.getState().setValue("undying" + getSourceId(),permanent.getId());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -109,8 +110,10 @@ class UndyingReplacementEffect extends ReplacementEffectImpl {
|
|||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (event.getTargetId().equals(source.getSourceId())) {
|
||||
Object fixedTarget = game.getState().getValue(new StringBuilder("undying").append(source.getSourceId()).toString());
|
||||
if (fixedTarget instanceof FixedTarget && ((FixedTarget) fixedTarget).getFirst(game, source).equals(source.getSourceId())) {
|
||||
// Check if undying condition is true
|
||||
UUID target = (UUID) game.getState().getValue("undying" + source.getSourceId());
|
||||
if (target.equals(source.getSourceId())) {
|
||||
game.getState().setValue("undying" + source.getSourceId(), null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ public interface Card extends MageObject {
|
|||
void assignNewId();
|
||||
|
||||
int getZoneChangeCounter();
|
||||
void updateZoneChangeCounter();
|
||||
|
||||
void addInfo(String key, String value);
|
||||
|
||||
|
|
|
|||
|
|
@ -665,7 +665,8 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
return zoneChangeCounter;
|
||||
}
|
||||
|
||||
private void updateZoneChangeCounter() {
|
||||
@Override
|
||||
public void updateZoneChangeCounter() {
|
||||
zoneChangeCounter++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,9 +135,10 @@ public class PermanentCard extends PermanentImpl {
|
|||
Zone fromZone = game.getState().getZone(objectId);
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller != null && controller.removeFromBattlefield(this, game)) {
|
||||
Card originalCard = game.getCard(this.getId());
|
||||
if (isFaceDown()) {
|
||||
setFaceDown(false);
|
||||
game.getCard(this.getId()).setFaceDown(false); //TODO: Do this in a better way
|
||||
originalCard.setFaceDown(false); //TODO: Do this in a better way
|
||||
}
|
||||
ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, controllerId, fromZone, toZone, appliedEffects);
|
||||
if (!game.replaceEvent(event)) {
|
||||
|
|
@ -145,6 +146,7 @@ public class PermanentCard extends PermanentImpl {
|
|||
game.rememberLKI(objectId, Zone.BATTLEFIELD, this);
|
||||
if (owner != null) {
|
||||
this.setControllerId(ownerId); // neccessary for e.g. abilities in graveyard or hand to not have a controller != owner
|
||||
originalCard.updateZoneChangeCounter();
|
||||
switch (event.getToZone()) {
|
||||
case GRAVEYARD:
|
||||
owner.putInGraveyard(card, game, !flag);
|
||||
|
|
@ -195,6 +197,8 @@ public class PermanentCard extends PermanentImpl {
|
|||
ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, ownerId, fromZone, Zone.EXILED, appliedEffects);
|
||||
if (!game.replaceEvent(event)) {
|
||||
game.rememberLKI(objectId, Zone.BATTLEFIELD, this);
|
||||
// update zone change counter of original card
|
||||
game.getCard(this.getId()).updateZoneChangeCounter();
|
||||
if (exileId == null) {
|
||||
game.getExile().getPermanentExile().add(card);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ import java.util.Map;
|
|||
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 FirstTargetPointer implements TargetPointer {
|
||||
|
||||
|
|
@ -47,7 +49,12 @@ public class FirstTargetPointer implements TargetPointer {
|
|||
Card card = game.getCard(targetId);
|
||||
if (card != null && zoneChangeCounter.containsKey(targetId)
|
||||
&& card.getZoneChangeCounter() != zoneChangeCounter.get(targetId)) {
|
||||
continue;
|
||||
// because if dies trigger has to trigger as permanent has already moved zone, we have to check if target was on the battlefield immed. before
|
||||
// but no longer if new permanent is already on the battlefield
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(targetId);
|
||||
if (permanent == null || permanent.getZoneChangeCounter() != zoneChangeCounter.get(targetId)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
target.add(targetId);
|
||||
}
|
||||
|
|
@ -62,7 +69,12 @@ public class FirstTargetPointer implements TargetPointer {
|
|||
Card card = game.getCard(targetId);
|
||||
if (card != null && zoneChangeCounter.containsKey(targetId)
|
||||
&& card.getZoneChangeCounter() != zoneChangeCounter.get(targetId)) {
|
||||
return null;
|
||||
// because if dies trigger has to trigger as permanent has already moved zone, we have to check if target was on the battlefield immed. before
|
||||
// but no longer if new permanent is already on the battlefield
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(targetId);
|
||||
if (permanent == null || permanent.getZoneChangeCounter() != zoneChangeCounter.get(targetId)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return targetId;
|
||||
|
|
|
|||
|
|
@ -479,7 +479,11 @@ public class CardUtil {
|
|||
}
|
||||
|
||||
public static UUID getCardExileZoneId(Game game, UUID sourceId) {
|
||||
String key = getCardZoneString("SourceExileZone", sourceId, game);
|
||||
return getCardExileZoneId(game, sourceId, false);
|
||||
}
|
||||
|
||||
public static UUID getCardExileZoneId(Game game, UUID sourceId, boolean previous) {
|
||||
String key = getCardZoneString("SourceExileZone", sourceId, game, previous);
|
||||
UUID exileId = (UUID) game.getState().getValue(key);
|
||||
if (exileId == null) {
|
||||
exileId = UUID.randomUUID();
|
||||
|
|
@ -499,6 +503,11 @@ public class CardUtil {
|
|||
* @return
|
||||
*/
|
||||
public static String getCardZoneString(String text, UUID cardId, Game game) {
|
||||
return getCardZoneString(text, cardId, game, false);
|
||||
}
|
||||
|
||||
public static String getCardZoneString(String text, UUID cardId, Game game, boolean previous) {
|
||||
|
||||
StringBuilder uniqueString = new StringBuilder();
|
||||
if (text != null) {
|
||||
uniqueString.append(text);
|
||||
|
|
@ -506,7 +515,7 @@ public class CardUtil {
|
|||
uniqueString.append(cardId);
|
||||
Card card = game.getCard(cardId); // if called for a token, the id is enough
|
||||
if (card != null) {
|
||||
uniqueString.append(card.getZoneChangeCounter());
|
||||
uniqueString.append(previous ? card.getZoneChangeCounter() - 1: card.getZoneChangeCounter());
|
||||
}
|
||||
return uniqueString.toString();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue