MayLook: refactor it to use timestamp, also handle facedown exile

This commit is contained in:
Hans Mackowiak
2020-07-19 15:59:42 +00:00
committed by Michael Kamensky
parent aafbdd1a9c
commit b816bae232
7 changed files with 55 additions and 73 deletions

View File

@@ -17,16 +17,13 @@
*/ */
package forge.game; package forge.game;
import forge.game.ability.AbilityUtils;
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;
import forge.game.card.CardUtil;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.staticability.StaticAbility; import forge.game.staticability.StaticAbility;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -182,12 +179,9 @@ public class StaticEffect {
boolean setPT = false; boolean setPT = false;
String[] addHiddenKeywords = null; String[] addHiddenKeywords = null;
String addColors = null;
boolean removeMayPlay = false; boolean removeMayPlay = false;
boolean removeWithFlash = false; boolean removeWithFlash = false;
List<Player> mayLookAt = null;
if (hasParam("ChangeColorWordsTo")) { if (hasParam("ChangeColorWordsTo")) {
changeColorWordsTo = getParam("ChangeColorWordsTo"); changeColorWordsTo = getParam("ChangeColorWordsTo");
} }
@@ -200,31 +194,6 @@ public class StaticEffect {
addHiddenKeywords = getParam("AddHiddenKeyword").split(" & "); addHiddenKeywords = getParam("AddHiddenKeyword").split(" & ");
} }
if (hasParam("AddColor")) {
final String colors = getParam("AddColor");
if (colors.equals("ChosenColor")) {
addColors = CardUtil.getShortColorsString(getSource().getChosenColors());
} else {
addColors = CardUtil.getShortColorsString(new ArrayList<>(Arrays.asList(colors.split(" & "))));
}
}
if (hasParam("SetColor")) {
final String colors = getParam("SetColor");
if (colors.equals("ChosenColor")) {
addColors = CardUtil.getShortColorsString(getSource().getChosenColors());
} else {
addColors = CardUtil.getShortColorsString(new ArrayList<>(Arrays.asList(colors.split(" & "))));
}
}
if (hasParam("MayLookAt")) {
String look = getParam("MayLookAt");
if ("True".equals(look)) {
look = "You";
}
mayLookAt = AbilityUtils.getDefinedPlayers(source, look, null);
}
if (hasParam("MayPlay")) { if (hasParam("MayPlay")) {
removeMayPlay = true; removeMayPlay = true;
} }
@@ -303,15 +272,13 @@ public class StaticEffect {
} }
// remove colors // remove colors
if (addColors != null) { if (hasParam("AddColor") || hasParam("SetColor")) {
affectedCard.removeColor(getTimestamp()); affectedCard.removeColor(getTimestamp());
} }
// remove may look at // remove may look at
if (mayLookAt != null) { if (hasParam("MayLookAt")) {
for (Player p : mayLookAt) { affectedCard.removeMayLookAt(getTimestamp());
affectedCard.setMayLookAt(p, false);
}
} }
if (removeMayPlay) { if (removeMayPlay) {
affectedCard.removeMayPlay(ability); affectedCard.removeMayPlay(ability);

View File

@@ -124,6 +124,10 @@ public class Card extends GameEntity implements Comparable<Card> {
private final NavigableMap<Long, CardCloneStates> clonedStates = Maps.newTreeMap(); private final NavigableMap<Long, CardCloneStates> clonedStates = Maps.newTreeMap();
private final NavigableMap<Long, CardCloneStates> textChangeStates = Maps.newTreeMap(); private final NavigableMap<Long, CardCloneStates> textChangeStates = Maps.newTreeMap();
private final Map<Long, PlayerCollection> mayLook = Maps.newHashMap();
private final PlayerCollection mayLookFaceDownExile = new PlayerCollection();
private final PlayerCollection mayLookTemp = new PlayerCollection();
private final Multimap<Long, Keyword> cantHaveKeywords = MultimapBuilder.hashKeys().enumSetValues(Keyword.class).build(); private final Multimap<Long, Keyword> cantHaveKeywords = MultimapBuilder.hashKeys().enumSetValues(Keyword.class).build();
private final Map<CounterType, Long> counterTypeTimestamps = Maps.newHashMap(); private final Map<CounterType, Long> counterTypeTimestamps = Maps.newHashMap();
@@ -2842,11 +2846,44 @@ public class Card extends GameEntity implements Comparable<Card> {
return view.mayPlayerLook(player.getView()); return view.mayPlayerLook(player.getView());
} }
public final void setMayLookAt(final Player player, final boolean mayLookAt) { public final void addMayLookAt(final long timestamp, final Iterable<Player> list) {
setMayLookAt(player, mayLookAt, false); PlayerCollection plist = new PlayerCollection(list);
mayLook.put(timestamp, plist);
if (isFaceDown() && isInZone(ZoneType.Exile)) {
mayLookFaceDownExile.addAll(plist);
} }
public final void setMayLookAt(final Player player, final boolean mayLookAt, final boolean temp) { updateMayLook();
view.setPlayerMayLook(player, mayLookAt, temp); }
public final void removeMayLookAt(final long timestamp) {
if (mayLook.remove(timestamp) != null) {
updateMayLook();
}
}
public final void addMayLookTemp(final Player player) {
if (mayLookTemp.add(player)) {
if (isFaceDown() && isInZone(ZoneType.Exile)) {
mayLookFaceDownExile.add(player);
}
updateMayLook();
}
}
public final void removeMayLookTemp(final Player player) {
if (mayLookTemp.remove(player)) {
updateMayLook();
}
}
public final void updateMayLook() {
PlayerCollection result = new PlayerCollection();
for (PlayerCollection v : mayLook.values()) {
result.addAll(v);
}
result.addAll(mayLookFaceDownExile);
result.addAll(mayLookTemp);
getView().setPlayerMayLook(result);
} }
public final CardPlayOption mayPlay(final StaticAbility sta) { public final CardPlayOption mayPlay(final StaticAbility sta) {

View File

@@ -20,6 +20,7 @@ package forge.game.card;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
@@ -204,7 +205,7 @@ public class CardFactoryUtil {
card.setNamedCard(name); card.setNamedCard(name);
card.turnFaceDown(); card.turnFaceDown();
card.setMayLookAt(player, true); card.addMayLookAt(player.getGame().getNextTimestamp(), ImmutableList.of(player));
card.addSpellAbility(abilityRevealHiddenAgenda(card)); card.addSpellAbility(abilityRevealHiddenAgenda(card));
return true; return true;
} }

View File

@@ -353,33 +353,13 @@ public class CardView extends GameEntityView {
public boolean mayPlayerLook(PlayerView pv) { public boolean mayPlayerLook(PlayerView pv) {
TrackableCollection<PlayerView> col = get(TrackableProperty.PlayerMayLook); TrackableCollection<PlayerView> col = get(TrackableProperty.PlayerMayLook);
if (col != null && col.contains(pv)) {
return true;
}
col = get(TrackableProperty.PlayerMayLookTemp);
return col != null && col.contains(pv); return col != null && col.contains(pv);
} }
void setPlayerMayLook(Player p, boolean mayLook, boolean temp) { void setPlayerMayLook(Iterable<Player> list) {
TrackableProperty prop = temp ? TrackableProperty.PlayerMayLookTemp : TrackableProperty.PlayerMayLook; if (Iterables.isEmpty(list)) {
TrackableCollection<PlayerView> col = get(prop); set(TrackableProperty.PlayerMayLook, null);
if (mayLook) { } else {
if (col == null) { set(TrackableProperty.PlayerMayLook, PlayerView.getCollection(list));
col = new TrackableCollection<>(p.getView());
set(prop, col);
}
else if (col.add(p.getView())) {
flagAsChanged(prop);
}
}
else if (col != null) {
if (col.remove(p.getView())) {
if (col.isEmpty()) {
set(prop, null);
}
else {
flagAsChanged(prop);
}
}
} }
} }

View File

@@ -824,9 +824,7 @@ public final class StaticAbilityContinuous {
} }
if (mayLookAt != null) { if (mayLookAt != null) {
for (Player p : mayLookAt) { affectedCard.addMayLookAt(se.getTimestamp(), mayLookAt);
affectedCard.setMayLookAt(p, true);
}
} }
if (withFlash != null) { if (withFlash != null) {
affectedCard.addWithFlash(se.getTimestamp(), withFlash); affectedCard.addWithFlash(se.getTimestamp(), withFlash);

View File

@@ -54,7 +54,6 @@ public enum TrackableProperty {
Remembered(TrackableTypes.StringType), Remembered(TrackableTypes.StringType),
NamedCard(TrackableTypes.StringType), NamedCard(TrackableTypes.StringType),
PlayerMayLook(TrackableTypes.PlayerViewCollectionType, FreezeMode.IgnoresFreeze), PlayerMayLook(TrackableTypes.PlayerViewCollectionType, FreezeMode.IgnoresFreeze),
PlayerMayLookTemp(TrackableTypes.PlayerViewCollectionType, FreezeMode.IgnoresFreeze),
EntityAttachedTo(TrackableTypes.GameEntityViewType), EntityAttachedTo(TrackableTypes.GameEntityViewType),
EncodedCards(TrackableTypes.CardViewCollectionType), EncodedCards(TrackableTypes.CardViewCollectionType),
GainControlTargets(TrackableTypes.CardViewCollectionType), GainControlTargets(TrackableTypes.CardViewCollectionType),

View File

@@ -161,7 +161,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
return; return;
} }
tempShownCards.add(c); tempShownCards.add(c);
c.setMayLookAt(player, true, true); c.addMayLookTemp(player);
} }
@Override @Override
@@ -178,7 +178,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
} }
for (final Card c : tempShownCards) { for (final Card c : tempShownCards) {
c.setMayLookAt(player, false, true); c.removeMayLookTemp(player);
} }
tempShownCards.clear(); tempShownCards.clear();
} }