Trying to make GameState properly restore commander state - still not fully there.

This commit is contained in:
Myrd
2016-01-02 01:35:12 +00:00
parent d108aa0378
commit 7e65a16f2a
2 changed files with 39 additions and 23 deletions

View File

@@ -12,6 +12,7 @@ import java.util.Map.Entry;
import forge.card.CardStateName; import forge.card.CardStateName;
import forge.game.Game; import forge.game.Game;
import forge.game.ability.effects.DetachedCardEffect;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardCollection; import forge.game.card.CardCollection;
import forge.game.card.CardCollectionView; import forge.game.card.CardCollectionView;
@@ -20,6 +21,7 @@ import forge.game.card.CounterType;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.trigger.TriggerType; import forge.game.trigger.TriggerType;
import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.item.IPaperCard; import forge.item.IPaperCard;
import forge.util.collect.FCollectionView; import forge.util.collect.FCollectionView;
@@ -87,6 +89,9 @@ public abstract class GameState {
aiCardTexts.put(zone, ""); aiCardTexts.put(zone, "");
humanCardTexts.put(zone, ""); humanCardTexts.put(zone, "");
for (Card card : game.getCardsIn(zone)) { for (Card card : game.getCardsIn(zone)) {
if (card instanceof DetachedCardEffect) {
continue;
}
addCard(zone, card.getOwner() == ai ? aiCardTexts : humanCardTexts, card); addCard(zone, card.getOwner() == ai ? aiCardTexts : humanCardTexts, card);
} }
} }
@@ -102,6 +107,9 @@ public abstract class GameState {
} else { } else {
newText.append(c.getPaperCard().getName()); newText.append(c.getPaperCard().getName());
} }
if (c.isCommander()) {
newText.append("|IsCommander:True");
}
if (zoneType == ZoneType.Battlefield) { if (zoneType == ZoneType.Battlefield) {
if (c.isTapped()) { if (c.isTapped()) {
newText.append("|Tapped:True"); newText.append("|Tapped:True");
@@ -207,13 +215,14 @@ public abstract class GameState {
private void setupPlayerState(int life, Map<ZoneType, String> cardTexts, final Player p) { private void setupPlayerState(int life, Map<ZoneType, String> cardTexts, final Player p) {
Map<ZoneType, CardCollectionView> playerCards = new EnumMap<ZoneType, CardCollectionView>(ZoneType.class); Map<ZoneType, CardCollectionView> playerCards = new EnumMap<ZoneType, CardCollectionView>(ZoneType.class);
for(Entry<ZoneType, String> kv : cardTexts.entrySet()) { for (Entry<ZoneType, String> kv : cardTexts.entrySet()) {
String value = kv.getValue(); String value = kv.getValue();
playerCards.put(kv.getKey(), processCardsForZone(value.isEmpty() ? new String[0] : value.split(";"), p)); playerCards.put(kv.getKey(), processCardsForZone(value.isEmpty() ? new String[0] : value.split(";"), p));
} }
if (life >= 0) p.setLife(life, null); if (life >= 0) p.setLife(life, null);
for (Entry<ZoneType, CardCollectionView> kv : playerCards.entrySet()) { for (Entry<ZoneType, CardCollectionView> kv : playerCards.entrySet()) {
PlayerZone zone = p.getZone(kv.getKey());
if (kv.getKey() == ZoneType.Battlefield) { if (kv.getKey() == ZoneType.Battlefield) {
List<Card> cards = new ArrayList<Card>(); List<Card> cards = new ArrayList<Card>();
for (final Card c : kv.getValue()) { for (final Card c : kv.getValue()) {
@@ -221,7 +230,7 @@ public abstract class GameState {
cards.add(c); cards.add(c);
} }
} }
p.getZone(kv.getKey()).setCards(cards); zone.setCards(cards);
for (final Card c : kv.getValue()) { for (final Card c : kv.getValue()) {
if (c.isToken()) { if (c.isToken()) {
continue; continue;
@@ -234,7 +243,7 @@ public abstract class GameState {
c.setSickness(sickness); c.setSickness(sickness);
} }
} else { } else {
p.getZone(kv.getKey()).setCards(kv.getValue()); zone.setCards(kv.getValue());
} }
} }
} }
@@ -282,6 +291,11 @@ public abstract class GameState {
c.setSickness(true); c.setSickness(true);
} else if (info.equalsIgnoreCase("FaceDown:True")) { } else if (info.equalsIgnoreCase("FaceDown:True")) {
c.setState(CardStateName.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));
} }
} }

View File

@@ -2714,26 +2714,7 @@ public class Player extends GameEntity implements Comparable<Player> {
cmd.setCommander(true); cmd.setCommander(true);
com.add(cmd); com.add(cmd);
setCommander(cmd); setCommander(cmd);
com.add(createCommanderEffect(game, 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);
} }
for (IPaperCard cp : registeredPlayer.getConspiracies()) { for (IPaperCard cp : registeredPlayer.getConspiracies()) {
@@ -2747,6 +2728,27 @@ public class Player extends GameEntity implements Comparable<Player> {
} }
} }
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) { public void changeOwnership(Card card) {
// If lost then gained, just clear out of lost. // If lost then gained, just clear out of lost.
// If gained then lost, just clear out of gained. // If gained then lost, just clear out of gained.