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;
import forge.game.ability.AbilityUtils;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CardCollectionView;
import forge.game.card.CardUtil;
import forge.game.player.Player;
import forge.game.staticability.StaticAbility;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -182,12 +179,9 @@ public class StaticEffect {
boolean setPT = false;
String[] addHiddenKeywords = null;
String addColors = null;
boolean removeMayPlay = false;
boolean removeWithFlash = false;
List<Player> mayLookAt = null;
if (hasParam("ChangeColorWordsTo")) {
changeColorWordsTo = getParam("ChangeColorWordsTo");
}
@@ -200,31 +194,6 @@ public class StaticEffect {
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")) {
removeMayPlay = true;
}
@@ -303,15 +272,13 @@ public class StaticEffect {
}
// remove colors
if (addColors != null) {
if (hasParam("AddColor") || hasParam("SetColor")) {
affectedCard.removeColor(getTimestamp());
}
// remove may look at
if (mayLookAt != null) {
for (Player p : mayLookAt) {
affectedCard.setMayLookAt(p, false);
}
if (hasParam("MayLookAt")) {
affectedCard.removeMayLookAt(getTimestamp());
}
if (removeMayPlay) {
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> 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 Map<CounterType, Long> counterTypeTimestamps = Maps.newHashMap();
@@ -2842,11 +2846,44 @@ public class Card extends GameEntity implements Comparable<Card> {
return view.mayPlayerLook(player.getView());
}
public final void setMayLookAt(final Player player, final boolean mayLookAt) {
setMayLookAt(player, mayLookAt, false);
public final void addMayLookAt(final long timestamp, final Iterable<Player> list) {
PlayerCollection plist = new PlayerCollection(list);
mayLook.put(timestamp, plist);
if (isFaceDown() && isInZone(ZoneType.Exile)) {
mayLookFaceDownExile.addAll(plist);
}
updateMayLook();
}
public final void setMayLookAt(final Player player, final boolean mayLookAt, final boolean temp) {
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) {

View File

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

View File

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

View File

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

View File

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

View File

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