From 7e65a16f2a444796438df1068591bd843c838c55 Mon Sep 17 00:00:00 2001 From: Myrd Date: Sat, 2 Jan 2016 01:35:12 +0000 Subject: [PATCH] Trying to make GameState properly restore commander state - still not fully there. --- .../src/main/java/forge/ai/GameState.java | 20 +++++++-- .../main/java/forge/game/player/Player.java | 42 ++++++++++--------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/GameState.java b/forge-ai/src/main/java/forge/ai/GameState.java index 2cef1991eb5..11c77929966 100644 --- a/forge-ai/src/main/java/forge/ai/GameState.java +++ b/forge-ai/src/main/java/forge/ai/GameState.java @@ -12,6 +12,7 @@ import java.util.Map.Entry; import forge.card.CardStateName; import forge.game.Game; +import forge.game.ability.effects.DetachedCardEffect; import forge.game.card.Card; import forge.game.card.CardCollection; import forge.game.card.CardCollectionView; @@ -20,6 +21,7 @@ import forge.game.card.CounterType; import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.trigger.TriggerType; +import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; import forge.item.IPaperCard; import forge.util.collect.FCollectionView; @@ -87,6 +89,9 @@ public abstract class GameState { aiCardTexts.put(zone, ""); humanCardTexts.put(zone, ""); for (Card card : game.getCardsIn(zone)) { + if (card instanceof DetachedCardEffect) { + continue; + } addCard(zone, card.getOwner() == ai ? aiCardTexts : humanCardTexts, card); } } @@ -102,6 +107,9 @@ public abstract class GameState { } else { newText.append(c.getPaperCard().getName()); } + if (c.isCommander()) { + newText.append("|IsCommander:True"); + } if (zoneType == ZoneType.Battlefield) { if (c.isTapped()) { newText.append("|Tapped:True"); @@ -207,13 +215,14 @@ public abstract class GameState { private void setupPlayerState(int life, Map cardTexts, final Player p) { Map playerCards = new EnumMap(ZoneType.class); - for(Entry kv : cardTexts.entrySet()) { + for (Entry kv : cardTexts.entrySet()) { String value = kv.getValue(); playerCards.put(kv.getKey(), processCardsForZone(value.isEmpty() ? new String[0] : value.split(";"), p)); } if (life >= 0) p.setLife(life, null); for (Entry kv : playerCards.entrySet()) { + PlayerZone zone = p.getZone(kv.getKey()); if (kv.getKey() == ZoneType.Battlefield) { List cards = new ArrayList(); for (final Card c : kv.getValue()) { @@ -221,7 +230,7 @@ public abstract class GameState { cards.add(c); } } - p.getZone(kv.getKey()).setCards(cards); + zone.setCards(cards); for (final Card c : kv.getValue()) { if (c.isToken()) { continue; @@ -234,7 +243,7 @@ public abstract class GameState { c.setSickness(sickness); } } else { - p.getZone(kv.getKey()).setCards(kv.getValue()); + zone.setCards(kv.getValue()); } } } @@ -282,6 +291,11 @@ public abstract class GameState { c.setSickness(true); } else if (info.equalsIgnoreCase("FaceDown:True")) { c.setState(CardStateName.FaceDown, true); + } else if (info.equalsIgnoreCase("IsCommander:True")) { + // TODO: This doesn't seem to properly restore the ability to play the commander. Why? + c.setCommander(true); + player.setCommander(c); + player.getZone(ZoneType.Command).add(Player.createCommanderEffect(player.getGame(), c)); } } diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index 6e6239b9f84..d9ca1dd1f4e 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -2714,26 +2714,7 @@ public class Player extends GameEntity implements Comparable { cmd.setCommander(true); com.add(cmd); setCommander(cmd); - - DetachedCardEffect eff = new DetachedCardEffect(cmd, "Commander Effect"); - - eff.setSVar("CommanderMoveReplacement", "DB$ ChangeZone | Origin$ Battlefield,Graveyard,Exile,Library,Hand | Destination$ Command | Defined$ ReplacedCard"); - eff.setSVar("DBCommanderIncCast","DB$ StoreSVar | References$ CommanderCostRaise | SVar$ CommanderCostRaise | Type$ CountSVar | Expression$ CommanderCostRaise/Plus.2"); - eff.setSVar("CommanderCostRaise","Number$0"); - - Trigger t = TriggerHandler.parseTrigger("Mode$ SpellCast | Static$ True | ValidCard$ Card.YouOwn+IsCommander+wasCastFromCommand | References$ CommanderCostRaise | Execute$ DBCommanderIncCast", eff, true); - eff.addTrigger(t); - ReplacementEffect r; - if (game.getRules().hasAppliedVariant(GameType.TinyLeaders)) { - r = ReplacementHandler.parseReplacement("Event$ Moved | Destination$ Graveyard,Exile | ValidCard$ Card.IsCommander+YouOwn | Secondary$ True | Optional$ True | OptionalDecider$ You | ReplaceWith$ CommanderMoveReplacement | Description$ If a commander would be put into its owner's graveyard or exile from anywhere, that player may put it into the command zone instead.", eff, true); - } else { - r = ReplacementHandler.parseReplacement("Event$ Moved | Destination$ Graveyard,Exile,Hand,Library | ValidCard$ Card.IsCommander+YouOwn | Secondary$ True | Optional$ True | OptionalDecider$ You | ReplaceWith$ CommanderMoveReplacement | Description$ If a commander would be exiled or put into hand, graveyard, or library from anywhere, that player may put it into the command zone instead.", eff, true); - } - eff.addReplacementEffect(r); - eff.addStaticAbility("Mode$ Continuous | EffectZone$ Command | AddKeyword$ May be played | Affected$ Card.YouOwn+IsCommander | AffectedZone$ Command"); - eff.addStaticAbility("Mode$ RaiseCost | EffectZone$ Command | References$ CommanderCostRaise | Amount$ CommanderCostRaise | Type$ Spell | ValidCard$ Card.YouOwn+IsCommander+wasCastFromCommand | EffectZone$ All | AffectedZone$ Command,Stack"); - - com.add(eff); + com.add(createCommanderEffect(game, cmd)); } for (IPaperCard cp : registeredPlayer.getConspiracies()) { @@ -2747,6 +2728,27 @@ public class Player extends GameEntity implements Comparable { } } + public static DetachedCardEffect createCommanderEffect(Game game, Card commander) { + DetachedCardEffect eff = new DetachedCardEffect(commander, "Commander Effect"); + + eff.setSVar("CommanderMoveReplacement", "DB$ ChangeZone | Origin$ Battlefield,Graveyard,Exile,Library,Hand | Destination$ Command | Defined$ ReplacedCard"); + eff.setSVar("DBCommanderIncCast","DB$ StoreSVar | References$ CommanderCostRaise | SVar$ CommanderCostRaise | Type$ CountSVar | Expression$ CommanderCostRaise/Plus.2"); + eff.setSVar("CommanderCostRaise","Number$0"); + + Trigger t = TriggerHandler.parseTrigger("Mode$ SpellCast | Static$ True | ValidCard$ Card.YouOwn+IsCommander+wasCastFromCommand | References$ CommanderCostRaise | Execute$ DBCommanderIncCast", eff, true); + eff.addTrigger(t); + ReplacementEffect r; + if (game.getRules().hasAppliedVariant(GameType.TinyLeaders)) { + r = ReplacementHandler.parseReplacement("Event$ Moved | Destination$ Graveyard,Exile | ValidCard$ Card.IsCommander+YouOwn | Secondary$ True | Optional$ True | OptionalDecider$ You | ReplaceWith$ CommanderMoveReplacement | Description$ If a commander would be put into its owner's graveyard or exile from anywhere, that player may put it into the command zone instead.", eff, true); + } else { + r = ReplacementHandler.parseReplacement("Event$ Moved | Destination$ Graveyard,Exile,Hand,Library | ValidCard$ Card.IsCommander+YouOwn | Secondary$ True | Optional$ True | OptionalDecider$ You | ReplaceWith$ CommanderMoveReplacement | Description$ If a commander would be exiled or put into hand, graveyard, or library from anywhere, that player may put it into the command zone instead.", eff, true); + } + eff.addReplacementEffect(r); + eff.addStaticAbility("Mode$ Continuous | EffectZone$ Command | AddKeyword$ May be played | Affected$ Card.YouOwn+IsCommander | AffectedZone$ Command"); + eff.addStaticAbility("Mode$ RaiseCost | EffectZone$ Command | References$ CommanderCostRaise | Amount$ CommanderCostRaise | Type$ Spell | ValidCard$ Card.YouOwn+IsCommander+wasCastFromCommand | EffectZone$ All | AffectedZone$ Command,Stack"); + return eff; + } + public void changeOwnership(Card card) { // If lost then gained, just clear out of lost. // If gained then lost, just clear out of gained.