mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +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.isMayChooseNewTargets() && !sa.setupTargets()) {
|
||||||
if (sa.isSpell()) {
|
if (sa.isSpell()) {
|
||||||
sa.getHostCard().ceaseToExist(false);
|
player.getGame().getAction().ceaseToExist(sa.getHostCard(), false);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -785,12 +785,12 @@ public class Game {
|
|||||||
// unattach all "Enchant Player"
|
// unattach all "Enchant Player"
|
||||||
c.removeAttachedTo(p);
|
c.removeAttachedTo(p);
|
||||||
if (c.getOwner().equals(p)) {
|
if (c.getOwner().equals(p)) {
|
||||||
for(Card cc : cards) {
|
for (Card cc : cards) {
|
||||||
cc.removeImprintedCard(c);
|
cc.removeImprintedCard(c);
|
||||||
cc.removeEncodedCard(c);
|
cc.removeEncodedCard(c);
|
||||||
cc.removeRemembered(c);
|
cc.removeRemembered(c);
|
||||||
}
|
}
|
||||||
c.ceaseToExist(false);
|
getAction().ceaseToExist(c, false);
|
||||||
// CR 603.2f owner of trigger source lost game
|
// CR 603.2f owner of trigger source lost game
|
||||||
triggerHandler.clearDelayedTrigger(c);
|
triggerHandler.clearDelayedTrigger(c);
|
||||||
} else {
|
} 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.
|
// Temporarily disable (if mode = true) actively checking static abilities.
|
||||||
private void setHoldCheckingStaticAbilities(boolean mode) {
|
private void setHoldCheckingStaticAbilities(boolean mode) {
|
||||||
holdCheckingStaticAbilities = mode;
|
holdCheckingStaticAbilities = mode;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package forge.game.ability.effects;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.GameCommand;
|
import forge.GameCommand;
|
||||||
@@ -13,12 +15,14 @@ import forge.game.card.Card;
|
|||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.card.CardFactory;
|
import forge.game.card.CardFactory;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
|
import forge.game.card.CardPredicates;
|
||||||
import forge.game.event.GameEventCardStatsChanged;
|
import forge.game.event.GameEventCardStatsChanged;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.CardTranslation;
|
import forge.util.CardTranslation;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
|
import forge.util.collect.FCollection;
|
||||||
|
|
||||||
public class CloneEffect extends SpellAbilityEffect {
|
public class CloneEffect extends SpellAbilityEffect {
|
||||||
// TODO update this method
|
// TODO update this method
|
||||||
@@ -139,10 +143,6 @@ public class CloneEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
tgtCard.updateStateForView();
|
tgtCard.updateStateForView();
|
||||||
|
|
||||||
//Clear Remembered and Imprint lists
|
|
||||||
tgtCard.clearRemembered();
|
|
||||||
tgtCard.clearImprintedCards();
|
|
||||||
|
|
||||||
// check if clone is now an Aura that needs to be attached
|
// check if clone is now an Aura that needs to be attached
|
||||||
if (tgtCard.isAura() && !tgtCard.isInZone(ZoneType.Battlefield)) {
|
if (tgtCard.isAura() && !tgtCard.isInZone(ZoneType.Battlefield)) {
|
||||||
AttachEffect.attachAuraOnIndirectEnterBattlefield(tgtCard);
|
AttachEffect.attachAuraOnIndirectEnterBattlefield(tgtCard);
|
||||||
@@ -150,12 +150,23 @@ public class CloneEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
if (sa.hasParam("Duration")) {
|
if (sa.hasParam("Duration")) {
|
||||||
final Card cloneCard = tgtCard;
|
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() {
|
final GameCommand unclone = new GameCommand() {
|
||||||
private static final long serialVersionUID = -78375985476256279L;
|
private static final long serialVersionUID = -78375985476256279L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (cloneCard.removeCloneState(ts)) {
|
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();
|
cloneCard.updateStateForView();
|
||||||
game.fireEvent(new GameEventCardStatsChanged(cloneCard));
|
game.fireEvent(new GameEventCardStatsChanged(cloneCard));
|
||||||
}
|
}
|
||||||
@@ -176,9 +187,15 @@ public class CloneEffect extends SpellAbilityEffect {
|
|||||||
sa.getHostCard().addFacedownCommand(unclone);
|
sa.getHostCard().addFacedownCommand(unclone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Clear Remembered and Imprint lists
|
||||||
|
tgtCard.clearRemembered();
|
||||||
|
tgtCard.clearImprintedCards();
|
||||||
|
|
||||||
if (sa.hasParam("RememberCloneOrigin")) {
|
if (sa.hasParam("RememberCloneOrigin")) {
|
||||||
tgtCard.addRemembered(cardToCopy);
|
tgtCard.addRemembered(cardToCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
game.fireEvent(new GameEventCardStatsChanged(tgtCard));
|
game.fireEvent(new GameEventCardStatsChanged(tgtCard));
|
||||||
} // cloneResolve
|
} // 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() {
|
public void forceTurnFaceUp() {
|
||||||
getGame().getTriggerHandler().suppressMode(TriggerType.TurnFaceUp);
|
getGame().getTriggerHandler().suppressMode(TriggerType.TurnFaceUp);
|
||||||
turnFaceUp(false, false, null);
|
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) {
|
public static final Predicate<Card> isType(final String cardType) {
|
||||||
return new Predicate<Card>() {
|
return new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2357,7 +2357,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
|
|
||||||
public void rollback() {
|
public void rollback() {
|
||||||
for (Card c : rollbackEffects) {
|
for (Card c : rollbackEffects) {
|
||||||
c.ceaseToExist(true);
|
c.getGame().getAction().ceaseToExist(c, true);
|
||||||
}
|
}
|
||||||
rollbackEffects.clear();
|
rollbackEffects.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,7 +319,9 @@ public class TriggerHandler {
|
|||||||
checkStatics |= type.equals("Battlefield");
|
checkStatics |= type.equals("Battlefield");
|
||||||
} else {
|
} else {
|
||||||
final ZoneType zone = (ZoneType) runParams.get(AbilityKey.Destination);
|
final ZoneType zone = (ZoneType) runParams.get(AbilityKey.Destination);
|
||||||
checkStatics |= zone.equals(ZoneType.Battlefield);
|
if (zone != null) {
|
||||||
|
checkStatics |= zone.equals(ZoneType.Battlefield);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -586,7 +586,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (source.isCopiedSpell() && source.isInZone(ZoneType.Stack)) {
|
if (source.isCopiedSpell() && source.isInZone(ZoneType.Stack)) {
|
||||||
source.ceaseToExist(true);
|
game.getAction().ceaseToExist(source, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2840,8 +2840,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
if (c == null) {
|
if (c == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
c.getZone().remove(c);
|
c.getGame().getAction().ceaseToExist(c, true);
|
||||||
c.ceaseToExist(true);
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(p).append(" removes ").append(c).append(" from game due to Dev Cheats.");
|
sb.append(p).append(" removes ").append(c).append(" from game due to Dev Cheats.");
|
||||||
|
|||||||
Reference in New Issue
Block a user