Merge pull request 'master' (#26) from External/mage:master into master
All checks were successful
/ build_release (push) Successful in 14m41s

Reviewed-on: #26
This commit is contained in:
Failure 2025-05-19 22:03:43 -07:00
commit 9a2382cd2c
788 changed files with 29882 additions and 3734 deletions

View file

@ -83,7 +83,7 @@ public enum CombatManager {
UUID defenderId = group.getDefenderId();
if (defenderId != null) {
// if attacker was blocked then use another arrow color
Color attackColor = group.getBlockers().isEmpty() ? ARROW_COLOR_ATTACKER : ARROW_COLOR_BLOCKED_ATTACKER;
Color attackColor = group.isBlocked() ? ARROW_COLOR_BLOCKED_ATTACKER : ARROW_COLOR_ATTACKER;
parentPoint = getParentPoint(attackerCard);
PlayAreaPanel p = MageFrame.getGamePlayers(gameId).get(defenderId);
if (p != null) {

View file

@ -326,6 +326,13 @@ public class TestCardRenderDialog extends MageDialog {
possibleTargets.add(playerYou.getId());
}
// chosen target
Set<UUID> chosenTargets = null;
if (false) { // TODO: add GUI's checkbox for checkPlayerAsChosen
chosenTargets = new LinkedHashSet<>();
chosenTargets.add(playerYou.getId());
}
// player's panel
if (this.player == null) {
// create new panel
@ -345,7 +352,7 @@ public class TestCardRenderDialog extends MageDialog {
.findFirst()
.orElse(null);
this.player.init(this.game.getId(), playerYou.getId(), isMe, this.bigCard, 0);
this.player.update(gameView, currentPlayerView, possibleTargets);
this.player.update(gameView, currentPlayerView, possibleTargets, chosenTargets);
this.player.sizePlayerPanel(smallMode);
// update CARDS

View file

@ -218,6 +218,22 @@ public final class GamePanel extends javax.swing.JPanel {
});
}
public List<UUID> getPossibleTargets() {
if (options != null && options.containsKey("possibleTargets")) {
return (List<UUID>) options.get("possibleTargets");
} else {
return Collections.emptyList();
}
}
public Set<UUID> getChosenTargets() {
if (options != null && options.containsKey("chosenTargets")) {
return new HashSet<>((List<UUID>) options.get("chosenTargets"));
} else {
return Collections.emptySet();
}
}
public CardView findCard(UUID id) {
return this.allCardsIndex.getOrDefault(id, null);
}
@ -658,7 +674,7 @@ public final class GamePanel extends javax.swing.JPanel {
// see test render dialog for refresh commands order
playPanel.getPlayerPanel().fullRefresh(GUISizeHelper.playerPanelGuiScale);
playPanel.init(player, bigCard, gameId, player.getPriorityTimeLeftSecs());
playPanel.update(lastGameData.game, player, lastGameData.targets);
playPanel.update(lastGameData.game, player, lastGameData.targets, lastGameData.getChosenTargets());
playPanel.getPlayerPanel().sizePlayerPanel(false);
}
});
@ -1186,7 +1202,7 @@ public final class GamePanel extends javax.swing.JPanel {
}
}
}
players.get(player.getPlayerId()).update(lastGameData.game, player, lastGameData.targets);
players.get(player.getPlayerId()).update(lastGameData.game, player, lastGameData.targets, lastGameData.getChosenTargets());
if (player.getPlayerId().equals(playerId)) {
skipButtons.updateFromPlayer(player);
}
@ -1802,12 +1818,7 @@ public final class GamePanel extends javax.swing.JPanel {
needZone = (Zone) lastGameData.options.get("targetZone");
}
List<UUID> needChosen;
if (lastGameData.options != null && lastGameData.options.containsKey("chosenTargets")) {
needChosen = (List<UUID>) lastGameData.options.get("chosenTargets");
} else {
needChosen = new ArrayList<>();
}
Set<UUID> needChosen = lastGameData.getChosenTargets();
Set<UUID> needSelectable;
if (lastGameData.targets != null) {
@ -2037,7 +2048,7 @@ public final class GamePanel extends javax.swing.JPanel {
private void prepareSelectableWindows(
Collection<CardInfoWindowDialog> windows,
Set<UUID> needSelectable,
List<UUID> needChosen,
Set<UUID> needChosen,
PlayableObjectsList needPlayable
) {
// lookAt or reveals windows clean up on next priority, so users can see dialogs, but xmage can't restore it

View file

@ -57,7 +57,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
// data init
init(player, bigCard, gameId, priorityTime);
update(null, player, null);
update(null, player, null, null);
playerPanel.sizePlayerPanel(isSmallMode());
// init popup menu (must run after data init)
@ -510,8 +510,8 @@ public class PlayAreaPanel extends javax.swing.JPanel {
this.isMe = player.getControlled();
}
public final void update(GameView game, PlayerView player, Set<UUID> possibleTargets) {
this.playerPanel.update(game, player, possibleTargets);
public final void update(GameView game, PlayerView player, Set<UUID> possibleTargets, Set<UUID> chosenTargets) {
this.playerPanel.update(game, player, possibleTargets, chosenTargets);
this.battlefieldPanel.update(player.getBattlefield());
if (this.allowViewHandCardsMenuItem != null) {
this.allowViewHandCardsMenuItem.setSelected(player.getUserData().isAllowRequestHandToAll());

View file

@ -247,7 +247,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
.orElse(0);
}
public void update(GameView game, PlayerView player, Set<UUID> possibleTargets) {
public void update(GameView game, PlayerView player, Set<UUID> possibleTargets, Set<UUID> chosenTargets) {
this.player = player;
int pastLife = player.getLife();
if (playerLives != null) {
@ -427,6 +427,12 @@ public class PlayerPanelExt extends javax.swing.JPanel {
this.btnPlayer.setBorder(YELLOW_BORDER);
}
// selected targeting (draw as priority)
if (chosenTargets != null && chosenTargets.contains(this.playerId)) {
this.avatar.setBorder(GREEN_BORDER); // TODO: use diff green color for chosen targeting and current priority?
this.btnPlayer.setBorder(GREEN_BORDER);
}
update(player.getManaPool());
}

View file

@ -10,6 +10,7 @@ import mage.client.draft.DraftPanel;
import mage.client.game.GamePanel;
import mage.client.plugins.impl.Plugins;
import mage.client.util.DeckUtil;
import mage.client.util.GUISizeHelper;
import mage.client.util.IgnoreList;
import mage.client.util.audio.AudioManager;
import mage.client.util.object.SaveObjectUtil;
@ -22,9 +23,12 @@ import mage.util.DebugUtil;
import mage.view.*;
import mage.view.ChatMessage.MessageType;
import org.apache.log4j.Logger;
import org.mage.card.arcane.ManaSymbols;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.*;
/**
@ -203,11 +207,7 @@ public class CallbackClientImpl implements CallbackClient {
case SERVER_MESSAGE: {
if (callback.getData() != null) {
ChatMessage message = (ChatMessage) callback.getData();
if (message.getColor() == ChatMessage.MessageColor.RED) {
JOptionPane.showMessageDialog(null, message.getMessage(), "Server message", JOptionPane.WARNING_MESSAGE);
} else {
JOptionPane.showMessageDialog(null, message.getMessage(), "Server message", JOptionPane.INFORMATION_MESSAGE);
}
showMessageDialog(null, message.getMessage(), "Server message");
}
break;
}
@ -401,7 +401,7 @@ public class CallbackClientImpl implements CallbackClient {
case SHOW_USERMESSAGE: {
List<String> messageData = (List<String>) callback.getData();
if (messageData.size() == 2) {
JOptionPane.showMessageDialog(null, messageData.get(1), messageData.get(0), JOptionPane.WARNING_MESSAGE);
showMessageDialog(null, messageData.get(1), messageData.get(0));
}
break;
}
@ -420,8 +420,7 @@ public class CallbackClientImpl implements CallbackClient {
GameClientMessage message = (GameClientMessage) callback.getData();
GamePanel panel = MageFrame.getGame(callback.getObjectId());
if (panel != null) {
JOptionPane.showMessageDialog(panel, message.getMessage(), "Game message",
JOptionPane.INFORMATION_MESSAGE);
showMessageDialog(panel, message.getMessage(), "Game message");
}
break;
}
@ -510,6 +509,18 @@ public class CallbackClientImpl implements CallbackClient {
});
}
/**
* Show modal message box, so try to use it only for critical errors or global message. As less as possible.
*/
private void showMessageDialog(Component parentComponent, String message, String title) {
// convert to html
// message - supported
// title - not supported
message = ManaSymbols.replaceSymbolsWithHTML(message, ManaSymbols.Type.DIALOG);
message = GUISizeHelper.textToHtmlWithSize(message, GUISizeHelper.dialogFont);
JOptionPane.showMessageDialog(parentComponent, message, title, JOptionPane.INFORMATION_MESSAGE);
}
private ActionData appendJsonEvent(String name, UUID gameId, Object value) {
Session session = SessionHandler.getSession();
if (session.isJsonLogActive()) {

View file

@ -6,6 +6,7 @@ import mage.client.util.gui.GuiDisplayUtil;
import org.mage.card.arcane.CardRenderer;
import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import java.awt.*;
import java.lang.reflect.Field;
import java.util.Locale;
@ -108,7 +109,7 @@ public final class GUISizeHelper {
// app - frame/window title
// nimbus's LaF limited to static title size, so font can't be too big (related code in SynthInternalFrameTitlePane, BasicInternalFrameTitlePane)
UIManager.put("InternalFrame.titleFont", dialogFont.deriveFont(Font.BOLD, Math.min(17, 0.8f * dialogFont.getSize())));
UIManager.put("InternalFrame.titleFont", new FontUIResource(dialogFont.deriveFont(Font.BOLD, Math.min(17, 0.8f * dialogFont.getSize()))));
// app - tables
tableFont = new java.awt.Font("Arial", 0, dialogFontSize);
@ -150,7 +151,11 @@ public final class GUISizeHelper {
cardTooltipLargeImageHeight = 30 * tooltipFontSize;
cardTooltipLargeTextWidth = Math.max(150, 20 * tooltipFontSize - 50);
cardTooltipLargeTextHeight = Math.max(100, 12 * tooltipFontSize - 20);
UIManager.put("ToolTip.font", cardTooltipFont);
UIManager.put("ToolTip.font", new FontUIResource(cardTooltipFont));
// app - information boxes (only title, text controls by content)
// TODO: doesn't work
//UIManager.put("OptionPane.titleFont", new FontUIResource(dialogFont.deriveFont(Font.BOLD, Math.min(17, 1.3f * dialogFont.getSize()))));
// game - player panel
playerPanelGuiScale = (float) (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GUI_PLAYER_PANEL_SIZE, 14) / 14.0);

View file

@ -474,7 +474,7 @@ public final class GuiDisplayUtil {
public static void refreshThemeSettings() {
// apply Nimbus's look and fill
// possible settings:
// https://docs.oracle.com/en%2Fjava%2Fjavase%2F17%2Fdocs%2Fapi%2F%2F/java.desktop/javax/swing/plaf/nimbus/doc-files/properties.html
// https://docs.oracle.com/en/java/javase/23/docs/api/java.desktop/javax/swing/plaf/nimbus/doc-files/properties.html
// enable nimbus
try {