Commit f8465890 authored by Walter Adolph's avatar Walter Adolph

Merge remote-tracking branch 'remotes/upstream/master'

parents 965dcfe0 413de957
......@@ -1339,7 +1339,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
});
for (Card pw : aiPlaneswalkers) {
int curLoyalty = pw.getCounters(CounterType.LOYALTY);
int freshLoyalty = pw.getCurrentState().getBaseLoyalty();
int freshLoyalty = Integer.valueOf(pw.getCurrentState().getBaseLoyalty());
if (freshLoyalty - curLoyalty >= loyaltyDiff && curLoyalty <= maxLoyaltyToConsider) {
return pw;
}
......
......@@ -290,7 +290,6 @@ public class GameCopier {
// TODO: Is this correct? Does it not duplicate keywords from enchantments and such?
for (KeywordInterface kw : c.getHiddenExtrinsicKeywords())
newCard.addHiddenExtrinsicKeyword(kw);
newCard.setExtrinsicKeyword(Lists.newArrayList(c.getExtrinsicKeyword()));
if (c.isTapped()) {
newCard.setTapped(true);
}
......
......@@ -38,7 +38,7 @@ final class CardFace implements ICardFace {
private int iToughness = Integer.MAX_VALUE;
private String power = null;
private String toughness = null;
private int initialLoyalty = -1;
private String initialLoyalty = "";
private String nonAbilityText = null;
private List<String> keywords = null;
......@@ -56,7 +56,7 @@ final class CardFace implements ICardFace {
@Override public int getIntToughness() { return iToughness; }
@Override public String getPower() { return power; }
@Override public String getToughness() { return toughness; }
@Override public int getInitialLoyalty() { return initialLoyalty; }
@Override public String getInitialLoyalty() { return initialLoyalty; }
@Override public String getName() { return this.name; }
@Override public CardType getType() { return this.type; }
@Override public ManaCost getManaCost() { return this.manaCost; }
......@@ -84,7 +84,7 @@ final class CardFace implements ICardFace {
void setManaCost(ManaCost manaCost0) { this.manaCost = manaCost0; }
void setColor(ColorSet color0) { this.color = color0; }
void setOracleText(String text) { this.oracleText = text; }
void setInitialLoyalty(int value) { this.initialLoyalty = value; }
void setInitialLoyalty(String value) { this.initialLoyalty = value; }
void setPtText(String value) {
final String k[] = value.split("/");
......
......@@ -186,7 +186,7 @@ public final class CardRules implements ICardCharacteristics {
@Override public int getIntToughness() { return mainPart.getIntToughness(); }
@Override public String getPower() { return mainPart.getPower(); }
@Override public String getToughness() { return mainPart.getToughness(); }
@Override public int getInitialLoyalty() { return mainPart.getInitialLoyalty(); }
@Override public String getInitialLoyalty() { return mainPart.getInitialLoyalty(); }
@Override
public String getOracleText() {
......@@ -409,7 +409,7 @@ public final class CardRules implements ICardCharacteristics {
case 'L':
if ("Loyalty".equals(key)) {
this.faces[this.curFace].setInitialLoyalty(Integer.valueOf(value));
this.faces[this.curFace].setInitialLoyalty(value);
}
break;
......
......@@ -12,7 +12,7 @@ public interface ICardCharacteristics {
int getIntToughness();
String getPower();
String getToughness();
int getInitialLoyalty();
String getInitialLoyalty();
String getOracleText();
}
......@@ -376,6 +376,9 @@ public class GameAction {
copied.clearEtbCounters();
}
// update state for view
copied.updateStateForView();
if (fromBattlefield) {
c.setDamage(0); //clear damage after a card leaves the battlefield
c.setHasBeenDealtDeathtouchDamage(false);
......
......@@ -204,7 +204,8 @@ public final class AbilityFactory {
else if (api == ApiType.PermanentCreature || api == ApiType.PermanentNoncreature) {
// If API is a permanent type, and creating AF Spell
// Clear out the auto created SpellPemanent spell
if (type == AbilityRecordType.Spell && !mapParams.containsKey("SubAbility")) {
if (type == AbilityRecordType.Spell
&& !mapParams.containsKey("SubAbility") && !mapParams.containsKey("NonBasicSpell")) {
hostCard.clearFirstSpell();
}
}
......@@ -389,6 +390,10 @@ public final class AbilityFactory {
sa.setBasicSpell(false);
}
if (mapParams.containsKey("Dash")) {
sa.setDash(true);
}
if (mapParams.containsKey("Outlast")) {
sa.setOutlast(true);
}
......
......@@ -238,7 +238,7 @@ public abstract class SpellAbilityEffect {
}
sb.append(Lang.joinHomogenous(crds));
if (location.equals("Hand")) {
sb.append("to your hand").append(" ");
sb.append(" to your hand");
}
sb.append(" at the ");
if (combat) {
......
......@@ -134,6 +134,9 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
&& !sa.hasParam("Shuffle") && cards.size() >= 2 && !random) {
Player p = AbilityUtils.getDefinedPlayers(source, sa.getParamOrDefault("DefinedPlayer", "You"), sa).get(0);
cards = (CardCollection) p.getController().orderMoveToZoneList(cards, destination);
//the last card in this list will be the closest to the top, but we want the first card to be closest.
//so reverse it here before moving them to the library.
java.util.Collections.reverse(cards);
}
if (destination == ZoneType.Graveyard) {
......
......@@ -537,10 +537,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
tgtC.getController().getZone(destination), tgtC, sa, null);
if (sa.hasParam("Unearth")) {
movedCard.setUnearthed(true);
movedCard.addExtrinsicKeyword("Haste");
movedCard.addChangedCardKeywords(Lists.newArrayList("Haste"), null, false, false,
game.getNextTimestamp(), true);
registerDelayedTrigger(sa, "Exile", Lists.newArrayList(movedCard));
addLeaveBattlefieldReplacement(movedCard, sa, "Exile");
movedCard.updateStateForView();
}
if (sa.hasParam("FaceDown")) {
movedCard.turnFaceDown(true);
......
......@@ -52,7 +52,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
}
CardCollectionView choices = game.getCardsIn(choiceZone);
if (sa.hasParam("Choices")) {
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host, sa);
}
if (sa.hasParam("TargetControls")) {
choices = CardLists.filterControlledBy(choices, tgtPlayers.get(0));
......
......@@ -3,6 +3,8 @@ package forge.game.ability.effects;
import java.util.Arrays;
import java.util.List;
import com.google.common.collect.Lists;
import forge.GameCommand;
import forge.card.mana.ManaCost;
import forge.game.Game;
......@@ -11,6 +13,7 @@ import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.card.CardCollectionView;
import forge.game.card.CardLists;
import forge.game.event.GameEventCardStatsChanged;
import forge.game.player.Player;
import forge.game.spellability.Ability;
import forge.game.spellability.SpellAbility;
......@@ -35,23 +38,26 @@ public class ControlGainEffect extends SpellAbilityEffect {
if (tgts.isEmpty()) {
sb.append(" (nothing)");
} else {
for (final Card c : getDefinedCards(sa)) {
sb.append(" ");
if (c.isFaceDown()) {
sb.append("Face-down creature (").append(c.getId()).append(')');
} else {
sb.append(c);
}
}
for (final Card c : tgts) {
sb.append(" ");
if (c.isFaceDown()) {
sb.append("Face-down creature (").append(c.getId()).append(')');
} else {
sb.append(c);
}
}
}
sb.append(".");
if (sa.hasParam("Untap")) {
sb.append(" Untap it.");
}
return sb.toString();
}
private static void doLoseControl(final Card c, final Card host,
final boolean tapOnLose, final List<String> addedKeywords,
final long tStamp) {
final boolean tapOnLose, final long tStamp) {
if (null == c || c.hasKeyword("Other players can't gain control of CARDNAME.")) {
return;
}
......@@ -61,12 +67,6 @@ public class ControlGainEffect extends SpellAbilityEffect {
if (tapOnLose) {
c.tap();
}
if (null != addedKeywords) {
for (final String kw : addedKeywords) {
c.removeExtrinsicKeyword(kw);
}
}
} // if
host.removeGainControlTargets(c);
......@@ -82,7 +82,7 @@ public class ControlGainEffect extends SpellAbilityEffect {
final boolean remember = sa.hasParam("RememberControlled");
final boolean forget = sa.hasParam("ForgetControlled");
final List<String> destroyOn = sa.hasParam("DestroyTgt") ? Arrays.asList(sa.getParam("DestroyTgt").split(",")) : null;
final List<String> kws = sa.hasParam("AddKWs") ? Arrays.asList(sa.getParam("AddKWs").split(" & ")) : null;
final List<String> keywords = sa.hasParam("AddKWs") ? Arrays.asList(sa.getParam("AddKWs").split(" & ")) : null;
final List<String> lose = sa.hasParam("LoseControl") ? Arrays.asList(sa.getParam("LoseControl").split(",")) : null;
final List<Player> controllers = getDefinedPlayersOrTargeted(sa, "NewController");
......@@ -125,15 +125,22 @@ public class ControlGainEffect extends SpellAbilityEffect {
tgtC.untap();
}
if (null != kws) {
for (final String kw : kws) {
tgtC.addExtrinsicKeyword(kw);
if (kw.equals("Haste")) {
tgtC.updateStateForView(); // ensure that summoning sickness icon is removed
final List<String> kws = Lists.newArrayList();
if (null != keywords) {
for (final String kw : keywords) {
if (kw.startsWith("HIDDEN")) {
tgtC.addHiddenExtrinsicKeyword(kw);
} else {
kws.add(kw);
}
}
}
if (!kws.isEmpty()) {
tgtC.addChangedCardKeywords(kws, Lists.<String>newArrayList(), false, false, tStamp);
game.fireEvent(new GameEventCardStatsChanged(tgtC));
}
if (remember && !sa.getHostCard().isRemembered(tgtC)) {
sa.getHostCard().addRemembered(tgtC);
}
......@@ -143,7 +150,7 @@ public class ControlGainEffect extends SpellAbilityEffect {
}
if (lose != null) {
final GameCommand loseControl = getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws);
final GameCommand loseControl = getLoseControlCommand(tgtC, tStamp, bTapOnLose, source);
if (lose.contains("LeavesPlay")) {
sa.getHostCard().addLeavesPlayCommand(loseControl);
}
......@@ -183,6 +190,26 @@ public class ControlGainEffect extends SpellAbilityEffect {
}
}
if (keywords != null) {
// Add keywords only until end of turn
final GameCommand untilKeywordEOT = new GameCommand() {
private static final long serialVersionUID = -42244224L;
@Override
public void run() {
if (keywords.size() > 0) {
for (String kw : keywords) {
if (kw.startsWith("HIDDEN")) {
tgtC.removeHiddenExtrinsicKeyword(kw);
}
}
tgtC.removeChangedCardKeywords(tStamp);
}
}
};
game.getEndOfTurn().addUntil(untilKeywordEOT);
}
game.getAction().controllerChangeZoneCorrection(tgtC);
} // end foreach target
}
......@@ -236,14 +263,13 @@ public class ControlGainEffect extends SpellAbilityEffect {
* @return a {@link forge.GameCommand} object.
*/
private static GameCommand getLoseControlCommand(final Card c,
final long tStamp, final boolean bTapOnLose, final Card hostCard,
final List<String> kws) {
final long tStamp, final boolean bTapOnLose, final Card hostCard) {
final GameCommand loseControl = new GameCommand() {
private static final long serialVersionUID = 878543373519872418L;
@Override
public void run() {
doLoseControl(c, hostCard, bTapOnLose, kws, tStamp);
doLoseControl(c, hostCard, bTapOnLose, tStamp);
c.getSVars().remove("SacMe");
}
};
......
......@@ -83,10 +83,6 @@ public class DigEffect extends SpellAbilityEffect {
boolean changeAll = false;
boolean allButOne = false;
final List<String> keywords = new ArrayList<String>();
if (sa.hasParam("Keywords")) {
keywords.addAll(Arrays.asList(sa.getParam("Keywords").split(" & ")));
}
if (sa.hasParam("ChangeNum")) {
if (sa.getParam("ChangeNum").equalsIgnoreCase("All")) {
......@@ -307,9 +303,6 @@ public class DigEffect extends SpellAbilityEffect {
else {
c = game.getAction().moveTo(zone, c, sa);
if (destZone1.equals(ZoneType.Battlefield)) {
for (final String kw : keywords) {
c.addExtrinsicKeyword(kw);
}
if (sa.hasParam("Tapped")) {
c.setTapped(true);
}
......@@ -377,11 +370,7 @@ public class DigEffect extends SpellAbilityEffect {
if (!origin.equals(c.getZone().getZoneType())) {
table.put(origin, c.getZone().getZoneType(), c);
}
if (destZone2 == ZoneType.Battlefield && !keywords.isEmpty()) {
for (final String kw : keywords) {
c.addExtrinsicKeyword(kw);
}
} else if (destZone2 == ZoneType.Exile) {
if (destZone2 == ZoneType.Exile) {
if (sa.hasParam("ExileWithCounter")) {
c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")),
1, player, true, counterTable);
......
package forge.game.ability.effects;
import com.google.common.collect.Lists;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.player.Player;
......@@ -25,9 +27,8 @@ public class PermanentEffect extends SpellAbilityEffect {
// some extra for Dashing
if (sa.isDash()) {
c.addExtrinsicKeyword("Haste");
c.setSVar("EndOfTurnLeavePlay", "Dash");
c.updateKeywords();
registerDelayedTrigger(sa, "Hand", Lists.newArrayList(c));
}
}
}
......@@ -94,7 +94,6 @@ public class Card extends GameEntity implements Comparable<Card> {
private final CardDamageHistory damageHistory = new CardDamageHistory();
private Map<Card, Map<CounterType, Integer>> countersAddedBy = Maps.newTreeMap();
private KeywordCollection extrinsicKeyword = new KeywordCollection();
// Hidden keywords won't be displayed on the card
private final KeywordCollection hiddenExtrinsicKeyword = new KeywordCollection();
......@@ -540,8 +539,7 @@ public class Card extends GameEntity implements Comparable<Card> {
}
public final void updatePowerToughnessForView() {
currentState.getView().updatePower(this);
currentState.getView().updateToughness(this);
view.updateCounters(this);
}
public final void updateTypesForView() {
......@@ -2698,6 +2696,13 @@ public class Card extends GameEntity implements Comparable<Card> {
}
public final Player getController() {
if ((currentZone == null) || ((currentZone.getZoneType() != ZoneType.Battlefield) && (currentZone.getZoneType() != ZoneType.Stack))){
//only permanents and spells have controllers [108.4],
//so a card really only has a controller while it's on the stack or battlefield.
//everywhere else, just use the owner [108.4a].
return owner;
}
Entry<Long, Player> lastEntry = tempControllers.lastEntry();
if (lastEntry != null) {
final long lastTimestamp = lastEntry.getKey();
......@@ -3727,7 +3732,6 @@ public class Card extends GameEntity implements Comparable<Card> {
if (!removeIntrinsic) {
keywords.insertAll(state.getIntrinsicKeywords());
}
keywords.insertAll(extrinsicKeyword.getValues());
// see if keyword changes are in effect
for (final KeywordsChange ck : changedCardKeywords.values()) {
......@@ -3755,11 +3759,6 @@ public class Card extends GameEntity implements Comparable<Card> {
return;
}
}
for (KeywordInterface kw : extrinsicKeyword.getValues()) {
if (!visitor.visit(kw)) {
return;
}
}
} else {
for (KeywordInterface kw : getUnhiddenKeywords(state)) {
if (!visitor.visit(kw)) {
......@@ -3927,53 +3926,6 @@ public class Card extends GameEntity implements Comparable<Card> {
}
}
public Collection<KeywordInterface> getExtrinsicKeyword() {
return extrinsicKeyword.getValues();
}
public final void setExtrinsicKeyword(final List<String> a) {
extrinsicKeyword.clear();
extrinsicKeyword.addAll(a);
}
public void setExtrinsicKeyword(Collection<KeywordInterface> extrinsicKeyword2) {
extrinsicKeyword.clear();
extrinsicKeyword.insertAll(extrinsicKeyword2);
}
public void addExtrinsicKeyword(final String s) {
if (s.startsWith("HIDDEN")) {
addHiddenExtrinsicKeyword(s);
}
else {
extrinsicKeyword.add(s);
}
}
public void removeExtrinsicKeyword(final String s) {
if (s.startsWith("HIDDEN")) {
removeHiddenExtrinsicKeyword(s);
}
else if (extrinsicKeyword.remove(s)) {
currentState.getView().updateKeywords(this, currentState);
}
}
public void removeAllExtrinsicKeyword(final String s) {
final List<String> strings = Lists.newArrayList();
strings.add(s);
boolean needKeywordUpdate = false;
if (extrinsicKeyword.removeAll(strings)) {
needKeywordUpdate = true;
}
strings.add("HIDDEN " + s);
if (hiddenExtrinsicKeyword.removeAll(strings)) {
view.updateNonAbilityText(this);
needKeywordUpdate = true;
}
if (needKeywordUpdate) {
currentState.getView().updateKeywords(this, currentState);
}
}
// Hidden Keywords will be returned without the indicator HIDDEN
public final List<KeywordInterface> getHiddenExtrinsicKeywords() {
ListKeywordVisitor visitor = new ListKeywordVisitor();
......
......@@ -325,9 +325,6 @@ public class CardFactory {
// ******************************************************************
// ************** Link to different CardFactories *******************
if (card.isPlaneswalker()) {
buildPlaneswalkerAbilities(card);
}
if (state == CardStateName.LeftSplit || state == CardStateName.RightSplit) {
for (final SpellAbility sa : card.getSpellAbilities()) {
......@@ -383,18 +380,6 @@ public class CardFactory {
card.addSpellAbility(planarRoll);
}
private static void buildPlaneswalkerAbilities(Card card) {
CardState state = card.getCurrentState();
// etbCounter only for Original Card
if (state.getBaseLoyalty() > 0) {
final String loyalty = Integer.toString(state.getBaseLoyalty());
// keyword need to be added to state directly, so init can be disabled
if (state.addIntrinsicKeyword("etbCounter:LOYALTY:" + loyalty + ":no Condition:no desc", false) != null) {
card.updateKeywords();
}
}
}
private static Card readCard(final CardRules rules, final IPaperCard paperCard, int cardId, Game game) {
final Card card = new Card(cardId, paperCard, game);
......
......@@ -3508,7 +3508,7 @@ public class CardFactoryUtil {
String abExile = "DB$ ChangeZone | Defined$ Self | Origin$ Stack | Destination$ Exile";
String delTrig = "DB$ DelayedTrigger | Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You " +
" | OptionalDecider$ You | RememberObjects$ Self | TriggerDescription$"
+ " At the beginning of your next upkeep, you may cast " + card.toString() + " without paying it's manacost.";
+ " At the beginning of your next upkeep, you may cast " + card.toString() + " without paying its mana cost.";
// TODO add check for still in exile
String abPlay = "DB$ Play | Defined$ Self | WithoutManaCost$ True | Optional$ True";
......@@ -3850,23 +3850,11 @@ public class CardFactoryUtil {
inst.addSpellAbility(sa);
} else if (keyword.startsWith("Dash")) {
final String[] k = keyword.split(":");
final String dashString = "SP$ PermanentCreature | Cost$ " + k[1] + " | SubAbility$"
+ " DashDelayedTrigger";
final String dbDelayTrigger = "DB$ DelayedTrigger | Mode$ Phase | Phase$"
+ " End of Turn | Execute$ DashReturnSelf | RememberObjects$ Self"
+ " | TriggerDescription$ Return CARDNAME from the battlefield to" + " its owner's hand.";
final String dbReturn = "DB$ ChangeZone | Origin$ Battlefield | Destination$ Hand"
+ " | Defined$ DelayTriggerRemembered";
card.setSVar("DashDelayedTrigger", dbDelayTrigger);
card.setSVar("DashReturnSelf", dbReturn);
final String dashString = "SP$ PermanentCreature | Cost$ " + k[1] + " | StackDescription$ CARDNAME (Dash)"
+ " | Dash$ True | NonBasicSpell$ True"
+ " | SpellDescription$ Dash " + ManaCostParser.parse(k[1]) + " (" + inst.getReminderText() + ")";
final SpellAbility newSA = AbilityFactory.getAbility(dashString, card);
String desc = "Dash " + ManaCostParser.parse(k[1]) + " (" + inst.getReminderText()
+ ")";
newSA.setStackDescription(card.getName() + " (Dash)");
newSA.setDescription(desc);
newSA.setBasicSpell(false);
newSA.setDash(true);
newSA.setIntrinsic(intrinsic);
newSA.setTemporary(!intrinsic);
......@@ -4527,6 +4515,8 @@ public class CardFactoryUtil {
card.setSVar("CipherTrigger", trig);
card.setSVar("PlayEncoded", ab);
} else if (keyword.startsWith("Dash")) {
effect = "Mode$ Continuous | Affected$ Card.Self+dashed | AddKeyword$ Haste";
} else if (keyword.equals("Devoid")) {
effect = "Mode$ Continuous | EffectZone$ All | Affected$ Card.Self" +
" | CharacteristicDefining$ True | SetColor$ Colorless | Secondary$ True" +
......
......@@ -1639,6 +1639,11 @@ public class CardProperty {
return false;
}
return card.getCastSA().isSurged();
} else if (property.startsWith("dashed")) {
if (card.getCastSA() == null) {
return false;
}
return card.getCastSA().isDash();
} else if (property.startsWith("evoked")) {
if (card.getCastSA() == null) {
return false;
......
......@@ -53,7 +53,7 @@ public class CardState extends GameObject {
private byte color = MagicColor.COLORLESS;
private int basePower = 0;
private int baseToughness = 0;
private int baseLoyalty = 0;
private String baseLoyalty = "";
private KeywordCollection intrinsicKeywords = new KeywordCollection();
private final FCollection<SpellAbility> nonManaAbilities = new FCollection<SpellAbility>();
......@@ -72,6 +72,8 @@ public class CardState extends GameObject {
private final CardStateView view;
private final Card card;
private ReplacementEffect loyaltyRep = null;
public CardState(Card card, CardStateName name) {
this(card.getView().createAlternateState(name), card);
}
......@@ -174,11 +176,11 @@ public class CardState extends GameObject {
view.updateToughness(this);
}
public int getBaseLoyalty() {
public String getBaseLoyalty() {
return baseLoyalty;
}
public final void setBaseLoyalty(final int loyalty) {
baseLoyalty = loyalty;
public final void setBaseLoyalty(final String string) {
baseLoyalty = string;
view.updateLoyalty(this);
}
......@@ -400,6 +402,14 @@ public class CardState extends GameObject {
public FCollectionView<ReplacementEffect> getReplacementEffects() {
FCollection<ReplacementEffect> result = new FCollection<>(replacementEffects);
if (getTypeWithChanges().isPlaneswalker()) {
if (loyaltyRep == null) {
loyaltyRep = CardFactoryUtil.makeEtbCounter("etbCounter:LOYALTY:" + this.baseLoyalty, card, true);
}
result.add(loyaltyRep);
}
card.updateReplacementEffects(result, this);
return result;
}
......
......@@ -255,7 +255,6 @@ public final class CardUtil {
newCopy.setBaseToughness(in.getCurrentToughness() + in.getTempToughnessBoost() + in.getSemiPermanentToughnessBoost());
newCopy.setCounters(Maps.newEnumMap(in.getCounters()));
newCopy.setExtrinsicKeyword(in.getExtrinsicKeyword());
newCopy.setColor(in.determineColor().getColor());
newCopy.setReceivedDamageFromThisTurn(in.getReceivedDamageFromThisTurn());
......
......@@ -659,6 +659,8 @@ public class CardView extends GameEntityView {
if (c.getGame() != null) {
currentStateView.updateColors(currentState);
}
} else {
currentStateView.updateLoyalty(currentState);
}
currentState.getView().updateKeywords(c, currentState); //update keywords even if state doesn't change
......@@ -685,6 +687,8 @@ public class CardView extends GameEntityView {
if (c.getGame() != null) {
alternateStateView.updateColors(alternateState);
}
} else {
alternateStateView.updateLoyalty(alternateState);
}
alternateState.getView().updateKeywords(c, alternateState);
}
......@@ -889,13 +893,17 @@ public class CardView extends GameEntityView {
set(TrackableProperty.Toughness, c.getBaseToughness());
}
public int getLoyalty() {
public String getLoyalty() {
return get(TrackableProperty.Loyalty);
}
void updateLoyalty(Card c) {
updateLoyalty(c.getCurrentLoyalty());
if (c.isInZone(ZoneType.Battlefield)) {
updateLoyalty(String.valueOf(c.getCurrentLoyalty()));
} else {
updateLoyalty(c.getCurrentState().getBaseLoyalty());
}
}
void updateLoyalty(int loyalty) {
void updateLoyalty(String loyalty) {
set(TrackableProperty.Loyalty, loyalty);
}
void updateLoyalty(CardState c) {
......@@ -911,7 +919,7 @@ public class CardView extends GameEntityView {
return;
}
}
set(TrackableProperty.Loyalty, 0); //alternates don't need loyalty
set(TrackableProperty.Loyalty, "0"); //alternates don't need loyalty
}
public String getSetCode() {
......
......@@ -209,11 +209,10 @@ public class Untap extends Phase {
// Remove temporary keywords
for (final Card c : player.getCardsIn(ZoneType.Battlefield)) {
c.removeAllExtrinsicKeyword("This card doesn't untap during your next untap step.");
c.removeAllExtrinsicKeyword("HIDDEN This card doesn't untap during your next untap step.");
c.removeHiddenExtrinsicKeyword("This card doesn't untap during your next untap step.");
if (c.hasKeyword("This card doesn't untap during your next two untap steps.")) {
c.removeAllExtrinsicKeyword("HIDDEN This card doesn't untap during your next two untap steps.");
c.addHiddenExtrinsicKeyword