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