mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
Temporary clones: restore Remembered/Imprinted
This commit is contained in:
committed by
Michael Kamensky
parent
98600e9a19
commit
b7a475cc0a
@@ -1029,7 +1029,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
*/
|
||||
if (sa.isMayChooseNewTargets() && !sa.setupTargets()) {
|
||||
if (sa.isSpell()) {
|
||||
sa.getHostCard().ceaseToExist(false);
|
||||
player.getGame().getAction().ceaseToExist(sa.getHostCard(), false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -790,7 +790,7 @@ public class Game {
|
||||
cc.removeEncodedCard(c);
|
||||
cc.removeRemembered(c);
|
||||
}
|
||||
c.ceaseToExist(false);
|
||||
getAction().ceaseToExist(c, false);
|
||||
// CR 603.2f owner of trigger source lost game
|
||||
triggerHandler.clearDelayedTrigger(c);
|
||||
} else {
|
||||
|
||||
@@ -919,6 +919,38 @@ public class GameAction {
|
||||
}
|
||||
}
|
||||
|
||||
public void ceaseToExist(Card c, boolean skipTrig) {
|
||||
final String origin = c.getZone().getZoneType().name();
|
||||
|
||||
c.getZone().remove(c);
|
||||
c.setZone(null);
|
||||
|
||||
// CR 603.6c other players LTB triggers should work
|
||||
if (!skipTrig) {
|
||||
game.addChangeZoneLKIInfo(c);
|
||||
Card lki = null;
|
||||
CardCollectionView lastBattlefield = game.getLastStateBattlefield();
|
||||
int idx = lastBattlefield.indexOf(c);
|
||||
if (idx != -1) {
|
||||
lki = lastBattlefield.get(idx);
|
||||
}
|
||||
if (lki == null) {
|
||||
lki = CardUtil.getLKICopy(c);
|
||||
}
|
||||
if (game.getCombat() != null) {
|
||||
game.getCombat().removeFromCombat(c);
|
||||
game.getCombat().saveLKI(lki);
|
||||
}
|
||||
game.getTriggerHandler().registerActiveLTBTrigger(lki);
|
||||
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(c);
|
||||
runParams.put(AbilityKey.CardLKI, lki);
|
||||
runParams.put(AbilityKey.Origin, origin);
|
||||
game.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams, false);
|
||||
game.getTriggerHandler().runWaitingTriggers();
|
||||
}
|
||||
}
|
||||
|
||||
// Temporarily disable (if mode = true) actively checking static abilities.
|
||||
private void setHoldCheckingStaticAbilities(boolean mode) {
|
||||
holdCheckingStaticAbilities = mode;
|
||||
|
||||
@@ -3,6 +3,8 @@ package forge.game.ability.effects;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.GameCommand;
|
||||
@@ -13,12 +15,14 @@ import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardFactory;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.event.GameEventCardStatsChanged;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.CardTranslation;
|
||||
import forge.util.Localizer;
|
||||
import forge.util.collect.FCollection;
|
||||
|
||||
public class CloneEffect extends SpellAbilityEffect {
|
||||
// TODO update this method
|
||||
@@ -139,10 +143,6 @@ public class CloneEffect extends SpellAbilityEffect {
|
||||
|
||||
tgtCard.updateStateForView();
|
||||
|
||||
//Clear Remembered and Imprint lists
|
||||
tgtCard.clearRemembered();
|
||||
tgtCard.clearImprintedCards();
|
||||
|
||||
// check if clone is now an Aura that needs to be attached
|
||||
if (tgtCard.isAura() && !tgtCard.isInZone(ZoneType.Battlefield)) {
|
||||
AttachEffect.attachAuraOnIndirectEnterBattlefield(tgtCard);
|
||||
@@ -150,12 +150,23 @@ public class CloneEffect extends SpellAbilityEffect {
|
||||
|
||||
if (sa.hasParam("Duration")) {
|
||||
final Card cloneCard = tgtCard;
|
||||
// if clone is temporary, target needs old values back after
|
||||
final Iterable<Card> clonedImprinted = new CardCollection(tgtCard.getImprintedCards());
|
||||
final Iterable<Object> clonedRemembered = new FCollection<>(tgtCard.getRemembered());
|
||||
|
||||
final GameCommand unclone = new GameCommand() {
|
||||
private static final long serialVersionUID = -78375985476256279L;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (cloneCard.removeCloneState(ts)) {
|
||||
// remove values gained while being cloned
|
||||
cloneCard.clearImprintedCards();
|
||||
cloneCard.clearRemembered();
|
||||
// restore original Remembered and Imprinted, ignore cards from players who lost
|
||||
cloneCard.addImprintedCards(Iterables.filter(clonedImprinted, Predicates.not(CardPredicates.inZone(ZoneType.None))));
|
||||
cloneCard.addRemembered(Iterables.filter(clonedRemembered, Player.class));
|
||||
cloneCard.addRemembered(Iterables.filter(Iterables.filter(clonedRemembered, Card.class), CardPredicates.ownerLives()));
|
||||
cloneCard.updateStateForView();
|
||||
game.fireEvent(new GameEventCardStatsChanged(cloneCard));
|
||||
}
|
||||
@@ -176,9 +187,15 @@ public class CloneEffect extends SpellAbilityEffect {
|
||||
sa.getHostCard().addFacedownCommand(unclone);
|
||||
}
|
||||
}
|
||||
|
||||
//Clear Remembered and Imprint lists
|
||||
tgtCard.clearRemembered();
|
||||
tgtCard.clearImprintedCards();
|
||||
|
||||
if (sa.hasParam("RememberCloneOrigin")) {
|
||||
tgtCard.addRemembered(cardToCopy);
|
||||
}
|
||||
|
||||
game.fireEvent(new GameEventCardStatsChanged(tgtCard));
|
||||
} // cloneResolve
|
||||
|
||||
|
||||
@@ -6762,17 +6762,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
}
|
||||
|
||||
public void ceaseToExist(boolean skipTrig) {
|
||||
// CR 603.6c other players LTB triggers should work
|
||||
if (skipTrig) {
|
||||
getZone().remove(this);
|
||||
setZone(getOwner().getZone(ZoneType.None));
|
||||
}
|
||||
else {
|
||||
game.getAction().moveTo(ZoneType.None, this, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void forceTurnFaceUp() {
|
||||
getGame().getTriggerHandler().suppressMode(TriggerType.TurnFaceUp);
|
||||
turnFaceUp(false, false, null);
|
||||
|
||||
@@ -68,6 +68,15 @@ public final class CardPredicates {
|
||||
};
|
||||
}
|
||||
|
||||
public static final Predicate<Card> ownerLives() {
|
||||
return new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return !c.getOwner().hasLost();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static final Predicate<Card> isType(final String cardType) {
|
||||
return new Predicate<Card>() {
|
||||
@Override
|
||||
|
||||
@@ -2357,7 +2357,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
|
||||
public void rollback() {
|
||||
for (Card c : rollbackEffects) {
|
||||
c.ceaseToExist(true);
|
||||
c.getGame().getAction().ceaseToExist(c, true);
|
||||
}
|
||||
rollbackEffects.clear();
|
||||
}
|
||||
|
||||
@@ -319,9 +319,11 @@ public class TriggerHandler {
|
||||
checkStatics |= type.equals("Battlefield");
|
||||
} else {
|
||||
final ZoneType zone = (ZoneType) runParams.get(AbilityKey.Destination);
|
||||
if (zone != null) {
|
||||
checkStatics |= zone.equals(ZoneType.Battlefield);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AP
|
||||
checkStatics |= runNonStaticTriggersForPlayer(playerAP, wt, delayedTriggersWorkingCopy);
|
||||
|
||||
@@ -586,7 +586,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
}
|
||||
|
||||
if (source.isCopiedSpell() && source.isInZone(ZoneType.Stack)) {
|
||||
source.ceaseToExist(true);
|
||||
game.getAction().ceaseToExist(source, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -2840,8 +2840,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
if (c == null) {
|
||||
continue;
|
||||
}
|
||||
c.getZone().remove(c);
|
||||
c.ceaseToExist(true);
|
||||
c.getGame().getAction().ceaseToExist(c, true);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(p).append(" removes ").append(c).append(" from game due to Dev Cheats.");
|
||||
|
||||
Reference in New Issue
Block a user