1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.magicproject.clickable.targetable.player;
21
22 import java.awt.BorderLayout;
23 import java.awt.Color;
24 import java.awt.Dimension;
25 import java.awt.FlowLayout;
26 import java.awt.Font;
27 import java.awt.Graphics;
28 import java.awt.Graphics2D;
29 import java.awt.Image;
30 import java.awt.event.MouseEvent;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.util.List;
34
35 import javax.swing.BoxLayout;
36 import javax.swing.JButton;
37 import javax.swing.JLabel;
38 import javax.swing.JPanel;
39 import javax.swing.JSplitPane;
40 import javax.swing.border.EtchedBorder;
41
42 import net.sf.magicproject.action.PayMana;
43 import net.sf.magicproject.action.WaitActivatedChoice;
44 import net.sf.magicproject.action.WaitTriggeredBufferChoice;
45 import net.sf.magicproject.action.target.ChoosenTarget;
46 import net.sf.magicproject.clickable.ability.Ability;
47 import net.sf.magicproject.clickable.mana.ManaPool;
48 import net.sf.magicproject.clickable.targetable.Targetable;
49 import net.sf.magicproject.clickable.targetable.TargetableFactory;
50 import net.sf.magicproject.clickable.targetable.card.CardFactory;
51 import net.sf.magicproject.clickable.targetable.card.TriggeredCard;
52 import net.sf.magicproject.deckbuilder.Deck;
53 import net.sf.magicproject.modifier.RegisterIndirection;
54 import net.sf.magicproject.modifier.RegisterModifier;
55 import net.sf.magicproject.network.ConnectionManager;
56 import net.sf.magicproject.network.IdMessages;
57 import net.sf.magicproject.network.Synchronizer;
58 import net.sf.magicproject.operation.Operation;
59 import net.sf.magicproject.stack.ActionManager;
60 import net.sf.magicproject.stack.EventManager;
61 import net.sf.magicproject.stack.MPhase;
62 import net.sf.magicproject.stack.StackManager;
63 import net.sf.magicproject.stack.TargetHelper;
64 import net.sf.magicproject.token.IdTokens;
65 import net.sf.magicproject.token.MCommonVars;
66 import net.sf.magicproject.tools.Configuration;
67 import net.sf.magicproject.tools.Log;
68 import net.sf.magicproject.ui.MagicUIComponents;
69 import net.sf.magicproject.ui.UIHelper;
70 import net.sf.magicproject.ui.i18n.LanguageManager;
71 import net.sf.magicproject.zone.ZoneManager;
72
73 /***
74 * Represents a player : name (avatar, preferences,...), mana and zones. Has
75 * also a register like cards to store data as life, poison, maximal number of
76 * cards in hand and number of cards to draw counter.<br>
77 * TODO support modifiers for player components, like cards.
78 *
79 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
80 */
81 public abstract class Player extends Targetable {
82
83 /***
84 * Player view width
85 */
86 public static final int PLAYER_SIZE_WIDTH = 80;
87
88 /***
89 * Player view height
90 */
91 public static final int PLAYER_SIZE_HEIGHT = 40;
92
93 /***
94 * creates a new instance of MPlayer
95 *
96 * @param idPlayer
97 * id of this player
98 * @param mana
99 * manas of this player
100 * @param zoneManager
101 * the zoneManager of this player
102 * @param morePanel
103 * the panel containing player info.
104 */
105 protected Player(int idPlayer, ManaPool mana, ZoneManager zoneManager,
106 JPanel morePanel) {
107 this.idPlayer = idPlayer;
108 this.zoneManager = zoneManager;
109 this.mana = mana;
110 this.morePanel = morePanel;
111 setForeground(Color.RED);
112 setBorder(new EtchedBorder());
113 addMouseListener(this);
114 setPreferredSize(new Dimension(130, PLAYER_SIZE_HEIGHT));
115 playerCard = new PlayerCard(this);
116 avatarButton = new AvatarButton();
117 avatarButton.setMinimumSize(new Dimension(1, 180));
118 avatarButton.addMouseListener(this);
119 mainPanel = new JPanel(new BorderLayout());
120 mainPanel.setBorder(null);
121 infoPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
122
123 lifeLabel = new JLabel("", UIHelper.getIcon("life.gif"), 0);
124 lifeLabel.setBackground(Color.pink);
125 lifeLabel.setForeground(new Color(0, 153, 153));
126 lifeLabel.setToolTipText(LanguageManager.getString("life"));
127 lifeLabel.setBorder(new EtchedBorder());
128 lifeLabel.setIconTextGap(6);
129 lifeLabel.setPreferredSize(new Dimension(45, PLAYER_SIZE_HEIGHT));
130 lifeLabel.setOpaque(true);
131
132 poisonLabel = new JLabel("", UIHelper.getIcon("poison.gif"), 0);
133 poisonLabel.setBackground(new Color(0, 102, 0));
134 poisonLabel.setForeground(new Color(153, 255, 153));
135 poisonLabel.setToolTipText(LanguageManager.getString("poison"));
136 poisonLabel.setBorder(new EtchedBorder());
137 poisonLabel.setIconTextGap(6);
138 poisonLabel.setPreferredSize(new Dimension(45, PLAYER_SIZE_HEIGHT));
139 poisonLabel.setOpaque(true);
140
141 phases = new JPanel();
142 phases.setLayout(new BoxLayout(phases, BoxLayout.Y_AXIS));
143 phases.setOpaque(false);
144 phases.setMinimumSize(new Dimension(43, PLAYER_SIZE_WIDTH));
145
146 handSplitter = new JSplitPane();
147 handSplitter.setDividerSize(12);
148 handSplitter.setOneTouchExpandable(true);
149 handSplitter.setAutoscrolls(true);
150 handSplitter.setOpaque(false);
151 handSplitter.setBorder(null);
152 initComponents();
153 mainPanel.add(handSplitter, BorderLayout.CENTER);
154 JPanel namePanel = new JPanel();
155 namePanel.setLayout(new BoxLayout(namePanel, BoxLayout.Y_AXIS));
156
157
158 nickNamePanel = new JPanel();
159 nickNamePanel.setLayout(new BoxLayout(nickNamePanel, BoxLayout.X_AXIS));
160 JLabel nickLabel = new JLabel(UIHelper.getIcon("nickname.gif"));
161 nickLabel.setPreferredSize(new Dimension(18, 18));
162 nickNamePanel.add(nickLabel);
163 namePanel.add(nickNamePanel);
164
165
166 realNamePanel = new JPanel();
167 realNamePanel.setLayout(new BoxLayout(realNamePanel, BoxLayout.X_AXIS));
168
169 realNamePanel.setVisible(false);
170 JLabel realLabel = new JLabel(UIHelper.getIcon("id.gif"));
171 realLabel.setPreferredSize(new Dimension(18, 18));
172 realNamePanel.add(realLabel);
173 namePanel.add(realNamePanel);
174
175
176 morePanel.add(avatarButton, BorderLayout.CENTER);
177 morePanel.add(namePanel, BorderLayout.NORTH);
178
179
180 togglePanel = new JPanel();
181 togglePanel.setLayout(new BoxLayout(togglePanel, BoxLayout.X_AXIS));
182 morePanel.add(togglePanel, BorderLayout.SOUTH);
183
184 abilitiesPanel = new JPanel();
185 abilitiesPanel.setLayout(new BoxLayout(abilitiesPanel, BoxLayout.Y_AXIS));
186 morePanel.add(abilitiesPanel, BorderLayout.SOUTH);
187 }
188
189 /***
190 * Init components of this player.
191 */
192 protected abstract void initComponents();
193
194 /***
195 * Update the opponent side depending on the "enable reverse" options.
196 */
197 public abstract void updateReversed();
198
199 /***
200 * Remove, and then fill the phases of this player
201 *
202 * @param phases
203 * the phases to add.
204 */
205 public void reset(MPhase[] phases) {
206 this.phases.removeAll();
207 for (MPhase phase : phases) {
208 this.phases.add(phase);
209 }
210 this.phases.doLayout();
211 }
212
213 @Override
214 public boolean isCard() {
215 return false;
216 }
217
218 @Override
219 public final boolean isAbility() {
220 return false;
221 }
222
223 @Override
224 public final boolean isSpell() {
225 return false;
226 }
227
228 /***
229 * tell if this player is you
230 *
231 * @return true if this player is you
232 */
233 public abstract boolean isYou();
234
235 /***
236 * tell if this player is the current one
237 *
238 * @return true if this player is the current one
239 */
240 public boolean isCurrentPlayer() {
241 return StackManager.idCurrentPlayer == idPlayer;
242 }
243
244 /***
245 * Return the opponent player
246 *
247 * @return the opponent player
248 */
249 public Player getOpponent() {
250 return StackManager.PLAYERS[1 - idPlayer];
251 }
252
253 @Override
254 protected final void highLight(Color highLightColor) {
255 setBackground(highLightColor);
256 if (CardFactory.ACTIVATED_COLOR.equals(highLightColor)) {
257
258 final List<Ability> abilities = WaitActivatedChoice.getInstance()
259 .abilitiesOf(playerCard);
260 if (abilities.size() > 0) {
261 abilitiesPanel.add(new JLabel(LanguageManager.getString("abilities")
262 + " : "));
263 }
264 for (int i = abilities.size(); i-- > 0;) {
265 final JButton button = new JButton(abilities.get(i).toString());
266 button.setActionCommand("" + i);
267 button.addActionListener(this);
268 abilitiesPanel.add(button);
269 }
270 }
271 avatarButton.setBackground(highLightColor);
272 MagicUIComponents.playerTabbedPanel.setSelectedComponent(morePanel);
273 MagicUIComponents.playerTabbedPanel.setBackgroundAt(
274 MagicUIComponents.playerTabbedPanel.indexOfComponent(morePanel),
275 highLightColor);
276 super.highLight(highLightColor);
277 }
278
279 @Override
280 public void disHighLight() {
281 isHighLighted = false;
282 setBackground(new Color(204, 204, 204));
283 avatarButton.setBackground(null);
284 abilitiesPanel.removeAll();
285 try {
286 MagicUIComponents.playerTabbedPanel
287 .setBackgroundAt(MagicUIComponents.playerTabbedPanel
288 .indexOfComponent(morePanel), null);
289 } catch (Exception e) {
290 Log.error("Error in tabbedpanel : " + e);
291 }
292 super.disHighLight();
293 }
294
295 /***
296 * Set to the register of this card a value to a specified index. The given
297 * operation is uesed to apply operation on old and the given value. To set
298 * the given value as the new one, use the "set" operation.
299 *
300 * @param index
301 * is the index of register to modify
302 * @param operation
303 * the operation to use
304 * @param rightValue
305 * is the value to use as right operande for the operation
306 */
307 public void setValue(int index, Operation operation, int rightValue) {
308 registers[index] = operation.process(registers[index], rightValue);
309
310 if (index < 6) {
311
312 mana.manaButtons[index].repaint();
313 } else if (index == IdTokens.LIFE) {
314
315 updateLife();
316 } else if (index == IdTokens.POISON) {
317
318 updatePoison();
319 }
320 }
321
322 @Override
323 public void update(Graphics g) {
324 super.paintComponent(g);
325
326 if (isHighLighted) {
327 g.setColor(highLightColor);
328 g.draw3DRect(0, 0, getWidth() - 1, getHeight() - 1, true);
329 g.draw3DRect(1, 1, getWidth() - 3, getHeight() - 3, true);
330 }
331 g.dispose();
332 }
333
334 /***
335 * update the life counter label
336 */
337 private void updateLife() {
338 lifeLabel.setText(String.valueOf(registers[IdTokens.LIFE]));
339 }
340
341 /***
342 * update the life counter label
343 */
344 private void updatePoison() {
345 poisonLabel.setText(String.valueOf(registers[IdTokens.POISON]));
346 }
347
348 /***
349 * Initialize the labels referencing to the registers of the MPlayer
350 * components.
351 */
352 public static void init() {
353 for (Player player : StackManager.PLAYERS) {
354 player.updateLife();
355 player.updatePoison();
356 player.mana.setVisible(PayMana.useMana);
357 }
358 MagicUIComponents.chatHistoryText.setContact(StackManager.PLAYERS[0]
359 .getNickName(), StackManager.PLAYERS[1].getName());
360 MagicUIComponents.logListing.setContact(StackManager.PLAYERS[0]
361 .getNickName(), StackManager.PLAYERS[1].getNickName());
362 }
363
364 /***
365 * return the player's name
366 *
367 * @return the player's name
368 */
369 @Override
370 public String toString() {
371 return getNickName();
372 }
373
374 /***
375 * Return the player's name.
376 *
377 * @return the player's name
378 */
379 public abstract String getNickName();
380
381 /***
382 * Indicates if this player decline to response to the current effect.
383 *
384 * @return true if this player decline to response to the current effect.
385 * @see MPhase#declineResponseMe()
386 * @since 0.30
387 * @since 0.31 an option "skip all even opponent's spell" is suported
388 * @since 0.80 "medium decline" is suported
389 */
390 public boolean declineResponseMe() {
391 if (MPhase.phases[StackManager.idCurrentPlayer][EventManager.phaseIndex]
392 .declineResponseMe()) {
393 return false;
394 }
395 for (int i = EventManager.phaseIndex + 1; i < EventManager.turnStructure.length; i++) {
396 if (MPhase.phases[StackManager.idCurrentPlayer][i].declineResponseMe()) {
397 return true;
398 }
399 }
400 for (int i = 0; i < EventManager.turnStructure.length; i++) {
401 if (MPhase.phases[1 - StackManager.idCurrentPlayer][i]
402 .declineResponseMe()) {
403 return true;
404 }
405 }
406 return false;
407 }
408
409 /***
410 * Indicates if this player decline to play any ability with an empty stack.
411 *
412 * @return if this player decline to play any ability with an empty stack.
413 * @see MPhase#breakpoint()
414 * @since 0.30
415 * @since 0.31 an option "skip all even opponent's spell" is suported
416 * @since 0.80 "medium decline" is suported
417 */
418 public boolean declinePlay() {
419 if (MPhase.phases[StackManager.idCurrentPlayer][EventManager.phaseIndex]
420 .breakpoint()) {
421 return false;
422 }
423 for (int i = EventManager.phaseIndex + 1; i < EventManager.turnStructure.length; i++) {
424 if (MPhase.phases[StackManager.idCurrentPlayer][i].declineResponseMe()) {
425 return true;
426 }
427 }
428 for (int i = 0; i < EventManager.turnStructure.length; i++) {
429 if (MPhase.phases[1 - StackManager.idCurrentPlayer][i]
430 .declineResponseMe()) {
431 return true;
432 }
433 }
434 return false;
435 }
436
437 /***
438 * Indicates if this player decline to response to the current effect owned by
439 * opponent.
440 *
441 * @return true if this player decline to response to the current effect owned
442 * by opponent.
443 * @see MPhase#declineResponseOpponent()
444 * @since 0.30
445 * @since 0.31 an option "skip all even opponent's spell" is suported
446 * @since 0.80 "medium decline" is suported
447 */
448 public boolean declineResponseOpponent() {
449 if (MPhase.phases[StackManager.idCurrentPlayer][EventManager.phaseIndex]
450 .declineResponseOpponent()) {
451 return false;
452 }
453 for (int i = EventManager.phaseIndex + 1; i < EventManager.turnStructure.length; i++) {
454 if (MPhase.phases[StackManager.idCurrentPlayer][i]
455 .declineResponseOpponent()) {
456 return true;
457 }
458 }
459 for (int i = 0; i < EventManager.turnStructure.length; i++) {
460 if (MPhase.phases[1 - StackManager.idCurrentPlayer][i]
461 .declineResponseOpponent()) {
462 return true;
463 }
464 }
465 return false;
466 }
467
468 /***
469 * Set this player as active one
470 */
471 public void setActivePlayer() {
472 StackManager.idActivePlayer = idPlayer;
473 setHandedPlayer();
474 EventManager.updatePhasesGUI();
475 }
476
477 /***
478 * Set this player as handed one
479 */
480 public void setHandedPlayer() {
481 MagicUIComponents.targetTimer.resetCounter();
482 StackManager.idHandedPlayer = idPlayer;
483 infoPanel.setBackground(Color.ORANGE);
484 }
485
486 /***
487 * Remove to all players the possibility to do something
488 */
489 public static void unsetHandedPlayer() {
490 StackManager.oldIdHandedPlayer = StackManager.idHandedPlayer;
491 StackManager.idHandedPlayer = -1;
492 for (Player player : StackManager.PLAYERS) {
493 player.infoPanel.setBackground(null);
494 }
495 MagicUIComponents.skipButton.setEnabled(false);
496 MagicUIComponents.skipMenu.setEnabled(false);
497 MagicUIComponents.waitingLabel.setText(HANDED_NOBODY);
498 MagicUIComponents.waitingLabel.setForeground(Color.ORANGE);
499 }
500
501 /***
502 * Wait for the active player, then the non-active player to make choice of
503 * the order of triggered abilities to be put from the buffer to the stack
504 *
505 * @param resolveOnEmpty
506 * if true, the stack resolution would be broken if no triggered
507 * abilities have been played instead of playing the
508 * WaitActivatedChoice action.
509 * @return true if NO high priority triggered ability has been played from the
510 * TBZ. So the stack can be resolved.
511 */
512 public boolean waitTriggeredBufferChoice(boolean resolveOnEmpty) {
513 StackManager.actionManager.currentAction = WaitTriggeredBufferChoice
514 .getInstance();
515
516
517 StackManager.processRefreshRequests();
518 if (waitTriggeredBufferChoiceRec()) {
519
520 if (resolveOnEmpty) {
521 StackManager.actionManager.waitingOnMiddle = false;
522 WaitTriggeredBufferChoice.getInstance().finished();
523 }
524 return true;
525 }
526 return false;
527 }
528
529 /***
530 * Return true if there was one or several processed hidden triggered
531 * abilities
532 *
533 * @return true if there was one or several processed hidden triggered
534 * abilities
535 */
536 public boolean processHiddenTriggered() {
537 return zoneManager.triggeredBuffer.resolveHiddenHighLevel(idPlayer)
538 || getOpponent().zoneManager.triggeredBuffer
539 .resolveHiddenHighLevel(1 - idPlayer)
540 || zoneManager.triggeredBuffer.resolveHiddenNormalLevel(idPlayer)
541 || getOpponent().zoneManager.triggeredBuffer
542 .resolveHiddenNormalLevel(1 - idPlayer)
543 || zoneManager.triggeredBuffer.resolveHiddenLowestLevel(idPlayer)
544 || getOpponent().zoneManager.triggeredBuffer
545 .resolveHiddenLowestLevel(1 - idPlayer);
546 }
547
548 /***
549 * List, purge, recheck, add found triggered abilities into the stack. If only
550 * one ability has been found, it is played automatically. If several
551 * abilities are found for YOU, and if the 'auto-stack' option is enabled, the
552 * abilities are all added sequentially added to the stack.
553 *
554 * @return true if NO triggered ability has been found in the TBZ.
555 */
556 private boolean waitTriggeredBufferChoiceRec() {
557 if (processHiddenTriggered()) {
558
559 return false;
560 }
561
562
563
564
565
566
567 if (zoneManager.triggeredBuffer.getCardCount() > 0) {
568
569 TriggeredCard triggered = zoneManager.triggeredBuffer.chooseAbility();
570 if (triggered != null) {
571
572
573
574 StackManager.idActivePlayer = idPlayer;
575 StackManager.actionManager.succeedClickOn(triggered);
576 } else if (zoneManager.triggeredBuffer.getCardCount() > 1
577 && MCommonVars.autoStack && isYou()) {
578
579 StackManager.idActivePlayer = idPlayer;
580 System.out.println("\t>>>> outAuto :" + counter++);
581 TriggeredCard triggered0 = (TriggeredCard) StackManager.PLAYERS[0].zoneManager.triggeredBuffer
582 .getComponent(0);
583 Synchronizer.setAsHanded();
584 Log.debug("clickedOn triggeredcard " + triggered0
585 + "- AUTO STACK OPTION");
586 triggered0.sendClickToOpponent();
587 StackManager.actionManager.succeedClickOn(triggered0);
588 } else if (zoneManager.triggeredBuffer.getCardCount() == 0) {
589
590
591
592
593 return true;
594 } else {
595
596
597
598
599 System.out.println("\t>>>> outPrompt :" + counter++ + "(idPlayer="
600 + idPlayer + ", triggered size="
601 + zoneManager.triggeredBuffer.getCardCount() + ")");
602 setActivePlayer();
603 zoneManager.triggeredBuffer.highlightStackable();
604 }
605
606
607
608
609
610 return false;
611 }
612
613
614 if (idPlayer == StackManager.idActivePlayer) {
615
616 return getOpponent().waitTriggeredBufferChoiceRec();
617 }
618 return true;
619 }
620
621 static int counter = 0;
622
623 @Override
624 public void mouseClicked(MouseEvent e) {
625
626 StackManager.noReplayToken.take();
627 try {
628 if (ConnectionManager.isConnected()
629 && e.getButton() == MouseEvent.BUTTON1
630 && StackManager.idHandedPlayer == 0
631 && StackManager.actionManager.clickOn(this)) {
632 Log.debug("clickOn(Mouse):player");
633 sendClickToOpponent();
634 StackManager.actionManager.succeedClickOn(this);
635 }
636 } catch (Throwable t) {
637 t.printStackTrace();
638 } finally {
639 StackManager.noReplayToken.release();
640 }
641 }
642
643 /***
644 * This method is invoked when opponent has clicked on this object. this call
645 * should be done from the net.sf.magicproject.network listener
646 *
647 * @param input
648 * input stream of our net.sf.magicproject.network connection
649 * @throws IOException
650 * if error occurred when reading the message
651 */
652 public static void clickOn(InputStream input) throws IOException {
653
654 Log.debug("clickOn(VirtualInput):player");
655 StackManager.actionManager
656 .succeedClickOn(StackManager.PLAYERS[input.read()]);
657 }
658
659 @Override
660 public void sendClickToOpponent() {
661
662 ConnectionManager.sendToOpponent(IdMessages.MSG_CLICK_PLAYER, 1 - idPlayer);
663 }
664
665 @Override
666 public int getValue(int index) {
667 if (index == IdTokens.MANA_POOL) {
668 if (StackManager.actionManager.idHandler == ActionManager.HANDLER_INITIALIZATION
669 && StackManager.getSpellController() == this) {
670 return mana.allManas()
671 - StackManager.getTotalManaCost(StackManager.tokenCard);
672 }
673 return mana.allManas();
674 }
675 if (index == IdTokens.ID) {
676 return getId();
677 }
678 if (index < IdTokens.FIRST_FREE_CARD_INDEX) {
679 return registers[index];
680 }
681
682 return registers[index];
683 }
684
685 @Override
686 public int getTimestamp() {
687 return 0;
688 }
689
690 @Override
691 public void mouseEntered(MouseEvent e) {
692 if (StackManager.currentAbility != null
693 && StackManager.actionManager.currentAction != null
694 && StackManager.actionManager.currentAction instanceof ChoosenTarget) {
695
696 if (((ChoosenTarget) StackManager.actionManager.currentAction)
697 .isValidTarget(this)) {
698 setToolTipText("<html>" + getNickName()
699 + TargetableFactory.tooltipValidTarget);
700 } else {
701 setToolTipText("<html>" + getNickName()
702 + TargetableFactory.tooltipInvalidTarget);
703 }
704 } else {
705 setToolTipText(getNickName());
706 }
707 }
708
709 @Override
710 public void removeModifier(RegisterModifier modifier, int index) {
711 throw new InternalError("not yet implemented");
712 }
713
714 @Override
715 public void removeModifier(RegisterIndirection indirection, int index) {
716 throw new InternalError("not yet implemented");
717 }
718
719 @Override
720 public Targetable getLastKnownTargetable(int timeStamp) {
721 return this;
722 }
723
724 /***
725 * Increment the reference counter for the current timestamp of this card.
726 */
727 @Override
728 public void addTimestampReference() {
729
730 }
731
732 @Override
733 public void decrementTimestampReference(int timestamp) {
734
735 }
736
737 /***
738 * Set the icon (32x32) of this player
739 *
740 * @param name
741 * player's nickname.
742 * @param imageIcon
743 * the small avatar.
744 */
745 protected void init(String name, Image imageIcon) {
746 this.imageIcon = imageIcon;
747 repaint();
748 }
749
750 @Override
751 public void paint(Graphics g) {
752
753 super.paint(g);
754 final Graphics2D g2D = (Graphics2D) g;
755 if (!isYou() && Configuration.getBoolean("reverseSide", false)) {
756 g2D.translate(getWidth() - 1, getHeight() - 1);
757 g2D.rotate(Math.PI);
758 }
759 g2D.drawImage(imageIcon, 3, 4, null);
760 if (isHighLighted) {
761 g.setColor(highLightColor);
762 g.draw3DRect(0, 0, getWidth() - 1, getHeight() - 1, true);
763 g.draw3DRect(1, 1, getWidth() - 3, getHeight() - 3, true);
764 }
765
766
767 final String id = TargetHelper.getInstance().getMyId(this);
768 if (id != null) {
769 if (id == TargetHelper.STR_CONTEXT1) {
770
771 g2D.setColor(Color.BLUE);
772 g2D
773 .setFont(g2D.getFont()
774 .deriveFont(Font.BOLD, PLAYER_SIZE_HEIGHT - 4));
775 g2D.drawString(String.valueOf(id), 25, PLAYER_SIZE_HEIGHT - 2);
776 } else if (id == TargetHelper.STR_CONTEXT2) {
777
778 g2D.setColor(Color.BLUE);
779 g2D
780 .setFont(g2D.getFont()
781 .deriveFont(Font.BOLD, PLAYER_SIZE_HEIGHT - 4));
782 g2D.drawString(String.valueOf(id), 25, PLAYER_SIZE_HEIGHT - 2);
783 } else if (id != TargetHelper.STR_SOURCE) {
784
785
786
787
788 g2D.drawImage(TargetHelper.getInstance().getTargetPictureSml(), 30, 5,
789 null);
790 }
791 }
792
793 g2D.dispose();
794 }
795
796 @Override
797 public int getId() {
798 return idPlayer;
799 }
800
801 /***
802 * where all triggered abilities would go before to go to the stack
803 */
804 public ZoneManager zoneManager;
805
806 /***
807 * id of the player
808 */
809 public int idPlayer;
810
811 /***
812 * is the manas of this player
813 */
814 public ManaPool mana;
815
816 /***
817 * This card is used to represent this player as a card/
818 */
819 public PlayerCard playerCard;
820
821 /***
822 * The button containig the avatar picture
823 */
824 protected AvatarButton avatarButton;
825
826 /***
827 * Available string settings of any player.
828 */
829 protected static final String[] SETTINGS = { "email", "yahoo", "msn", "icq" };
830
831 /***
832 * Panel containing some information about player
833 */
834 protected JPanel morePanel;
835
836 /***
837 * The label representing player's lives.
838 */
839 protected JLabel lifeLabel;
840
841 /***
842 * The label representing player's poison.
843 */
844 protected JLabel poisonLabel;
845
846 /***
847 * The panel containing the hand and the play
848 */
849 public JPanel mainPanel;
850
851 /***
852 * The main panel containing player's lives+poison+mana+buttons.
853 */
854 protected JPanel infoPanel;
855
856 /***
857 * The panel representing player's phases.
858 */
859 protected JPanel phases;
860
861 /***
862 * Abilities panel (not yet implemented)
863 */
864 protected JPanel abilitiesPanel;
865
866 /***
867 * The splitter of game/hand zones.
868 */
869 public JSplitPane handSplitter;
870
871 /***
872 * The panel containing all icons representing contact info.
873 */
874 protected JPanel togglePanel;
875
876 /***
877 * Nickname panel : button and label.
878 */
879 protected JPanel nickNamePanel;
880
881 /***
882 * real name panel : button and label.
883 */
884 protected JPanel realNamePanel;
885
886 private Image imageIcon;
887
888 /***
889 * The deck of this player.
890 */
891 private Deck deck;
892
893 private static final String HANDED_NOBODY = LanguageManager
894 .getString("handed-nobody");
895
896 /***
897 * Set the deck of this player.
898 *
899 * @param deck
900 * the deck of this player.
901 */
902 public void setDeck(Deck deck) {
903 this.deck = deck;
904 }
905
906 /***
907 * Return the current deck of player.
908 *
909 * @return the current deck of player.
910 */
911 public Deck getDeck() {
912 return deck;
913 }
914 }