mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
Fix so cards in hidden zones are properly hidden
This commit is contained in:
@@ -222,7 +222,6 @@ public class Card extends GameEntity implements Comparable<Card>, IIdentifiable
|
|||||||
private Player controller = null;
|
private Player controller = null;
|
||||||
private long controllerTimestamp = 0;
|
private long controllerTimestamp = 0;
|
||||||
private TreeMap<Long, Player> tempControllers = new TreeMap<Long, Player>();
|
private TreeMap<Long, Player> tempControllers = new TreeMap<Long, Player>();
|
||||||
private final Set<Player> mayLookAt = Sets.newHashSet();
|
|
||||||
|
|
||||||
private String originalText = "", text = "";
|
private String originalText = "", text = "";
|
||||||
private String echoCost = "";
|
private String echoCost = "";
|
||||||
@@ -2120,13 +2119,11 @@ public class Card extends GameEntity implements Comparable<Card>, IIdentifiable
|
|||||||
view.updateController(this);
|
view.updateController(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setMayLookAt(final Player player, final boolean mayLookAt0) {
|
public final void setMayLookAt(final Player player, final boolean mayLookAt) {
|
||||||
if (mayLookAt0) {
|
setMayLookAt(player, mayLookAt, false);
|
||||||
mayLookAt.add(player);
|
}
|
||||||
}
|
public final void setMayLookAt(final Player player, final boolean mayLookAt, final boolean temp) {
|
||||||
else {
|
view.setPlayerMayLook(player, mayLookAt, temp);
|
||||||
mayLookAt.remove(player);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final CardCollectionView getEquippedBy(boolean allowModify) {
|
public final CardCollectionView getEquippedBy(boolean allowModify) {
|
||||||
@@ -6064,81 +6061,6 @@ public class Card extends GameEntity implements Comparable<Card>, IIdentifiable
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canBeShownTo(final Player viewer) {
|
|
||||||
if (viewer == null) { return false; }
|
|
||||||
|
|
||||||
Zone zone = getZone();
|
|
||||||
if (zone == null) { return true; } //cards outside any zone are visible to all
|
|
||||||
|
|
||||||
final Player controller = getController();
|
|
||||||
switch (zone.getZoneType()) {
|
|
||||||
case Ante:
|
|
||||||
case Command:
|
|
||||||
case Exile:
|
|
||||||
case Battlefield:
|
|
||||||
case Graveyard:
|
|
||||||
case Stack:
|
|
||||||
//cards in these zones are visible to all
|
|
||||||
return true;
|
|
||||||
case Hand:
|
|
||||||
if (controller.hasKeyword("Play with your hand revealed.")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//fall through
|
|
||||||
case Sideboard:
|
|
||||||
//face-up cards in these zones are hidden to opponents unless they specify otherwise
|
|
||||||
if (controller.isOpponentOf(viewer) && !hasKeyword("Your opponent may look at this card.")) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
case Library:
|
|
||||||
case PlanarDeck:
|
|
||||||
//cards in these zones are hidden to all unless they specify otherwise
|
|
||||||
if (controller == viewer && hasKeyword("You may look at this card.")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (controller.isOpponentOf(viewer) && hasKeyword("Your opponent may look at this card.")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SchemeDeck:
|
|
||||||
// true for now, to actually see the Scheme cards (can't see deck anyway)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// special viewing permissions for viewer
|
|
||||||
if (mayLookAt.contains(viewer)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if viewer is controlled by another player, also check if card can be shown to that player
|
|
||||||
if (controller.isMindSlaved() && viewer == controller.getMindSlaveMaster()) {
|
|
||||||
return canBeShownTo(controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canCardFaceBeShownTo(final Player viewer) {
|
|
||||||
if (!isFaceDown()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (viewer.hasKeyword("CanSeeOpponentsFaceDownCards")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// special viewing permissions for viewer
|
|
||||||
if (mayLookAt.contains(viewer)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if viewer is controlled by another player, also check if face can be shown to that player
|
|
||||||
if (viewer.isMindSlaved() && canCardFaceBeShownTo(viewer.getMindSlaveMaster())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return !getController().isOpponentOf(viewer) || hasKeyword("Your opponent may look at this card.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCMC() {
|
public int getCMC() {
|
||||||
return getCMC(SplitCMCMode.CurrentSideCMC);
|
return getCMC(SplitCMCMode.CurrentSideCMC);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import forge.item.IPaperCard;
|
|||||||
import forge.trackable.TrackableCollection;
|
import forge.trackable.TrackableCollection;
|
||||||
import forge.trackable.TrackableObject;
|
import forge.trackable.TrackableObject;
|
||||||
import forge.trackable.TrackableProperty;
|
import forge.trackable.TrackableProperty;
|
||||||
|
import forge.util.FCollectionView;
|
||||||
|
|
||||||
|
|
||||||
public class CardView extends GameEntityView {
|
public class CardView extends GameEntityView {
|
||||||
@@ -52,11 +53,11 @@ public class CardView extends GameEntityView {
|
|||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean mayViewAny(Iterable<CardView> cards) {
|
public static boolean mayViewAny(Iterable<CardView> cards, PlayerView viewer) {
|
||||||
if (cards == null) { return false; }
|
if (cards == null) { return false; }
|
||||||
|
|
||||||
for (CardView cv : cards) {
|
for (CardView cv : cards) {
|
||||||
if (cv.mayBeShown) {
|
if (cv.canBeShownTo(viewer)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,11 +290,120 @@ public class CardView extends GameEntityView {
|
|||||||
set(TrackableProperty.NamedCard, c.getNamedCard());
|
set(TrackableProperty.NamedCard, c.getNamedCard());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean mayPlayerLook(PlayerView pv) {
|
||||||
|
TrackableCollection<PlayerView> col = get(TrackableProperty.PlayerMayLook);
|
||||||
|
if (col != null && col.contains(pv)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
col = get(TrackableProperty.PlayerMayLookTemp);
|
||||||
|
if (col != null && col.contains(pv)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
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<PlayerView>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public boolean canBeShownTo(final PlayerView viewer) {
|
||||||
|
if (viewer == null) { return false; }
|
||||||
|
|
||||||
|
ZoneType zone = getZone();
|
||||||
|
if (zone == null) { return true; } //cards outside any zone are visible to all
|
||||||
|
|
||||||
|
final PlayerView controller = getController();
|
||||||
|
switch (zone) {
|
||||||
|
case Ante:
|
||||||
|
case Command:
|
||||||
|
case Exile:
|
||||||
|
case Battlefield:
|
||||||
|
case Graveyard:
|
||||||
|
case Stack:
|
||||||
|
//cards in these zones are visible to all
|
||||||
|
return true;
|
||||||
|
case Hand:
|
||||||
|
if (controller.hasKeyword("Play with your hand revealed.")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//fall through
|
||||||
|
case Sideboard:
|
||||||
|
//face-up cards in these zones are hidden to opponents unless they specify otherwise
|
||||||
|
if (controller.isOpponentOf(viewer) && !getCurrentState().getOpponentMayLook()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case Library:
|
||||||
|
case PlanarDeck:
|
||||||
|
//cards in these zones are hidden to all unless they specify otherwise
|
||||||
|
if (controller == viewer && getCurrentState().getYouMayLook()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (controller.isOpponentOf(viewer) && getCurrentState().getOpponentMayLook()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SchemeDeck:
|
||||||
|
// true for now, to actually see the Scheme cards (can't see deck anyway)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// special viewing permissions for viewer
|
||||||
|
if (mayPlayerLook(viewer)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if viewer is controlled by another player, also check if card can be shown to that player
|
||||||
|
PlayerView mindSlaveMaster = controller.getMindSlaveMaster();
|
||||||
|
if (mindSlaveMaster != null && mindSlaveMaster == viewer) {
|
||||||
|
return canBeShownTo(controller);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public boolean canFaceDownBeShownTo(final PlayerView viewer) {
|
||||||
|
if (!isFaceDown()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (viewer.hasKeyword("CanSeeOpponentsFaceDownCards")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// special viewing permissions for viewer
|
||||||
|
if (mayPlayerLook(viewer)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if viewer is controlled by another player, also check if face can be shown to that player
|
||||||
|
PlayerView mindSlaveMaster = viewer.getMindSlaveMaster();
|
||||||
|
if (mindSlaveMaster != null && canFaceDownBeShownTo(mindSlaveMaster)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !getController().isOpponentOf(viewer) || getCurrentState().getOpponentMayLook();
|
||||||
|
}
|
||||||
|
|
||||||
public CardView getEquipping() {
|
public CardView getEquipping() {
|
||||||
return get(TrackableProperty.Equipping);
|
return get(TrackableProperty.Equipping);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<CardView> getEquippedBy() {
|
public FCollectionView<CardView> getEquippedBy() {
|
||||||
return get(TrackableProperty.EquippedBy);
|
return get(TrackableProperty.EquippedBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +437,7 @@ public class CardView extends GameEntityView {
|
|||||||
return get(TrackableProperty.Fortifying);
|
return get(TrackableProperty.Fortifying);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<CardView> getFortifiedBy() {
|
public FCollectionView<CardView> getFortifiedBy() {
|
||||||
return get(TrackableProperty.FortifiedBy);
|
return get(TrackableProperty.FortifiedBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +445,7 @@ public class CardView extends GameEntityView {
|
|||||||
return getFortifiedBy() != null;
|
return getFortifiedBy() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<CardView> getGainControlTargets() {
|
public FCollectionView<CardView> getGainControlTargets() {
|
||||||
return get(TrackableProperty.GainControlTargets);
|
return get(TrackableProperty.GainControlTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,11 +453,11 @@ public class CardView extends GameEntityView {
|
|||||||
return get(TrackableProperty.CloneOrigin);
|
return get(TrackableProperty.CloneOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<CardView> getImprintedCards() {
|
public FCollectionView<CardView> getImprintedCards() {
|
||||||
return get(TrackableProperty.ImprintedCards);
|
return get(TrackableProperty.ImprintedCards);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<CardView> getHauntedBy() {
|
public FCollectionView<CardView> getHauntedBy() {
|
||||||
return get(TrackableProperty.HauntedBy);
|
return get(TrackableProperty.HauntedBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +465,7 @@ public class CardView extends GameEntityView {
|
|||||||
return get(TrackableProperty.Haunting);
|
return get(TrackableProperty.Haunting);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<CardView> getMustBlockCards() {
|
public FCollectionView<CardView> getMustBlockCards() {
|
||||||
return get(TrackableProperty.MustBlockCards);
|
return get(TrackableProperty.MustBlockCards);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,9 +644,9 @@ public class CardView extends GameEntityView {
|
|||||||
return getCurrentState().getName();
|
return getCurrentState().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mayBeShown) {
|
/*if (!mayBeShown) {
|
||||||
return "(Unknown card)";
|
return "???";
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (StringUtils.isEmpty(getCurrentState().getName())) {
|
if (StringUtils.isEmpty(getCurrentState().getName())) {
|
||||||
CardStateView alternate = getAlternateState();
|
CardStateView alternate = getAlternateState();
|
||||||
@@ -599,8 +709,8 @@ public class CardView extends GameEntityView {
|
|||||||
set(TrackableProperty.Colors, c.determineColor());
|
set(TrackableProperty.Colors, c.determineColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getImageKey(boolean ignoreMayBeShown) {
|
public String getImageKey(PlayerView viewer) {
|
||||||
if (mayBeShown || ignoreMayBeShown) {
|
if (viewer == null || canBeShownTo(viewer)) {
|
||||||
return get(TrackableProperty.ImageKey);
|
return get(TrackableProperty.ImageKey);
|
||||||
}
|
}
|
||||||
return ImageKeys.HIDDEN_CARD;
|
return ImageKeys.HIDDEN_CARD;
|
||||||
@@ -741,6 +851,12 @@ public class CardView extends GameEntityView {
|
|||||||
public boolean hasTrample() {
|
public boolean hasTrample() {
|
||||||
return get(TrackableProperty.HasTrample);
|
return get(TrackableProperty.HasTrample);
|
||||||
}
|
}
|
||||||
|
public boolean getYouMayLook() {
|
||||||
|
return get(TrackableProperty.YouMayLook);
|
||||||
|
}
|
||||||
|
public boolean getOpponentMayLook() {
|
||||||
|
return get(TrackableProperty.OpponentMayLook);
|
||||||
|
}
|
||||||
public int getBlockAdditional() {
|
public int getBlockAdditional() {
|
||||||
return get(TrackableProperty.BlockAdditional);
|
return get(TrackableProperty.BlockAdditional);
|
||||||
}
|
}
|
||||||
@@ -756,6 +872,7 @@ public class CardView extends GameEntityView {
|
|||||||
set(TrackableProperty.HasInfect, c.hasKeyword("Infect", state));
|
set(TrackableProperty.HasInfect, c.hasKeyword("Infect", state));
|
||||||
set(TrackableProperty.HasStorm, c.hasKeyword("Storm", state));
|
set(TrackableProperty.HasStorm, c.hasKeyword("Storm", state));
|
||||||
set(TrackableProperty.HasTrample, c.hasKeyword("Trample", state));
|
set(TrackableProperty.HasTrample, c.hasKeyword("Trample", state));
|
||||||
|
set(TrackableProperty.OpponentMayLook, c.hasKeyword("Your opponent may look at this card."));
|
||||||
set(TrackableProperty.BlockAdditional, c.getAmountOfKeyword("CARDNAME can block an additional creature.", state));
|
set(TrackableProperty.BlockAdditional, c.getAmountOfKeyword("CARDNAME can block an additional creature.", state));
|
||||||
updateAbilityText(c, state);
|
updateAbilityText(c, state);
|
||||||
}
|
}
|
||||||
@@ -895,13 +1012,4 @@ public class CardView extends GameEntityView {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//below are properties not shared across game instances
|
|
||||||
private boolean mayBeShown = true; //TODO: Make may be shown get updated
|
|
||||||
public boolean mayBeShown() {
|
|
||||||
return mayBeShown;
|
|
||||||
}
|
|
||||||
public void setMayBeShown(boolean mayBeShown0) {
|
|
||||||
//mayBeShown = mayBeShown0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2080,6 +2080,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mindSlaveMaster = mindSlaveMaster0;
|
mindSlaveMaster = mindSlaveMaster0;
|
||||||
|
view.updateMindSlaveMaster(this);
|
||||||
|
|
||||||
if (mindSlaveMaster != null) {
|
if (mindSlaveMaster != null) {
|
||||||
LobbyPlayer oldLobbyPlayer = getLobbyPlayer();
|
LobbyPlayer oldLobbyPlayer = getLobbyPlayer();
|
||||||
|
|||||||
@@ -104,6 +104,9 @@ public class PlayerView extends GameEntityView {
|
|||||||
public KeywordCollectionView getKeywords() {
|
public KeywordCollectionView getKeywords() {
|
||||||
return get(TrackableProperty.Keywords);
|
return get(TrackableProperty.Keywords);
|
||||||
}
|
}
|
||||||
|
public boolean hasKeyword(String keyword) {
|
||||||
|
return getKeywords().contains(keyword);
|
||||||
|
}
|
||||||
void updateKeywords(Player p) {
|
void updateKeywords(Player p) {
|
||||||
set(TrackableProperty.Keywords, p.getKeywords());
|
set(TrackableProperty.Keywords, p.getKeywords());
|
||||||
}
|
}
|
||||||
@@ -130,6 +133,13 @@ public class PlayerView extends GameEntityView {
|
|||||||
throw new NotImplementedException("Not implemented");
|
throw new NotImplementedException("Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PlayerView getMindSlaveMaster() {
|
||||||
|
return get(TrackableProperty.Commander);
|
||||||
|
}
|
||||||
|
void updateMindSlaveMaster(Player p) {
|
||||||
|
set(TrackableProperty.Commander, PlayerView.get(p.getMindSlaveMaster()));
|
||||||
|
}
|
||||||
|
|
||||||
public Iterable<CardView> getAnte() {
|
public Iterable<CardView> getAnte() {
|
||||||
return get(TrackableProperty.Ante);
|
return get(TrackableProperty.Ante);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
package forge.trackable;
|
package forge.trackable;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import forge.util.FCollection;
|
import forge.util.FCollection;
|
||||||
|
|
||||||
public class TrackableCollection<T extends TrackableObject> extends FCollection<T> {
|
public class TrackableCollection<T extends TrackableObject> extends FCollection<T> {
|
||||||
public TrackableCollection() {
|
public TrackableCollection() {
|
||||||
}
|
}
|
||||||
|
public TrackableCollection(T e) {
|
||||||
|
super(e);
|
||||||
|
}
|
||||||
|
public TrackableCollection(Collection<T> c) {
|
||||||
|
super(c);
|
||||||
|
}
|
||||||
|
public TrackableCollection(Iterable<T> i) {
|
||||||
|
super(i);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean add(T item) {
|
public boolean add(T item) {
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public enum TrackableProperty {
|
|||||||
ChosenDirection(TrackableTypes.EnumType(Direction.class)),
|
ChosenDirection(TrackableTypes.EnumType(Direction.class)),
|
||||||
Remembered(TrackableTypes.StringType),
|
Remembered(TrackableTypes.StringType),
|
||||||
NamedCard(TrackableTypes.StringType),
|
NamedCard(TrackableTypes.StringType),
|
||||||
|
PlayerMayLook(TrackableTypes.PlayerViewCollectionType),
|
||||||
|
PlayerMayLookTemp(TrackableTypes.PlayerViewCollectionType),
|
||||||
Equipping(TrackableTypes.CardViewType),
|
Equipping(TrackableTypes.CardViewType),
|
||||||
EquippedBy(TrackableTypes.CardViewCollectionType),
|
EquippedBy(TrackableTypes.CardViewCollectionType),
|
||||||
Enchanting(TrackableTypes.GameEntityViewType),
|
Enchanting(TrackableTypes.GameEntityViewType),
|
||||||
@@ -74,6 +76,8 @@ public enum TrackableProperty {
|
|||||||
HasInfect(TrackableTypes.BooleanType),
|
HasInfect(TrackableTypes.BooleanType),
|
||||||
HasStorm(TrackableTypes.BooleanType),
|
HasStorm(TrackableTypes.BooleanType),
|
||||||
HasTrample(TrackableTypes.BooleanType),
|
HasTrample(TrackableTypes.BooleanType),
|
||||||
|
YouMayLook(TrackableTypes.BooleanType),
|
||||||
|
OpponentMayLook(TrackableTypes.BooleanType),
|
||||||
BlockAdditional(TrackableTypes.IntegerType),
|
BlockAdditional(TrackableTypes.IntegerType),
|
||||||
AbilityText(TrackableTypes.StringType),
|
AbilityText(TrackableTypes.StringType),
|
||||||
NonAbilityText(TrackableTypes.StringType),
|
NonAbilityText(TrackableTypes.StringType),
|
||||||
@@ -90,6 +94,7 @@ public enum TrackableProperty {
|
|||||||
Keywords(TrackableTypes.KeywordCollectionViewType),
|
Keywords(TrackableTypes.KeywordCollectionViewType),
|
||||||
Commander(TrackableTypes.CardViewType),
|
Commander(TrackableTypes.CardViewType),
|
||||||
CommanderDamage(TrackableTypes.IntegerMapType),
|
CommanderDamage(TrackableTypes.IntegerMapType),
|
||||||
|
MindSlaveMaster(TrackableTypes.PlayerViewType),
|
||||||
Ante(TrackableTypes.CardViewCollectionType),
|
Ante(TrackableTypes.CardViewCollectionType),
|
||||||
Battlefield(TrackableTypes.CardViewCollectionType),
|
Battlefield(TrackableTypes.CardViewCollectionType),
|
||||||
Command(TrackableTypes.CardViewCollectionType),
|
Command(TrackableTypes.CardViewCollectionType),
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import forge.assets.FSkinProp;
|
|||||||
import forge.assets.ImageUtil;
|
import forge.assets.ImageUtil;
|
||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
import forge.item.InventoryItem;
|
import forge.item.InventoryItem;
|
||||||
|
import forge.match.MatchUtil;
|
||||||
import forge.properties.ForgeConstants;
|
import forge.properties.ForgeConstants;
|
||||||
import forge.toolbox.FSkin;
|
import forge.toolbox.FSkin;
|
||||||
import forge.toolbox.FSkin.SkinIcon;
|
import forge.toolbox.FSkin.SkinIcon;
|
||||||
@@ -81,7 +82,7 @@ public class ImageCache {
|
|||||||
* and cannot be loaded from disk. pass -1 for width and/or height to avoid resizing in that dimension.
|
* and cannot be loaded from disk. pass -1 for width and/or height to avoid resizing in that dimension.
|
||||||
*/
|
*/
|
||||||
public static BufferedImage getImage(final CardView card, final int width, final int height) {
|
public static BufferedImage getImage(final CardView card, final int width, final int height) {
|
||||||
final String key = card.getCurrentState().getImageKey(false);
|
final String key = MatchUtil.getCardImageKey(card.getCurrentState());
|
||||||
return scaleImage(key, width, height, true);
|
return scaleImage(key, width, height, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (final PlayerView p : sortedPlayers) {
|
for (final PlayerView p : sortedPlayers) {
|
||||||
if (allHands || p.getLobbyPlayer() instanceof LobbyPlayerHuman || CardView.mayViewAny(p.getHand())) {
|
if (allHands || p.getLobbyPlayer() instanceof LobbyPlayerHuman || CardView.mayViewAny(p.getHand(), p)) {
|
||||||
VHand newHand = new VHand(EDocID.Hands[i], p);
|
VHand newHand = new VHand(EDocID.Hands[i], p);
|
||||||
newHand.getLayoutControl().initialize();
|
newHand.getLayoutControl().initialize();
|
||||||
hands.add(newHand);
|
hands.add(newHand);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import forge.gui.CardPicturePanel;
|
|||||||
import forge.gui.framework.ICDoc;
|
import forge.gui.framework.ICDoc;
|
||||||
import forge.item.IPaperCard;
|
import forge.item.IPaperCard;
|
||||||
import forge.item.InventoryItem;
|
import forge.item.InventoryItem;
|
||||||
|
import forge.match.MatchUtil;
|
||||||
import forge.screens.match.views.VPicture;
|
import forge.screens.match.views.VPicture;
|
||||||
import forge.toolbox.FMouseAdapter;
|
import forge.toolbox.FMouseAdapter;
|
||||||
import forge.toolbox.special.CardZoomer;
|
import forge.toolbox.special.CardZoomer;
|
||||||
@@ -62,15 +63,17 @@ public enum CPicture implements ICDoc {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void showCard(final CardView c, boolean showAlt) {
|
public void showCard(final CardView c, boolean showAlt) {
|
||||||
if (null == c) {
|
if (c == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean canFlip = MatchUtil.canFaceDownCardBeShown(c);
|
||||||
|
|
||||||
currentView = c;
|
currentView = c;
|
||||||
isDisplayAlt = showAlt;
|
isDisplayAlt = showAlt;
|
||||||
flipIndicator.setVisible(c.hasAlternateState());
|
flipIndicator.setVisible(canFlip);
|
||||||
picturePanel.setCard(c.getState(showAlt));
|
picturePanel.setCard(c.getState(showAlt));
|
||||||
if (showAlt && c.hasAlternateState()) {
|
if (showAlt && canFlip) {
|
||||||
flipCard();
|
flipCard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,7 +175,7 @@ public enum CPicture implements ICDoc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void flipCard() {
|
public void flipCard() {
|
||||||
if (currentView.hasAlternateState()) {
|
if (MatchUtil.canFaceDownCardBeShown(currentView)) {
|
||||||
isDisplayAlt = !isDisplayAlt;
|
isDisplayAlt = !isDisplayAlt;
|
||||||
picturePanel.setCard(currentView.getState(isDisplayAlt));
|
picturePanel.setCard(currentView.getState(isDisplayAlt));
|
||||||
CDetail.SINGLETON_INSTANCE.showCard(currentView, isDisplayAlt);
|
CDetail.SINGLETON_INSTANCE.showCard(currentView, isDisplayAlt);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.awt.image.ColorModel;
|
|||||||
|
|
||||||
import forge.ImageCache;
|
import forge.ImageCache;
|
||||||
import forge.game.card.CardView.CardStateView;
|
import forge.game.card.CardView.CardStateView;
|
||||||
|
import forge.match.MatchUtil;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
import forge.toolbox.CardFaceSymbols;
|
import forge.toolbox.CardFaceSymbols;
|
||||||
@@ -48,7 +49,7 @@ public final class FImageUtil {
|
|||||||
* For flip cards, returns the un-flipped image.
|
* For flip cards, returns the un-flipped image.
|
||||||
*/
|
*/
|
||||||
public static BufferedImage getImage(final CardStateView card) {
|
public static BufferedImage getImage(final CardStateView card) {
|
||||||
BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(false), true);
|
BufferedImage image = ImageCache.getOriginalImage(MatchUtil.getCardImageKey(card), true);
|
||||||
final int foilIndex = card.getFoilIndex();
|
final int foilIndex = card.getFoilIndex();
|
||||||
if (image != null && foilIndex > 0) {
|
if (image != null && foilIndex > 0) {
|
||||||
image = getImageWithFoilEffect(image, foilIndex);
|
image = getImageWithFoilEffect(image, foilIndex);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import forge.game.card.CardView;
|
|||||||
import forge.game.player.IHasIcon;
|
import forge.game.player.IHasIcon;
|
||||||
import forge.item.InventoryItem;
|
import forge.item.InventoryItem;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
|
import forge.match.MatchUtil;
|
||||||
import forge.properties.ForgeConstants;
|
import forge.properties.ForgeConstants;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -80,7 +81,7 @@ public class ImageCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Texture getImage(CardView card) {
|
public static Texture getImage(CardView card) {
|
||||||
final String key = card.getCurrentState().getImageKey(false);
|
final String key = MatchUtil.getCardImageKey(card.getCurrentState());
|
||||||
return getImage(key, true);
|
return getImage(key, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public class CardRenderer {
|
|||||||
float w = width - 2 * x;
|
float w = width - 2 * x;
|
||||||
float h = height - 2 * y;
|
float h = height - 2 * y;
|
||||||
|
|
||||||
final Texture image = ImageCache.getImage(card.getCurrentState().getImageKey(false), true);
|
final Texture image = ImageCache.getImage(MatchUtil.getCardImageKey(card.getCurrentState()), true);
|
||||||
if (image == ImageCache.defaultImage) { //support drawing card image manually if card image not found
|
if (image == ImageCache.defaultImage) { //support drawing card image manually if card image not found
|
||||||
float ratio = h / w;
|
float ratio = h / w;
|
||||||
if (ratio > FCardPanel.ASPECT_RATIO) {
|
if (ratio > FCardPanel.ASPECT_RATIO) {
|
||||||
@@ -220,7 +220,7 @@ public class CardRenderer {
|
|||||||
return getCardArt(ImageKeys.getImageKey(pc, false), pc.getRules().getSplitType() == CardSplitType.Split);
|
return getCardArt(ImageKeys.getImageKey(pc, false), pc.getRules().getSplitType() == CardSplitType.Split);
|
||||||
}
|
}
|
||||||
public static FImageComplex getCardArt(CardView card) {
|
public static FImageComplex getCardArt(CardView card) {
|
||||||
return getCardArt(card.getCurrentState().getImageKey(true), card.isSplitCard());
|
return getCardArt(card.getCurrentState().getImageKey(null), card.isSplitCard());
|
||||||
}
|
}
|
||||||
public static FImageComplex getCardArt(String imageKey, boolean isSplitCard) {
|
public static FImageComplex getCardArt(String imageKey, boolean isSplitCard) {
|
||||||
FImageComplex cardArt = cardArtCache.get(imageKey);
|
FImageComplex cardArt = cardArtCache.get(imageKey);
|
||||||
@@ -535,8 +535,10 @@ public class CardRenderer {
|
|||||||
Color color = FSkinColor.fromRGB(borderColor.r, borderColor.g, borderColor.b);
|
Color color = FSkinColor.fromRGB(borderColor.r, borderColor.g, borderColor.b);
|
||||||
color = FSkinColor.tintColor(Color.WHITE, color, CardRenderer.PT_BOX_TINT);
|
color = FSkinColor.tintColor(Color.WHITE, color, CardRenderer.PT_BOX_TINT);
|
||||||
|
|
||||||
|
boolean canShow = MatchUtil.canCardBeShown(card);
|
||||||
|
|
||||||
//draw name and mana cost overlays if card is small or default card image being used
|
//draw name and mana cost overlays if card is small or default card image being used
|
||||||
if (h <= NAME_COST_THRESHOLD && card.mayBeShown()) {
|
if (h <= NAME_COST_THRESHOLD && canShow) {
|
||||||
if (showCardNameOverlay(card)) {
|
if (showCardNameOverlay(card)) {
|
||||||
g.drawOutlinedText(details.getName(), FSkinFont.forHeight(h * 0.18f), Color.WHITE, Color.BLACK, x + padding, y + padding, w - 2 * padding, h * 0.4f, true, HAlignment.LEFT, false);
|
g.drawOutlinedText(details.getName(), FSkinFont.forHeight(h * 0.18f), Color.WHITE, Color.BLACK, x + padding, y + padding, w - 2 * padding, h * 0.4f, true, HAlignment.LEFT, false);
|
||||||
}
|
}
|
||||||
@@ -614,7 +616,7 @@ public class CardRenderer {
|
|||||||
CardFaceSymbols.drawSymbol("sacrifice", g, (x + (w / 2)) - sacSymbolSize / 2, (y + (h / 2)) - sacSymbolSize / 2, otherSymbolsSize, otherSymbolsSize);
|
CardFaceSymbols.drawSymbol("sacrifice", g, (x + (w / 2)) - sacSymbolSize / 2, (y + (h / 2)) - sacSymbolSize / 2, otherSymbolsSize, otherSymbolsSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onTop && showCardPowerOverlay(card) && (card.mayBeShown() || card.isFaceDown())) { //make sure card p/t box appears on top
|
if (onTop && showCardPowerOverlay(card) && (canShow || card.isFaceDown())) { //make sure card p/t box appears on top
|
||||||
//only needed if on top since otherwise P/T will be hidden
|
//only needed if on top since otherwise P/T will be hidden
|
||||||
drawPtBox(g, card, details, color, x, y, w, h);
|
drawPtBox(g, card, details, color, x, y, w, h);
|
||||||
}
|
}
|
||||||
@@ -676,7 +678,7 @@ public class CardRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void drawFoilEffect(Graphics g, CardView card, float x, float y, float w, float h) {
|
public static void drawFoilEffect(Graphics g, CardView card, float x, float y, float w, float h) {
|
||||||
if (isPreferenceEnabled(FPref.UI_OVERLAY_FOIL_EFFECT) && card.mayBeShown()) {
|
if (isPreferenceEnabled(FPref.UI_OVERLAY_FOIL_EFFECT) && MatchUtil.canCardBeShown(card)) {
|
||||||
int foil = card.getCurrentState().getFoilIndex();
|
int foil = card.getCurrentState().getFoilIndex();
|
||||||
if (foil > 0) {
|
if (foil > 0) {
|
||||||
CardFaceSymbols.drawOther(g, String.format("foil%02d", foil), x, y, w, h);
|
CardFaceSymbols.drawOther(g, String.format("foil%02d", foil), x, y, w, h);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class CardDetailUtil {
|
|||||||
if (card == null) {
|
if (card == null) {
|
||||||
return getBorderColors(null, false, false, false).iterator().next();
|
return getBorderColors(null, false, false, false).iterator().next();
|
||||||
}
|
}
|
||||||
return getBorderColors(card.getColors(), card.isLand(), card.getCard().mayBeShown(), false).iterator().next();
|
return getBorderColors(card.getColors(), card.isLand(), MatchUtil.canCardBeShown(card.getCard()), false).iterator().next();
|
||||||
}
|
}
|
||||||
public static DetailColors getBorderColor(final ColorSet cardColors, final boolean isLand, boolean canShow) {
|
public static DetailColors getBorderColor(final ColorSet cardColors, final boolean isLand, boolean canShow) {
|
||||||
return getBorderColors(cardColors, isLand, canShow, false).get(0);
|
return getBorderColors(cardColors, isLand, canShow, false).get(0);
|
||||||
@@ -63,7 +63,7 @@ public class CardDetailUtil {
|
|||||||
if (card == null) {
|
if (card == null) {
|
||||||
return getBorderColors(null, false, false, true);
|
return getBorderColors(null, false, false, true);
|
||||||
}
|
}
|
||||||
return getBorderColors(card.getColors(), card.isLand(), card.getCard().mayBeShown(), true);
|
return getBorderColors(card.getColors(), card.isLand(), MatchUtil.canCardBeShown(card.getCard()), true);
|
||||||
}
|
}
|
||||||
private static List<DetailColors> getBorderColors(final ColorSet cardColors, final boolean isLand, boolean canShow, boolean supportMultiple) {
|
private static List<DetailColors> getBorderColors(final ColorSet cardColors, final boolean isLand, boolean canShow, boolean supportMultiple) {
|
||||||
List<DetailColors> borderColors = new ArrayList<DetailColors>();
|
List<DetailColors> borderColors = new ArrayList<DetailColors>();
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ package forge.control;
|
|||||||
|
|
||||||
import forge.LobbyPlayer;
|
import forge.LobbyPlayer;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.card.Card;
|
|
||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.player.PlayerView;
|
import forge.game.player.PlayerView;
|
||||||
@@ -91,16 +90,6 @@ public class WatchLocalGame extends PlayerControllerHuman {
|
|||||||
public void alphaStrike() {
|
public void alphaStrike() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean mayShowCard(final Card c) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean mayShowCardFace(final Card c) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> getAutoYields() {
|
public Iterable<String> getAutoYields() {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
@@ -29,6 +30,7 @@ import forge.game.GameType;
|
|||||||
import forge.game.GameView;
|
import forge.game.GameView;
|
||||||
import forge.game.Match;
|
import forge.game.Match;
|
||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
|
import forge.game.card.CardView.CardStateView;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.player.PlayerView;
|
import forge.game.player.PlayerView;
|
||||||
import forge.game.player.RegisteredPlayer;
|
import forge.game.player.RegisteredPlayer;
|
||||||
@@ -279,6 +281,18 @@ public class MatchUtil {
|
|||||||
return controller.assignDamage(attacker, blockers, damage, defender, overrideOrder);
|
return controller.assignDamage(attacker, blockers, damage, defender, overrideOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getCardImageKey(CardStateView csv) {
|
||||||
|
return csv.getImageKey(getCurrentPlayer().getView());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canCardBeShown(CardView cv) {
|
||||||
|
return cv.canBeShownTo(getCurrentPlayer().getView());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canFaceDownCardBeShown(CardView cv) {
|
||||||
|
return cv.hasAlternateState() && cv.canFaceDownBeShownTo(getCurrentPlayer().getView());
|
||||||
|
}
|
||||||
|
|
||||||
private static Set<PlayerView> highlightedPlayers = new HashSet<PlayerView>();
|
private static Set<PlayerView> highlightedPlayers = new HashSet<PlayerView>();
|
||||||
public static void setHighlighted(PlayerView pv, boolean b) {
|
public static void setHighlighted(PlayerView pv, boolean b) {
|
||||||
if (b) {
|
if (b) {
|
||||||
|
|||||||
@@ -176,12 +176,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
}
|
}
|
||||||
private void tempShowCard(Card c) {
|
private void tempShowCard(Card c) {
|
||||||
if (c == null) { return; }
|
if (c == null) { return; }
|
||||||
|
c.setMayLookAt(player, true, true);
|
||||||
CardView cv = c.getView();
|
|
||||||
if (!cv.mayBeShown()) {
|
|
||||||
cv.setMayBeShown(true);
|
|
||||||
tempShownCards.add(c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private void tempShowCards(Iterable<Card> cards) {
|
private void tempShowCards(Iterable<Card> cards) {
|
||||||
if (mayLookAtAllCards) { return; } //no needed if this is set
|
if (mayLookAtAllCards) { return; } //no needed if this is set
|
||||||
@@ -194,7 +189,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
if (tempShownCards.isEmpty()) { return; }
|
if (tempShownCards.isEmpty()) { return; }
|
||||||
|
|
||||||
for (Card c : tempShownCards) {
|
for (Card c : tempShownCards) {
|
||||||
c.getView().setMayBeShown(false);
|
c.setMayLookAt(player, false, true);
|
||||||
}
|
}
|
||||||
tempShownCards.clear();
|
tempShownCards.clear();
|
||||||
}
|
}
|
||||||
@@ -1381,27 +1376,6 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
inputProxy.alphaStrike();
|
inputProxy.alphaStrike();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether a card may be shown. If {@code mayLookAtAllCards} is
|
|
||||||
* {@code true}, any card may be shown.
|
|
||||||
*
|
|
||||||
* @param c a card.
|
|
||||||
* @return whether the card may be shown.
|
|
||||||
* @see GameView#mayShowCardNoRedirect(CardView)
|
|
||||||
*/
|
|
||||||
public boolean mayShowCard(final Card c) {
|
|
||||||
if (mayLookAtAllCards) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return c == null || tempShownCards.contains(c) || c.canBeShownTo(player);
|
|
||||||
}
|
|
||||||
public boolean mayShowCardFace(final Card c) {
|
|
||||||
if (mayLookAtAllCards) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return c == null || !c.isFaceDown() || c.canCardFaceBeShownTo(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resetAtEndOfTurn() {
|
public void resetAtEndOfTurn() {
|
||||||
// Not used by the human controller
|
// Not used by the human controller
|
||||||
|
|||||||
Reference in New Issue
Block a user