[UI] Displaying playable cards in hand

This commit is contained in:
magenoxx 2014-07-11 19:35:01 +04:00
parent 2fcf655994
commit 5fcc3b1ba8
9 changed files with 119 additions and 193 deletions

View file

@ -310,7 +310,7 @@ public class Cards extends javax.swing.JPanel {
Collections.sort(cards, new Comparator<CardPanel>() {
@Override
public int compare(CardPanel cp1, CardPanel cp2) {
return Integer.valueOf(cp1.getLocation().x).compareTo(Integer.valueOf(cp2.getLocation().x));
return Integer.valueOf(cp1.getLocation().x).compareTo(cp2.getLocation().x);
}
});

View file

@ -27,47 +27,6 @@
*/
package mage.client.game;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import javax.swing.AbstractAction;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingWorker;
import javax.swing.border.LineBorder;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import mage.cards.Card;
import mage.cards.action.ActionCallback;
import mage.client.MageFrame;
@ -78,12 +37,7 @@ import mage.client.components.HoverButton;
import mage.client.components.MageComponents;
import mage.client.components.ext.dlg.DialogManager;
import mage.client.components.layout.RelativeLayout;
import mage.client.dialog.ExileZoneDialog;
import mage.client.dialog.PickChoiceDialog;
import mage.client.dialog.PickNumberDialog;
import mage.client.dialog.PickPileDialog;
import mage.client.dialog.PreferencesDialog;
import mage.client.dialog.ShowCardsDialog;
import mage.client.dialog.*;
import mage.client.game.FeedbackPanel.FeedbackMode;
import mage.client.plugins.adapters.MageActionCallback;
import mage.client.plugins.impl.Plugins;
@ -94,29 +48,23 @@ import mage.client.util.PhaseManager;
import mage.client.util.gui.ArrowBuilder;
import mage.constants.EnlargeMode;
import mage.constants.PhaseStep;
import static mage.constants.PhaseStep.BEGIN_COMBAT;
import static mage.constants.PhaseStep.COMBAT_DAMAGE;
import static mage.constants.PhaseStep.DECLARE_ATTACKERS;
import static mage.constants.PhaseStep.DECLARE_BLOCKERS;
import static mage.constants.PhaseStep.DRAW;
import static mage.constants.PhaseStep.END_COMBAT;
import static mage.constants.PhaseStep.END_TURN;
import static mage.constants.PhaseStep.FIRST_COMBAT_DAMAGE;
import static mage.constants.PhaseStep.UNTAP;
import static mage.constants.PhaseStep.UPKEEP;
import mage.remote.Session;
import mage.view.AbilityPickerView;
import mage.view.CardsView;
import mage.view.ExileView;
import mage.view.GameView;
import mage.view.LookedAtView;
import mage.view.MatchView;
import mage.view.PlayerView;
import mage.view.RevealedView;
import mage.view.SimpleCardsView;
import mage.view.*;
import org.apache.log4j.Logger;
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
import javax.swing.*;
import javax.swing.GroupLayout.Alignment;
import javax.swing.border.LineBorder;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
/**
*
* @author BetaSteward_at_googlemail.com, nantuko8
@ -503,6 +451,15 @@ public final class GamePanel extends javax.swing.JPanel {
handCards.clear();
handCards.put(YOUR_HAND, CardsViewUtil.convertSimple(game.getHand(), loadedCards));
// Mark playable
if (game.getCanPlayInHand() != null) {
for (CardView card : handCards.get(YOUR_HAND).values()) {
if (game.getCanPlayInHand().contains(card.getId())) {
card.setPlayable(true);
}
}
}
// Get opponents hand cards if available
if (game.getOpponentHands() != null) {
for (Map.Entry<String, SimpleCardsView> hand: game.getOpponentHands().entrySet()) {

View file

@ -80,6 +80,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
public int cardXOffset, cardYOffset, cardWidth, cardHeight;
private boolean isSelected;
private boolean isPlayable;
private boolean showCastingCost;
private boolean hasImage = false;
private float alpha = 1.0f;
@ -420,6 +421,11 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
}
if (isPlayable) {
g2d.setColor(new Color(250, 250, 0, 200));
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
}
//TODO:uncomment
/*
if (gameCard.isAttacking()) {
@ -708,6 +714,8 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
}
setText(card);
this.isPlayable = card.isPlayable();
boolean updateImage = !gameCard.getName().equals(card.getName()) || gameCard.isFaceDown() != card.isFaceDown(); // update after e.g. turning a night/day card
this.gameCard = card;

View file

@ -28,17 +28,11 @@
package mage.view;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageObject;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.Modes;
import mage.abilities.SpellAbility;
import mage.abilities.common.TurnFaceUpAbility;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.keyword.MorphAbility;
import mage.cards.Card;
import mage.cards.SplitCard;
import mage.constants.CardType;
@ -49,7 +43,6 @@ import mage.counters.Counter;
import mage.counters.CounterType;
import mage.game.command.Emblem;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentToken;
import mage.game.permanent.token.Token;
import mage.game.stack.Spell;
@ -57,6 +50,10 @@ import mage.game.stack.StackAbility;
import mage.target.Target;
import mage.target.Targets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @author BetaSteward_at_googlemail.com
*/
@ -114,6 +111,8 @@ public class CardView extends SimpleCardView {
protected boolean rotate;
protected boolean hideInfo; // controlls if the tooltip window is shown (eg. controlled face down morph card)
protected boolean isPlayable;
public CardView(Card card) {
this(card, null, false);
}
@ -673,5 +672,12 @@ public class CardView extends SimpleCardView {
public boolean hideInfo() {
return hideInfo;
}
public boolean isPlayable() {
return isPlayable;
}
public void setPlayable(boolean isPlayable) {
this.isPlayable = isPlayable;
}
}

View file

@ -28,11 +28,6 @@
package mage.view;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.costs.Cost;
import mage.cards.Card;
@ -51,6 +46,9 @@ import mage.game.stack.StackAbility;
import mage.game.stack.StackObject;
import mage.players.Player;
import java.io.Serializable;
import java.util.*;
/**
*
@ -62,6 +60,7 @@ public class GameView implements Serializable {
private final int priorityTime;
private final List<PlayerView> players = new ArrayList<>();
private SimpleCardsView hand;
private Set<UUID> canPlayInHand;
private Map<String, SimpleCardsView> opponentHands;
private final CardsView stack = new CardsView();
private final List<ExileView> exiles = new ArrayList<>();
@ -280,4 +279,11 @@ public class GameView implements Serializable {
return isPlayer;
}
public Set<UUID> getCanPlayInHand() {
return canPlayInHand;
}
public void setCanPlayInHand(Set<UUID> canPlayInHand) {
this.canPlayInHand = canPlayInHand;
}
}

View file

@ -28,17 +28,6 @@
package mage.server.game;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import mage.cards.Cards;
import mage.constants.ManaType;
import mage.game.Game;
@ -50,14 +39,16 @@ import mage.server.User;
import mage.server.UserManager;
import mage.server.util.ConfigSettings;
import mage.server.util.ThreadExecutor;
import mage.view.AbilityPickerView;
import mage.view.CardsView;
import mage.view.GameClientMessage;
import mage.view.GameView;
import mage.view.LookedAtView;
import mage.view.SimpleCardsView;
import mage.view.*;
import org.apache.log4j.Logger;
import java.io.Serializable;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
*
* @author BetaSteward_at_googlemail.com
@ -245,15 +236,9 @@ public class GameSession extends GameWatcher {
player.setUserData(this.userData);
GameView gameView = new GameView(game.getState(), game, playerId);
gameView.setHand(new SimpleCardsView(player.getHand().getCards(game)));
gameView.setCanPlayInHand(player.getPlayableInHand(game));
if (player.getPlayersUnderYourControl().size() > 0) {
Map<String, SimpleCardsView> handCards = new HashMap<>();
for (UUID controlledPlayerId : player.getPlayersUnderYourControl()) {
Player opponent = game.getPlayer(controlledPlayerId);
handCards.put(opponent.getName(), new SimpleCardsView(opponent.getHand().getCards(game)));
}
gameView.setOpponentHands(handCards);
}
processControlledPlayers(player, gameView);
//TODO: should player who controls another player's turn be able to look at all these cards?
@ -267,6 +252,17 @@ public class GameSession extends GameWatcher {
return gameView;
}
private void processControlledPlayers(Player player, GameView gameView) {
if (player.getPlayersUnderYourControl().size() > 0) {
Map<String, SimpleCardsView> handCards = new HashMap<>();
for (UUID controlledPlayerId : player.getPlayersUnderYourControl()) {
Player opponent = game.getPlayer(controlledPlayerId);
handCards.put(opponent.getName(), new SimpleCardsView(opponent.getHand().getCards(game)));
}
gameView.setOpponentHands(handCards);
}
}
public void removeGame() {
User user = UserManager.getInstance().getUser(userId);
if (user != null) {

View file

@ -28,23 +28,6 @@
package mage.game;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
@ -68,13 +51,7 @@ import mage.cards.CardsImpl;
import mage.cards.SplitCard;
import mage.cards.decks.Deck;
import mage.choices.Choice;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.MultiplayerAttackOption;
import mage.constants.Outcome;
import mage.constants.PhaseStep;
import mage.constants.RangeOfInfluence;
import mage.constants.Zone;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.Filter;
import mage.filter.FilterPermanent;
@ -89,14 +66,8 @@ import mage.game.combat.Combat;
import mage.game.command.CommandObject;
import mage.game.command.Commander;
import mage.game.command.Emblem;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.events.Listener;
import mage.game.events.PlayerQueryEvent;
import mage.game.events.PlayerQueryEventSource;
import mage.game.events.TableEvent;
import mage.game.events.*;
import mage.game.events.TableEvent.EventType;
import mage.game.events.TableEventSource;
import mage.game.permanent.Battlefield;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
@ -114,14 +85,14 @@ import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.TargetPlayer;
import mage.util.functions.ApplyToPermanent;
import mage.watchers.common.CastSpellLastTurnWatcher;
import mage.watchers.common.MiracleWatcher;
import mage.watchers.common.MorbidWatcher;
import mage.watchers.common.PlayerDamagedBySourceWatcher;
import mage.watchers.common.PlayerLostLifeWatcher;
import mage.watchers.common.SoulbondWatcher;
import mage.watchers.common.*;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.io.Serializable;
import java.util.*;
import java.util.Map.Entry;
public abstract class GameImpl implements Game, Serializable {
private static final transient Logger logger = Logger.getLogger(GameImpl.class);
@ -1846,7 +1817,7 @@ public abstract class GameImpl implements Game, Serializable {
@Override
public boolean canPlaySorcery(UUID playerId) {
return getActivePlayerId().equals(playerId) && getStack().isEmpty() && isMainPhase();
return isMainPhase() && getActivePlayerId().equals(playerId) && getStack().isEmpty();
}
/**

View file

@ -28,21 +28,9 @@
package mage.players;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import mage.MageItem;
import mage.MageObject;
import mage.abilities.Abilities;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.Mode;
import mage.abilities.Modes;
import mage.abilities.SpellAbility;
import mage.abilities.TriggeredAbility;
import mage.abilities.*;
import mage.abilities.costs.AlternativeSourceCosts;
import mage.abilities.costs.VariableCost;
import mage.abilities.costs.mana.ManaCost;
@ -69,6 +57,9 @@ import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
import mage.util.Copyable;
import java.io.Serializable;
import java.util.*;
/**
*
* @author BetaSteward_at_googlemail.com
@ -340,6 +331,8 @@ public interface Player extends MageItem, Copyable<Player> {
List<Ability> getPlayable(Game game, boolean hidden);
List<Ability> getPlayableOptions(Ability ability, Game game);
Set<UUID> getPlayableInHand(Game game);
void addCounters(Counter counter, Game game);
List<UUID> getAttachments();
boolean addAttachment(UUID permanentId, Game game);

View file

@ -28,31 +28,9 @@
package mage.players;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
import mage.Mana;
import mage.abilities.Abilities;
import mage.abilities.AbilitiesImpl;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.Mode;
import mage.abilities.PlayLandAbility;
import mage.abilities.SpecialAction;
import mage.abilities.SpellAbility;
import mage.abilities.TriggeredAbility;
import mage.abilities.*;
import mage.abilities.common.PassAbility;
import mage.abilities.common.delayed.AtTheEndOfTurnStepPostDelayedTriggeredAbility;
import mage.abilities.costs.AdjustingSourceCosts;
@ -62,12 +40,7 @@ import mage.abilities.costs.AlternativeSourceCosts;
import mage.abilities.effects.RestrictionEffect;
import mage.abilities.effects.RestrictionUntapNotMoreThanEffect;
import mage.abilities.effects.common.LoseControlOnOtherPlayersControllerEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.abilities.keyword.HexproofAbility;
import mage.abilities.keyword.InfectAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.abilities.keyword.ShroudAbility;
import mage.abilities.keyword.*;
import mage.abilities.mana.ManaAbility;
import mage.abilities.mana.ManaOptions;
import mage.actions.MageDrawAction;
@ -76,14 +49,7 @@ import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.SplitCard;
import mage.cards.decks.Deck;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.RangeOfInfluence;
import mage.constants.SpellAbilityType;
import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.constants.*;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.counters.Counters;
@ -116,6 +82,10 @@ import mage.target.common.TargetDiscard;
import mage.watchers.common.BloodthirstWatcher;
import org.apache.log4j.Logger;
import java.io.Serializable;
import java.util.*;
import java.util.Map.Entry;
public abstract class PlayerImpl implements Player, Serializable {
private static final transient Logger log = Logger.getLogger(PlayerImpl.class);
@ -1973,6 +1943,25 @@ public abstract class PlayerImpl implements Player, Serializable {
return playable;
}
@Override
public Set<UUID> getPlayableInHand(Game game) {
Set<UUID> playable = new HashSet<>();
ManaOptions available = getManaAvailable(game);
available.addMana(manaPool.getMana());
for (Card card: hand.getCards(game)) {
for (ActivatedAbility ability: card.getAbilities().getPlayableAbilities(Zone.HAND)) {
if (canPlay(ability, available, game)) {
playable.add(card.getId());
break;
}
}
}
return playable;
}
/**
* Only used for AIs
*