");
Enumeration allP = game.getPlayers();
boolean foundPlayer = false;
@@ -5641,7 +5649,6 @@ public String getHexTooltip(MouseEvent e) {
}
final Collection shdList = game.getBoard().getSpecialHexDisplay(mcoords);
- final GamePhase currPhase = game.getPhase();
int round = game.getRoundCount();
if (shdList != null) {
boolean isHexAutoHit = localPlayer.getArtyAutoHitHexes().contains(mcoords);
@@ -5653,7 +5660,7 @@ public String getHexTooltip(MouseEvent e) {
// The exception is auto hits. There will be an icon for auto
// hits, so we need to draw a tooltip
if (!shd.isObscured(localPlayer)
- && (shd.drawNow(currPhase, round, localPlayer)
+ && (shd.drawNow(game.getPhase(), round, localPlayer)
|| (isHexAutoHit && isTypeAutoHit))) {
if (shd.getType() == SpecialHexDisplay.Type.PLAYER_NOTE) {
if (localPlayer.equals(shd.getOwner())) {
diff --git a/megamek/src/megamek/client/ui/swing/boardview/EntitySprite.java b/megamek/src/megamek/client/ui/swing/boardview/EntitySprite.java
index c303fd95c20..7ca95d738dc 100644
--- a/megamek/src/megamek/client/ui/swing/boardview/EntitySprite.java
+++ b/megamek/src/megamek/client/ui/swing/boardview/EntitySprite.java
@@ -18,25 +18,17 @@
*/
package megamek.client.ui.swing.boardview;
-import java.awt.AlphaComposite;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsEnvironment;
-import java.awt.Image;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.awt.Transparency;
-import java.util.*;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.util.EntityWreckHelper;
import megamek.common.*;
import megamek.common.annotations.Nullable;
-import megamek.common.enums.GamePhase;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Set;
/**
* Sprite for an entity. Changes whenever the entity changes. Consists of an
@@ -225,7 +217,7 @@ private void updateLabel() {
}
int face = (entity.isCommander() && !onlyDetectedBySensors()) ? Font.ITALIC : Font.PLAIN;
- labelFont = new Font("SansSerif", face, (int) (10 * Math.max(bv.scale, 0.9)));
+ labelFont = new Font(MMConstants.FONT_SANS_SERIF, face, (int) (10 * Math.max(bv.scale, 0.9)));
// Check the hexes in directions 2, 5, 1, 4 if they are free of entities
// and place the label in the direction of the first free hex
@@ -358,8 +350,8 @@ private void drawStatusStrings(Graphics2D g, ArrayList statusStrings) {
// When zoomed far out, status wouldn't be readable, therefore
// draw a big "!" (and the label is red)
- if (bv.scale < 0.55 && criticalStatus) {
- Font bigFont = new Font("SansSerif", Font.BOLD, (int) (42 * bv.scale));
+ if ((bv.scale < 0.55) && criticalStatus) {
+ Font bigFont = new Font(MMConstants.FONT_SANS_SERIF, Font.BOLD, (int) (42 * bv.scale));
g.setFont(bigFont);
Point pos = new Point(bv.hex_size.width / 2, bv.hex_size.height / 2);
bv.drawTextShadow(g, "!", pos, bigFont);
@@ -368,7 +360,7 @@ private void drawStatusStrings(Graphics2D g, ArrayList statusStrings) {
}
// Critical status text
- Font boldFont = new Font("SansSerif",Font.BOLD,(int) (12 * bv.scale));
+ Font boldFont = new Font(MMConstants.FONT_SANS_SERIF, Font.BOLD, (int) (12 * bv.scale));
g.setFont(boldFont);
int y = (int) (bv.hex_size.height * 0.6);
for (Status curStatus: statusStrings) {
@@ -704,7 +696,7 @@ public void prepare() {
&& !((Infantry) entity).isTakingCover())
&& !(isAero && ((IAero) entity).isSpheroid() && !board.inSpace())) {
// Indicate a stacked unit with the same facing that can still move
- if (shouldIndicateNotDone() && (bv.game.getPhase() == GamePhase.MOVEMENT)) {
+ if (shouldIndicateNotDone() && bv.game.getPhase().isMovement()) {
var tr = graph.getTransform();
// rotate the arrow slightly
graph.scale(1 / bv.scale, 1 / bv.scale);
@@ -717,7 +709,7 @@ public void prepare() {
graph.setTransform(tr);
}
- if (!entity.isDone() && (bv.game.getPhase() == GamePhase.MOVEMENT)) {
+ if (!entity.isDone() && bv.game.getPhase().isMovement()) {
graph.setColor(GUIPreferences.getInstance().getWarningColor());
graph.fill(bv.facingPolys[entity.getFacing()]);
graph.setColor(Color.WHITE);
diff --git a/megamek/src/megamek/client/ui/swing/boardview/FiringSolutionSprite.java b/megamek/src/megamek/client/ui/swing/boardview/FiringSolutionSprite.java
index 2826aae155d..00786b81c4d 100644
--- a/megamek/src/megamek/client/ui/swing/boardview/FiringSolutionSprite.java
+++ b/megamek/src/megamek/client/ui/swing/boardview/FiringSolutionSprite.java
@@ -97,18 +97,15 @@ public void prepare() {
graph.scale(bv.scale, bv.scale);
// get the right font
- String fontName = GUIPreferences.getInstance().getString(
- GUIPreferences.ADVANCED_MOVE_FONT_TYPE);
- int fontStyle = GUIPreferences.getInstance().getInt(
- GUIPreferences.ADVANCED_MOVE_FONT_STYLE);
+ String fontName = GUIPreferences.getInstance().getString(GUIPreferences.ADVANCED_MOVE_FONT_TYPE);
+ int fontStyle = GUIPreferences.getInstance().getInt(GUIPreferences.ADVANCED_MOVE_FONT_STYLE);
if (noHitPossible) {
// write big red X
graph.setFont(new Font(fontName, fontStyle, fontSizeLarge));
if (bv.scale > 0.7) {
// better translucent, the X is so big
- bv.drawOutlineText(graph, "X", centerHex,
- fontSizeLarge, xColor, true, Color.BLACK);
+ bv.drawOutlineText(graph, "X", centerHex, fontSizeLarge, xColor, true, Color.BLACK);
} else {
// better readable at small scale
bv.drawCenteredText(graph, "X", centerHex, xColor, false);
diff --git a/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java b/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java
index 5af2599ac84..78c10a63b21 100644
--- a/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java
+++ b/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java
@@ -3,7 +3,6 @@
import megamek.client.ui.swing.GUIPreferences;
import megamek.common.*;
import megamek.common.annotations.Nullable;
-import megamek.common.enums.GamePhase;
import megamek.common.enums.IlluminationLevel;
import megamek.common.event.GameListener;
import megamek.common.event.GameListenerAdapter;
@@ -97,8 +96,7 @@ boolean draw(Graphics boardGraph, Coords c, int drawX, int drawY, boolean saveBo
boolean highlight = gs.getBoolean(GUIPreferences.FOV_HIGHLIGHT);
boolean darken = gs.getBoolean(GUIPreferences.FOV_DARKEN);
- if ((darken || highlight)
- && (this.boardView1.game.getPhase() == GamePhase.MOVEMENT)) {
+ if ((darken || highlight) && this.boardView1.game.getPhase().isMovement()) {
final int pad = 0;
final int lw = 7;
diff --git a/megamek/src/megamek/client/ui/swing/boardview/GhostEntitySprite.java b/megamek/src/megamek/client/ui/swing/boardview/GhostEntitySprite.java
index 2b8ccda5fbf..514a4b47df5 100644
--- a/megamek/src/megamek/client/ui/swing/boardview/GhostEntitySprite.java
+++ b/megamek/src/megamek/client/ui/swing/boardview/GhostEntitySprite.java
@@ -1,13 +1,12 @@
package megamek.client.ui.swing.boardview;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Rectangle;
-import java.awt.image.ImageObserver;
-
+import megamek.MMConstants;
import megamek.common.Entity;
import megamek.common.util.ImageUtil;
+import java.awt.*;
+import java.awt.image.ImageObserver;
+
class GhostEntitySprite extends Sprite {
private Entity entity;
@@ -19,7 +18,7 @@ public GhostEntitySprite(BoardView boardView1, final Entity entity) {
this.entity = entity;
String shortName = entity.getShortName();
- Font font = new Font("SansSerif", Font.PLAIN, 10);
+ Font font = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 10);
modelRect = new Rectangle(47, 55, bv.getFontMetrics(font).stringWidth(
shortName) + 1, bv.getFontMetrics(font).getAscent());
Rectangle tempBounds = new Rectangle(bv.hex_size).union(modelRect);
diff --git a/megamek/src/megamek/client/ui/swing/boardview/IsometricSprite.java b/megamek/src/megamek/client/ui/swing/boardview/IsometricSprite.java
index dd5a52053a2..0815c5eab3a 100644
--- a/megamek/src/megamek/client/ui/swing/boardview/IsometricSprite.java
+++ b/megamek/src/megamek/client/ui/swing/boardview/IsometricSprite.java
@@ -1,5 +1,6 @@
package megamek.client.ui.swing.boardview;
+import megamek.MMConstants;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.util.EntityWreckHelper;
import megamek.common.Coords;
@@ -28,7 +29,7 @@ public IsometricSprite(BoardView boardView1, Entity entity, int secondaryPos, Im
this.radarBlipImage = radarBlipImage;
this.secondaryPos = secondaryPos;
String shortName = entity.getShortName();
- Font font = new Font("SansSerif", Font.PLAIN, 10);
+ Font font = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 10);
modelRect = new Rectangle(47, 55, bv.getFontMetrics(font).stringWidth(
shortName) + 1, bv.getFontMetrics(font).getAscent());
diff --git a/megamek/src/megamek/client/ui/swing/boardview/IsometricWreckSprite.java b/megamek/src/megamek/client/ui/swing/boardview/IsometricWreckSprite.java
index 33409fd0ca4..ecd75e59e73 100644
--- a/megamek/src/megamek/client/ui/swing/boardview/IsometricWreckSprite.java
+++ b/megamek/src/megamek/client/ui/swing/boardview/IsometricWreckSprite.java
@@ -1,28 +1,24 @@
/*
* MegaMek - Copyright (C) 2020 - The MegaMek Team
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
*/
-
package megamek.client.ui.swing.boardview;
-import java.awt.AlphaComposite;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.image.ImageObserver;
-
+import megamek.MMConstants;
import megamek.common.Entity;
+import java.awt.*;
+import java.awt.image.ImageObserver;
+
/**
* Sprite for an wreck. Consists of an image, drawn from the Tile Manager
* and an identification label.
@@ -39,27 +35,21 @@ public IsometricWreckSprite(BoardView boardView1, final Entity entity, int secon
String shortName = entity.getShortName();
- Font font = new Font("SansSerif", Font.PLAIN, 10);
+ Font font = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 10);
modelRect = new Rectangle(47, 55, bv.getFontMetrics(font).stringWidth(
shortName) + 1, bv.getFontMetrics(font).getAscent());
image = null;
}
- /**
- *
- */
@Override
- public void drawOnto(Graphics g, int x, int y, ImageObserver observer,
- boolean makeTranslucent) {
+ public void drawOnto(Graphics g, int x, int y, ImageObserver observer, boolean makeTranslucent) {
if (isReady()) {
Graphics2D g2 = (Graphics2D) g;
if (makeTranslucent) {
- g2.setComposite(AlphaComposite.getInstance(
- AlphaComposite.SRC_OVER, 0.35f));
+ g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.35f));
g2.drawImage(image, x, y, observer);
- g2.setComposite(AlphaComposite.getInstance(
- AlphaComposite.SRC_OVER, 1.0f));
+ g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
} else {
g.drawImage(image, x, y, observer);
}
@@ -71,5 +61,4 @@ public void drawOnto(Graphics g, int x, int y, ImageObserver observer,
public Entity getEntity() {
return entity;
}
-
}
diff --git a/megamek/src/megamek/client/ui/swing/boardview/KeyBindingsOverlay.java b/megamek/src/megamek/client/ui/swing/boardview/KeyBindingsOverlay.java
index fd1d40496d0..0917070cb88 100644
--- a/megamek/src/megamek/client/ui/swing/boardview/KeyBindingsOverlay.java
+++ b/megamek/src/megamek/client/ui/swing/boardview/KeyBindingsOverlay.java
@@ -13,20 +13,7 @@
*/
package megamek.client.ui.swing.boardview;
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.Rectangle;
-import java.awt.event.KeyEvent;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
+import megamek.MMConstants;
import megamek.client.ui.IDisplayable;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.ClientGUI;
@@ -44,6 +31,14 @@
import megamek.common.util.ImageUtil;
import org.apache.logging.log4j.LogManager;
+import java.awt.*;
+import java.awt.event.KeyEvent;
+import java.awt.font.TextAttribute;
+import java.text.AttributedString;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
/**
* An overlay for the Boardview that displays a selection of keybinds
* for the current game situation
@@ -51,7 +46,7 @@
* @author SJuliez
*/
public class KeyBindingsOverlay implements IDisplayable, IPreferenceChangeListener {
- private static final Font FONT = new Font("SansSerif", Font.PLAIN, 13);
+ private static final Font FONT = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 13);
private static final int DIST_TOP = 30;
private static final int DIST_SIDE = 30;
private static final int PADDING_X = 10;
@@ -65,17 +60,19 @@ public class KeyBindingsOverlay implements IDisplayable, IPreferenceChangeListen
private static final List BINDS_FIRE = Arrays.asList(
KeyCommandBind.NEXT_WEAPON,
KeyCommandBind.PREV_WEAPON,
+ KeyCommandBind.UNDO_LAST_STEP,
KeyCommandBind.NEXT_TARGET,
KeyCommandBind.NEXT_TARGET_VALID,
KeyCommandBind.NEXT_TARGET_NOALLIES,
KeyCommandBind.NEXT_TARGET_VALID_NO_ALLIES
- );
+ );
/** The keybinds to be shown during the movement phase */
private static final List BINDS_MOVE = Arrays.asList(
KeyCommandBind.TOGGLE_MOVEMODE,
+ KeyCommandBind.UNDO_LAST_STEP,
KeyCommandBind.TOGGLE_CONVERSIONMODE
- );
+ );
/** The keybinds to be shown in all phases during the local player's turn */
private static final List BINDS_MY_TURN = Arrays.asList(
@@ -84,19 +81,19 @@ public class KeyBindingsOverlay implements IDisplayable, IPreferenceChangeListen
KeyCommandBind.NEXT_UNIT,
KeyCommandBind.PREV_UNIT,
KeyCommandBind.CENTER_ON_SELECTED
- );
+ );
/** The keybinds to be shown in all phases during any player's turn */
private static final List BINDS_ANY_TURN = Arrays.asList(
KeyCommandBind.TOGGLE_CHAT,
KeyCommandBind.DRAW_LABELS,
KeyCommandBind.HEX_COORDS
- );
+ );
/** The keybinds to be shown in the Board Editor */
private static final List BINDS_BOARD_EDITOR = Arrays.asList(
KeyCommandBind.HEX_COORDS
- );
+ );
private static final List ADDTL_BINDS = Arrays.asList(
Messages.getString("KeyBindingsDisplay.fixedBinds").split("\n"));
@@ -106,6 +103,7 @@ public class KeyBindingsOverlay implements IDisplayable, IPreferenceChangeListen
ClientGUI clientGui;
+ private static final GUIPreferences GUIP = GUIPreferences.getInstance();
/** True when the overlay is displayed or fading in. */
private boolean visible;
@@ -127,11 +125,12 @@ public class KeyBindingsOverlay implements IDisplayable, IPreferenceChangeListen
* for the current game situation.
*/
public KeyBindingsOverlay(Game game, ClientGUI cg) {
- visible = GUIPreferences.getInstance().getBoolean(GUIPreferences.SHOW_KEYBINDS_OVERLAY);
+ visible = GUIP.getBoolean(GUIPreferences.SHOW_KEYBINDS_OVERLAY);
currentPhase = game.getPhase();
game.addGameListener(gameListener);
clientGui = cg;
KeyBindParser.addPreferenceChangeListener(this);
+ GUIP.addPreferenceChangeListener(this);
}
@Override
@@ -146,12 +145,13 @@ public void draw(Graphics graph, Rectangle clipBounds) {
changed = false;
// calculate the size from the text lines, font and padding
- graph.setFont(FONT);
- FontMetrics fm = graph.getFontMetrics(FONT);
+ Font newFont = FONT.deriveFont(FONT.getSize() * GUIP.getGUIScale());
+ graph.setFont(newFont);
+ FontMetrics fm = graph.getFontMetrics(newFont);
List allLines = assembleTextLines();
Rectangle r = getSize(graph, allLines, fm);
r = new Rectangle(r.width + 2 * PADDING_X, r.height + 2 * PADDING_Y);
-
+
displayImage = ImageUtil.createAcceleratedImage(r.width, r.height);
Graphics intGraph = displayImage.getGraphics();
GUIPreferences.AntiAliasifSet(intGraph);
@@ -190,6 +190,10 @@ private Rectangle getSize(Graphics graph, List lines, FontMetrics fm) {
int width = 0;
for (String line: lines) {
if (fm.stringWidth(line) > width) {
+ if (line.startsWith("#") && line.length() > 7) {
+ line = line.substring(7);
+ }
+
width = fm.stringWidth(line);
}
}
@@ -267,15 +271,21 @@ private void drawShadowedString(Graphics graph, String s, int x, int y) {
int grn = Integer.parseInt(s.substring(3, 5), 16);
int blu = Integer.parseInt(s.substring(5, 7), 16);
textColor = new Color(red, grn, blu);
- } catch (Exception e) {
- LogManager.getLogger().error("", e);
+ } catch (Exception ex) {
+ LogManager.getLogger().error("", ex);
}
s = s.substring(7);
}
- graph.setColor(SHADOW_COLOR);
- graph.drawString(s, x + 1, y + 1);
- graph.setColor(textColor);
- graph.drawString(s, x, y);
+
+ if (s.length() > 0) {
+ AttributedString text = new AttributedString(s);
+ text.addAttribute(TextAttribute.FONT, new Font(FONT.getFontName(), Font.PLAIN, (int) (FONT.getSize() * GUIP.getGUIScale())), 0, s.length());
+
+ graph.setColor(SHADOW_COLOR);
+ graph.drawString(text.getIterator(), x + 1, y + 1);
+ graph.setColor(textColor);
+ graph.drawString(text.getIterator(), x, y);
+ }
}
/**
@@ -285,7 +295,7 @@ private void drawShadowedString(Graphics graph, String s, int x, int y) {
* */
public void setVisible(boolean vis) {
visible = vis;
- GUIPreferences.getInstance().setValue(GUIPreferences.SHOW_KEYBINDS_OVERLAY, vis);
+ GUIP.setValue(GUIPreferences.SHOW_KEYBINDS_OVERLAY, vis);
if (vis) {
fadingIn = true;
fadingOut = false;
@@ -341,9 +351,8 @@ public void gameTurnChange(GameTurnChangeEvent e) {
@Override
public void preferenceChange(PreferenceChangeEvent e) {
- if (e.getName().equals(KeyBindParser.KEYBINDS_CHANGED)) {
- changed = true;
- }
+ // change on any preference change
+ changed = true;
}
}
diff --git a/megamek/src/megamek/client/ui/swing/boardview/MovingEntitySprite.java b/megamek/src/megamek/client/ui/swing/boardview/MovingEntitySprite.java
index 7b94c38a295..58142c3eda8 100644
--- a/megamek/src/megamek/client/ui/swing/boardview/MovingEntitySprite.java
+++ b/megamek/src/megamek/client/ui/swing/boardview/MovingEntitySprite.java
@@ -1,18 +1,13 @@
package megamek.client.ui.swing.boardview;
-import java.awt.AlphaComposite;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.Rectangle;
-import java.awt.image.ImageObserver;
-
+import megamek.MMConstants;
import megamek.common.Coords;
import megamek.common.Entity;
import megamek.common.util.ImageUtil;
+import java.awt.*;
+import java.awt.image.ImageObserver;
+
class MovingEntitySprite extends Sprite {
private int facing;
@@ -23,17 +18,17 @@ class MovingEntitySprite extends Sprite {
private int elevation;
- public MovingEntitySprite(BoardView boardView1, final Entity entity,
- final Coords position, final int facing, final int elevation) {
+ public MovingEntitySprite(BoardView boardView1, final Entity entity, final Coords position,
+ final int facing, final int elevation) {
super(boardView1);
this.entity = entity;
this.facing = facing;
this.elevation = elevation;
String shortName = entity.getShortName();
- Font font = new Font("SansSerif", Font.PLAIN, 10);
- modelRect = new Rectangle(47, 55, bv.getFontMetrics(font).stringWidth(
- shortName) + 1, bv.getFontMetrics(font).getAscent());
+ Font font = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 10);
+ modelRect = new Rectangle(47, 55, bv.getFontMetrics(font).stringWidth(shortName) + 1,
+ bv.getFontMetrics(font).getAscent());
int altAdjust = 0;
if (bv.useIsometric()
diff --git a/megamek/src/megamek/client/ui/swing/boardview/PlanetaryConditionsOverlay.java b/megamek/src/megamek/client/ui/swing/boardview/PlanetaryConditionsOverlay.java
new file mode 100644
index 00000000000..747a3abc4d6
--- /dev/null
+++ b/megamek/src/megamek/client/ui/swing/boardview/PlanetaryConditionsOverlay.java
@@ -0,0 +1,400 @@
+/*
+* MegaMek - Copyright (C) 2020 - The MegaMek Team
+*
+* This program is free software; you can redistribute it and/or modify it under
+* the terms of the GNU General Public License as published by the Free Software
+* Foundation; either version 2 of the License, or (at your option) any later
+* version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+* details.
+*/
+package megamek.client.ui.swing.boardview;
+
+import megamek.client.ui.IDisplayable;
+import megamek.client.ui.Messages;
+import megamek.client.ui.swing.ClientGUI;
+import megamek.client.ui.swing.GUIPreferences;
+import megamek.client.ui.swing.util.KeyCommandBind;
+import megamek.common.Game;
+import megamek.common.KeyBindParser;
+import megamek.common.PlanetaryConditions;
+import megamek.common.enums.GamePhase;
+import megamek.common.event.GameListener;
+import megamek.common.event.GameListenerAdapter;
+import megamek.common.event.GamePhaseChangeEvent;
+import megamek.common.event.GameTurnChangeEvent;
+import megamek.common.preference.IPreferenceChangeListener;
+import megamek.common.preference.PreferenceChangeEvent;
+import megamek.common.util.ImageUtil;
+import org.apache.logging.log4j.LogManager;
+
+import java.awt.event.KeyEvent;
+import java.awt.font.TextAttribute;
+import java.text.AttributedString;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.util.List;
+
+/**
+ * An overlay for the Boardview that displays a selection of Planetary Conditions
+ * for the current game situation
+ *
+ *
+ */
+public class PlanetaryConditionsOverlay implements IDisplayable, IPreferenceChangeListener {
+ private static final Font FONT = new Font("SansSerif", Font.PLAIN, 13);
+ private static final int DIST_TOP = 30;
+ private int distSide = 500;
+ private int overlayWidth = 500;
+ private static final int PADDING_X = 10;
+ private static final int PADDING_Y = 5;
+ private static final Color SHADOW_COLOR = Color.DARK_GRAY;
+ private static final float FADE_SPEED = 0.2f;
+
+ ClientGUI clientGui;
+ private static final GUIPreferences GUIP = GUIPreferences.getInstance();
+
+ /** True when the overlay is displayed or fading in. */
+ private boolean visible;
+ /** True indicates the strings should be redrawn. */
+ private boolean changed = true;
+ /** The cached image for this Display. */
+ Image displayImage;
+ /** The current game phase. */
+ GamePhase currentPhase;
+
+ Game currentGame;
+ /** True while fading in this overlay. */
+ private boolean fadingIn = false;
+ /** True while fading out this overlay. */
+ private boolean fadingOut = false;
+ /** The transparency of the overlay. Only used while fading in/out. */
+ private float alpha = 1;
+
+ private static final String MSG_HEADING = Messages.getString("PlanetaryConditionsOverlay.heading");
+ private static final String MSG_TEMPERATURE = Messages.getString("PlanetaryConditionsOverlay.Temperature");
+ private static final String MSG_GRAVITY = Messages.getString("PlanetaryConditionsOverlay.Gravity");
+ private static final String MSG_LIGHT = Messages.getString("PlanetaryConditionsOverlay.Light");
+ private static final String MSG_ATMOSPHERICPREASSURE = Messages.getString("PlanetaryConditionsOverlay.AtmosphericPressure");
+ private static final String MSG_EMI = Messages.getString("PlanetaryConditionsOverlay.EMI");
+ private static final String MSG_WEATHER = Messages.getString("PlanetaryConditionsOverlay.Weather");
+ private static final String MSG_WIND = Messages.getString("PlanetaryConditionsOverlay.Wind");
+ private static final String MSG_DIRECTION = Messages.getString("PlanetaryConditionsOverlay.WindDirection");
+ private static final String MSG_FOG = Messages.getString("PlanetaryConditionsOverlay.Fog");
+ private static final String MSG_BLOWINGSAND = Messages.getString("PlanetaryConditionsOverlay.BlowingSand");
+
+ /**
+ * An overlay for the Boardview that displays a selection of Planetary Conditions
+ * for the current game situation.
+ */
+ public PlanetaryConditionsOverlay(Game game, ClientGUI cg) {
+ visible = GUIP.getBoolean(GUIPreferences.SHOW_PLANETARYCONDITIONS_OVERLAY);
+ currentGame = game;
+ currentPhase = game.getPhase();
+ game.addGameListener(gameListener);
+ clientGui = cg;
+ KeyBindParser.addPreferenceChangeListener(this);
+ GUIP.addPreferenceChangeListener(this);
+ }
+
+ @Override
+ public void draw(Graphics graph, Rectangle clipBounds) {
+ if (!visible && !isSliding()) {
+ return;
+ }
+
+ if ((clientGui == null) || (currentGame == null)) {
+ return;
+ }
+
+ // At startup, phase and turn change and when the Planetary Conditions change,
+ // the cached image is (re)created
+ if (changed) {
+ changed = false;
+
+ // calculate the size from the text lines, font and padding
+ Font newFont = FONT.deriveFont(FONT.getSize() * GUIP.getGUIScale());
+ graph.setFont(newFont);
+ FontMetrics fm = graph.getFontMetrics(newFont);
+ List allLines = assembleTextLines();
+ Rectangle r = getSize(graph, allLines, fm);
+ r = new Rectangle(r.width + 2 * PADDING_X, r.height + 2 * PADDING_Y);
+ overlayWidth = r.width;
+
+ displayImage = ImageUtil.createAcceleratedImage(r.width, r.height);
+ Graphics intGraph = displayImage.getGraphics();
+ GUIPreferences.AntiAliasifSet(intGraph);
+
+ // draw a semi-transparent background rectangle
+ Color colorBG = GUIP.getPlanetaryConditionsColorBackground();
+ intGraph.setColor(new Color(colorBG.getRed(), colorBG.getGreen(), colorBG.getBlue(), 200));
+ intGraph.fillRoundRect(0, 0, r.width, r.height, PADDING_X, PADDING_X);
+
+ // The coordinates to write the texts to
+ int x = PADDING_X;
+ int y = PADDING_Y + fm.getAscent();
+
+ // write the strings
+ for (String line: allLines) {
+ drawShadowedString(intGraph, line, x, y);
+ y += fm.getHeight();
+ }
+ }
+
+ distSide = clientGui.getWidth() - (overlayWidth + 100);
+
+ // draw the cached image to the boardview
+ // uses Composite to draw the image with variable transparency
+ if (alpha < 1) {
+ // Save the former composite and set an alpha blending composite
+ Composite saveComp = ((Graphics2D) graph).getComposite();
+ int type = AlphaComposite.SRC_OVER;
+ ((Graphics2D) graph).setComposite(AlphaComposite.getInstance(type, alpha));
+ graph.drawImage(displayImage, clipBounds.x + distSide, clipBounds.y + DIST_TOP, null);
+ ((Graphics2D) graph).setComposite(saveComp);
+ } else {
+ graph.drawImage(displayImage, clipBounds.x + distSide, clipBounds.y + DIST_TOP, null);
+ }
+ }
+
+ /** Calculates the pixel size of the display from the necessary text lines. */
+ private Rectangle getSize(Graphics graph, List lines, FontMetrics fm) {
+ int width = 0;
+ for (String line: lines) {
+ if (fm.stringWidth(line) > width) {
+ if (line.startsWith("#") && line.length() > 7) {
+ line = line.substring(7);
+ }
+
+ width = fm.stringWidth(line);
+ }
+ }
+ int height = fm.getHeight() * lines.size();
+ return new Rectangle(width, height);
+ }
+
+ /** Returns an ArrayList of all text lines to be shown. */
+ private List assembleTextLines() {
+ List result = new ArrayList<>();
+
+ Color colorTitle = GUIP.getPlanetaryConditionsColorTitle();
+ Color colorHot = GUIP.getPlanetaryConditionsColorHot();
+ Color colorCold = GUIP.getPlanetaryConditionsColorCold();
+
+ KeyCommandBind kcb = KeyCommandBind.PLANETARY_CONDITIONS;
+ String mod = KeyEvent.getModifiersExText(kcb.modifiers);
+ String key = KeyEvent.getKeyText(kcb.key);
+ String toggleKey = (mod.isEmpty() ? "" : mod + "+") + key;
+
+ String tmpStr = "";
+ Boolean showHeading = GUIP.getAdvancedPlanetaryConditionsShowHeader();
+ tmpStr = (showHeading ? String.format("#%02X%02X%02X", colorTitle.getRed(), colorTitle.getGreen(), colorTitle.getBlue()) + MessageFormat.format(MSG_HEADING, toggleKey) : "");
+
+ if (tmpStr.length() > 0) {
+ result.add(tmpStr);
+ }
+
+ if (clientGui != null && !currentGame.getBoard().inSpace()) {
+ // In a game, not the Board Editor
+
+ String tempColor = "";
+ int temp = currentGame.getPlanetaryConditions().getTemperature();
+
+ if (currentGame.getPlanetaryConditions().isExtremeTemperatureHeat()) {
+ tempColor = String.format("#%02X%02X%02X", colorHot.getRed(), colorHot.getGreen(), colorHot.getBlue());
+ } else if (currentGame.getPlanetaryConditions().isExtremeTemperatureCold()) {
+ tempColor = String.format("#%02X%02X%02X", colorCold.getRed(), colorCold.getGreen(), colorCold.getBlue());
+ }
+
+ boolean showDefaultConditions = GUIP.getAdvancedPlanetaryConditionsShowDefaults();
+
+ Boolean showLabel = GUIP.getAdvancedPlanetaryConditionsShowLabels();
+ Boolean showValue = GUIP.getAdvancedPlanetaryConditionsShowValues();
+ Boolean showIndicator = GUIP.getAdvancedPlanetaryConditionsShowIndicators();
+
+
+ if (((showDefaultConditions) || ((!showDefaultConditions) && (currentGame.getPlanetaryConditions().isExtremeTemperature())))) {
+ tmpStr = (showLabel ? MSG_TEMPERATURE + " " : "");
+ tmpStr = tmpStr + (showValue ? temp + "\u00B0C " : "");
+ tmpStr = tmpStr + (showIndicator ? (!showValue ? temp + "\u00B0C " : "" ) + currentGame.getPlanetaryConditions().getTemperatureIndicator() : "");
+ result.add(tempColor + tmpStr);
+ }
+
+ if (((showDefaultConditions) || ((!showDefaultConditions) && (currentGame.getPlanetaryConditions().getGravity() != 1.0)))) {
+ float grav = currentGame.getPlanetaryConditions().getGravity();
+ tmpStr = (showLabel ? MSG_GRAVITY + " " : "");
+ tmpStr = tmpStr + (showValue ? grav + "g " : "");
+ tmpStr = tmpStr + (showIndicator ? (!showValue ? grav + "g " : "") + currentGame.getPlanetaryConditions().getGravityIndicator() : "");
+ result.add(tmpStr);
+ }
+
+ if (((showDefaultConditions) || ((!showDefaultConditions) && (currentGame.getPlanetaryConditions().getLight() != PlanetaryConditions.L_DAY)))) {
+ tmpStr = (showLabel ? MSG_LIGHT + " " : "");
+ tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getLightDisplayableName() + " " : "");
+ tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getLightIndicator() : "");
+ result.add(tmpStr);
+ }
+
+ if (((showDefaultConditions) || ((!showDefaultConditions) && (currentGame.getPlanetaryConditions().getAtmosphere() != PlanetaryConditions.ATMO_STANDARD)))) {
+ tmpStr = (showLabel ? MSG_ATMOSPHERICPREASSURE + " " : "");
+ tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getAtmosphereDisplayableName() + " " : "");
+ tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getAtmosphereIndicator() : "");
+ result.add(tmpStr);
+ }
+
+ if (((showDefaultConditions) || ((!showDefaultConditions) && (currentGame.getPlanetaryConditions().hasEMI())))) {
+ tmpStr = (showLabel ? MSG_EMI + " " : "");
+ tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getEMIDisplayableValue() + " " : "");
+ tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getEMIIndicator() : "");
+ result.add(tmpStr);
+ }
+
+ if (((showDefaultConditions) || ((!showDefaultConditions) && (currentGame.getPlanetaryConditions().getWeather() != PlanetaryConditions.WE_NONE)))) {
+ tmpStr = (showLabel ? MSG_WEATHER + " " : "");
+ tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getWeatherDisplayableName() + " " : "");
+ tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getWeatherIndicator() : "");
+ result.add(tmpStr);
+ }
+
+ if (((showDefaultConditions) || ((!showDefaultConditions) && (currentGame.getPlanetaryConditions().getWindStrength() != PlanetaryConditions.WI_NONE)))) {
+ tmpStr = (showLabel ? MSG_WIND + " " : "");
+ tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getWindDisplayableName() + " " : "");
+ tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getWindStrengthIndicator() : "");
+ result.add(tmpStr);
+ tmpStr = (showLabel ? MSG_DIRECTION + " " : "");
+ tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getWindDirDisplayableName() + " " : "");
+ tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getWindDirectionIndicator() : "");
+ result.add(tmpStr);
+ }
+
+ if (((showDefaultConditions) || ((!showDefaultConditions) && (currentGame.getPlanetaryConditions().getFog() != PlanetaryConditions.FOG_NONE)))) {
+ tmpStr = (showLabel ? MSG_FOG + " " : "");
+ tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getFogDisplayableName() + " " : "");
+ tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getFogIndicator() : "");
+ result.add(tmpStr);
+ }
+
+ if (((showDefaultConditions) || ((!showDefaultConditions) && (currentGame.getPlanetaryConditions().isSandBlowing())))) {
+ tmpStr = (showLabel ? MSG_BLOWINGSAND + " " : "");
+ tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getSandBlowingDisplayableValue() + " " : "");
+ tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getSandBlowingIndicator() : "");
+ result.add(tmpStr);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Draws the String s to the Graphics graph at position x, y
+ * with a shadow. If the string starts with #789ABC then 789ABC
+ * is converted to a color to write the rest of the text,
+ * otherwise TEXT_COLOR is used.
+ */
+ private void drawShadowedString(Graphics graph, String s, int x, int y) {
+ Color textColor = GUIP.getPlanetaryConditionsColorText();
+ // Extract a color code from the start of the string
+ // used to display headlines if it's there
+ if (s.startsWith("#") && s.length() > 7) {
+ try {
+ int red = Integer.parseInt(s.substring(1, 3), 16);
+ int grn = Integer.parseInt(s.substring(3, 5), 16);
+ int blu = Integer.parseInt(s.substring(5, 7), 16);
+ textColor = new Color(red, grn, blu);
+ } catch (Exception e) {
+ LogManager.getLogger().error("", e);
+ }
+ s = s.substring(7);
+ }
+
+ if (s.length() > 0) {
+ AttributedString text = new AttributedString(s);
+ text.addAttribute(TextAttribute.FONT, new Font(FONT.getFontName(), Font.PLAIN, (int) (FONT.getSize() * GUIP.getGUIScale())), 0, s.length());
+
+ graph.setColor(SHADOW_COLOR);
+ graph.drawString(text.getIterator(), x + 1, y + 1);
+ graph.setColor(textColor);
+ graph.drawString(text.getIterator(), x, y);
+ }
+ }
+
+ /**
+ * Activates or deactivates the overlay, fading it in or out.
+ * Also saves the visibility to the GUIPreferences so
+ * MegaMek remembers it.
+ * */
+ public void setVisible(boolean vis) {
+ visible = vis;
+ GUIP.setValue(GUIPreferences.SHOW_PLANETARYCONDITIONS_OVERLAY, vis);
+ if (vis) {
+ fadingIn = true;
+ fadingOut = false;
+ } else {
+ fadingIn = false;
+ fadingOut = true;
+ }
+ }
+
+ public boolean isVisible() {
+ return visible;
+ }
+
+ @Override
+ public boolean isSliding() {
+ return fadingOut || fadingIn;
+ }
+
+ @Override
+ public boolean slide() {
+ if (fadingIn) {
+ alpha += FADE_SPEED;
+ if (alpha > 1) {
+ alpha = 1;
+ fadingIn = false;
+ }
+ return true;
+ } else if (fadingOut) {
+ alpha -= FADE_SPEED;
+ if (alpha < 0) {
+ alpha = 0;
+ fadingOut = false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /** Detects phase and turn changes to display Planetary Conditions. */
+ private GameListener gameListener = new GameListenerAdapter() {
+ @Override
+ public void gamePhaseChange(GamePhaseChangeEvent e) {
+ currentPhase = e.getNewPhase();
+ changed = true;
+ }
+
+ @Override
+ public void gameTurnChange(GameTurnChangeEvent e) {
+ // The active player has changed
+ changed = true;
+ }
+ };
+
+ @Override
+ public void preferenceChange(PreferenceChangeEvent e) {
+ // change on any preference change
+ changed = true;
+ }
+
+}
diff --git a/megamek/src/megamek/client/ui/swing/boardview/StepSprite.java b/megamek/src/megamek/client/ui/swing/boardview/StepSprite.java
index 669ca4361a7..39e37f17ad1 100644
--- a/megamek/src/megamek/client/ui/swing/boardview/StepSprite.java
+++ b/megamek/src/megamek/client/ui/swing/boardview/StepSprite.java
@@ -13,16 +13,16 @@
*/
package megamek.client.ui.swing.boardview;
-import java.awt.*;
-import java.awt.geom.AffineTransform;
-import java.awt.image.BufferedImage;
-
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
-import megamek.codeUtilities.StringUtility;
import megamek.common.*;
import megamek.common.MovePath.MoveStepType;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+
/**
* Sprite for a step in a movement path. Only one sprite should exist for
* any hex in a path. Contains a colored number, and arrows indicating
@@ -256,7 +256,7 @@ public void prepare() {
// show new movement mode
String mode = Messages.getString("BoardView1.ConversionMode."
+ step.getMovementMode());
- graph.setFont(new Font("SansSerif", Font.PLAIN, 12));
+ graph.setFont(new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 12));
int modeX = 42 - (graph.getFontMetrics(graph.getFont()).stringWidth(mode) / 2);
graph.setColor(Color.darkGray);
graph.drawString(mode, modeX, modePos - 1);
@@ -305,7 +305,7 @@ private void drawAnnouncement(Graphics2D graph, String text, MoveStep step, Colo
if (step.isPastDanger()) {
text = "(" + text + ")";
}
- graph.setFont(new Font("SansSerif", Font.PLAIN, 12));
+ graph.setFont(new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 12));
int posX = 42 - (graph.getFontMetrics(graph.getFont()).stringWidth(text) / 2);
int posY = 38 + graph.getFontMetrics(graph.getFont()).getHeight();
graph.setColor(Color.darkGray);
@@ -323,7 +323,7 @@ private void drawAnnouncement(Graphics2D graph, String text, MoveStep step, Colo
private void drawConditions(MoveStep step, Graphics graph, Color col) {
if (step.isEvading()) {
String evade = Messages.getString("BoardView1.Evade");
- graph.setFont(new Font("SansSerif", Font.PLAIN, 12));
+ graph.setFont(new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 12));
int evadeX = 42 - (graph.getFontMetrics(graph.getFont()).stringWidth(evade) / 2);
graph.setColor(Color.darkGray);
graph.drawString(evade, evadeX, 64);
@@ -334,7 +334,7 @@ private void drawConditions(MoveStep step, Graphics graph, Color col) {
if (step.isRolled()) {
// Announce roll
String roll = Messages.getString("BoardView1.Roll");
- graph.setFont(new Font("SansSerif", Font.PLAIN, 12));
+ graph.setFont(new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 12));
int rollX = 42 - (graph.getFontMetrics(graph.getFont()).stringWidth(roll) / 2);
graph.setColor(Color.darkGray);
graph.drawString(roll, rollX, 18);
@@ -357,13 +357,12 @@ private void drawActiveVectors(MoveStep step, Graphics graph) {
int[] v = step.getVectors();
for (int i = 0; i < 6; i++) {
String active = Integer.toString(v[i]);
- graph.setFont(new Font("SansSerif", Font.PLAIN, 12));
+ graph.setFont(new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 12));
graph.setColor(Color.darkGray);
graph.drawString(active, activeXpos[i], activeYpos[i]);
graph.setColor(Color.red);
graph.drawString(active, activeXpos[i] - 1, activeYpos[i] - 1);
}
-
}
@Override
@@ -377,13 +376,9 @@ public MoveStep getStep() {
}
private Font getMovementFont() {
- String fontName = GUIPreferences.getInstance().getString(
- GUIPreferences.ADVANCED_MOVE_FONT_TYPE);
- int fontStyle = GUIPreferences.getInstance().getInt(
- GUIPreferences.ADVANCED_MOVE_FONT_STYLE);
- int fontSize = GUIPreferences.getInstance().getInt(
- GUIPreferences.ADVANCED_MOVE_FONT_SIZE);
-
+ String fontName = GUIPreferences.getInstance().getString(GUIPreferences.ADVANCED_MOVE_FONT_TYPE);
+ int fontStyle = GUIPreferences.getInstance().getInt(GUIPreferences.ADVANCED_MOVE_FONT_STYLE);
+ int fontSize = GUIPreferences.getInstance().getInt(GUIPreferences.ADVANCED_MOVE_FONT_SIZE);
return new Font(fontName, fontStyle, fontSize);
}
@@ -394,8 +389,7 @@ private void drawRemainingVelocity(MoveStep step, Graphics graph, boolean shiftF
return;
}
- if (!step.getEntity().isAirborne()
- || !step.getEntity().isAero()) {
+ if (!step.getEntity().isAirborne() || !step.getEntity().isAero()) {
return;
}
@@ -416,7 +410,7 @@ private void drawRemainingVelocity(MoveStep step, Graphics graph, boolean shiftF
// Convert the buffer to a String and draw it.
String velString = velStringBuf.toString();
- graph.setFont(new Font("SansSerif", Font.PLAIN, 12));
+ graph.setFont(new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 12));
int costX = 42;
if (shiftFlag) {
costX -= (graph.getFontMetrics(graph.getFont()).stringWidth(velString) / 2);
@@ -437,7 +431,7 @@ private void drawRemainingVelocity(MoveStep step, Graphics graph, boolean shiftF
}
String turnString = "<" + step.getNStraight() + ">";
- graph.setFont(new Font("SansSerif", Font.PLAIN, 10));
+ graph.setFont(new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 10));
costX = 50;
graph.setColor(Color.darkGray);
graph.drawString(turnString, costX, 15);
diff --git a/megamek/src/megamek/client/ui/swing/boardview/TextMarkerSprite.java b/megamek/src/megamek/client/ui/swing/boardview/TextMarkerSprite.java
index b9116dd46cc..e7e0daa5ea9 100644
--- a/megamek/src/megamek/client/ui/swing/boardview/TextMarkerSprite.java
+++ b/megamek/src/megamek/client/ui/swing/boardview/TextMarkerSprite.java
@@ -1,17 +1,13 @@
package megamek.client.ui.swing.boardview;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.geom.Rectangle2D;
-
+import megamek.MMConstants;
import megamek.client.ui.swing.GUIPreferences;
import megamek.common.Coords;
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+
public class TextMarkerSprite extends HexSprite {
-
private String spriteText;
private Color spriteColor;
@@ -33,7 +29,7 @@ public void prepare() {
// get a big font and test to see which font size will fit
// the hex shape
- Font textFont = new Font("SansSerif", Font.PLAIN, 1000);
+ Font textFont = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 1000);
graph.setFont(textFont);
FontMetrics fm = graph.getFontMetrics(graph.getFont());
Rectangle2D rect = fm.getStringBounds(spriteText, graph);
@@ -50,9 +46,9 @@ public void prepare() {
factor = factor * 0.7f;
// set the font and draw the text
- Font textFontS = new Font("SansSerif", Font.PLAIN, (int) (factor * 1000));
+ Font textFontS = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, (int) (factor * 1000));
graph.setFont(textFontS);
- Point pos = new Point((int) (bounds.getWidth() / 2),(int) (bounds.getHeight() / 2));
+ Point pos = new Point((int) (bounds.getWidth() / 2), (int) (bounds.getHeight() / 2));
bv.drawTextShadow(graph, spriteText, pos, textFontS);
bv.drawCenteredText(graph, spriteText, pos, spriteColor, false);
}
diff --git a/megamek/src/megamek/client/ui/swing/boardview/WreckSprite.java b/megamek/src/megamek/client/ui/swing/boardview/WreckSprite.java
index 7a5917ff012..53d164bdf75 100644
--- a/megamek/src/megamek/client/ui/swing/boardview/WreckSprite.java
+++ b/megamek/src/megamek/client/ui/swing/boardview/WreckSprite.java
@@ -1,24 +1,23 @@
/*
* MegaMek - Copyright (C) 2020 - The MegaMek Team
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
*/
-
package megamek.client.ui.swing.boardview;
-import java.awt.Font;
-import java.awt.Rectangle;
-
+import megamek.MMConstants;
import megamek.common.Entity;
+import java.awt.*;
+
/**
* Sprite for an wreck. Consists of an image, drawn from the Tile Manager
* and an identification label.
@@ -31,15 +30,14 @@ public WreckSprite(BoardView boardView1, final Entity entity, int secondaryPos)
String shortName = entity.getShortName();
- Font font = new Font("SansSerif", Font.PLAIN, 10);
- modelRect = new Rectangle(47, 55, bv.getFontMetrics(font).stringWidth(
- shortName) + 1, bv.getFontMetrics(font).getAscent());
+ Font font = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 10);
+ modelRect = new Rectangle(47, 55, bv.getFontMetrics(font).stringWidth(shortName) + 1,
+ bv.getFontMetrics(font).getAscent());
Rectangle tempBounds = new Rectangle(bv.hex_size).union(modelRect);
if (secondaryPos == -1) {
tempBounds.setLocation(bv.getHexLocation(entity.getPosition()));
} else {
- tempBounds.setLocation(bv.getHexLocation(entity
- .getSecondaryPositions().get(secondaryPos)));
+ tempBounds.setLocation(bv.getHexLocation(entity.getSecondaryPositions().get(secondaryPos)));
}
bounds = tempBounds;
diff --git a/megamek/src/megamek/client/ui/swing/calculationReport/TextCalculationReport.java b/megamek/src/megamek/client/ui/swing/calculationReport/TextCalculationReport.java
index d565bd9aa0b..da898dd37cb 100644
--- a/megamek/src/megamek/client/ui/swing/calculationReport/TextCalculationReport.java
+++ b/megamek/src/megamek/client/ui/swing/calculationReport/TextCalculationReport.java
@@ -18,6 +18,8 @@
*/
package megamek.client.ui.swing.calculationReport;
+import megamek.MMConstants;
+
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
@@ -131,7 +133,7 @@ public JComponent toJComponent() {
final JEditorPane editorPane = new JEditorPane("text/plain", this.toString());
editorPane.setEditable(false);
editorPane.setCaretPosition(0);
- editorPane.setFont(new Font("Monospaced", Font.PLAIN, editorPane.getFont().getSize()));
+ editorPane.setFont(new Font(MMConstants.FONT_MONOSPACED, Font.PLAIN, editorPane.getFont().getSize()));
return editorPane;
}
diff --git a/megamek/src/megamek/client/ui/swing/dialog/AbstractUnitSelectorDialog.java b/megamek/src/megamek/client/ui/swing/dialog/AbstractUnitSelectorDialog.java
index 66612977503..d66dfd7c039 100644
--- a/megamek/src/megamek/client/ui/swing/dialog/AbstractUnitSelectorDialog.java
+++ b/megamek/src/megamek/client/ui/swing/dialog/AbstractUnitSelectorDialog.java
@@ -14,12 +14,14 @@
*/
package megamek.client.ui.swing.dialog;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.dialogs.BVDisplayDialog;
import megamek.client.ui.models.XTableColumnModel;
import megamek.client.ui.panes.EntityViewPane;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.UnitLoadingDialog;
+import megamek.client.ui.swing.util.UIUtil;
import megamek.common.*;
import megamek.common.annotations.Nullable;
import megamek.common.options.GameOptions;
@@ -33,7 +35,9 @@
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
-import javax.swing.table.*;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
@@ -76,10 +80,13 @@ public abstract class AbstractUnitSelectorDialog extends JDialog implements Runn
protected Map techLevelListToIndex = new HashMap<>();
protected JComboBox comboUnitType = new JComboBox<>();
protected JComboBox comboWeight = new JComboBox<>();
+ private JScrollPane techLevelScroll;
+ private JPanel panelFilterButtons;
protected JLabel labelImage = new JLabel(""); //inline to avoid potential null pointer issues
protected JTable tableUnits;
protected JTextField textFilter;
protected EntityViewPane panePreview;
+ private JPanel selectionPanel;
private JSplitPane splitPane;
private StringBuffer searchBuffer = new StringBuffer();
@@ -101,6 +108,7 @@ public abstract class AbstractUnitSelectorDialog extends JDialog implements Runn
private AdvancedSearchDialog2 advancedSearchDialog2;
protected TableRowSorter sorter;
+ private JScrollPane scrollTableUnits;
protected GameOptions gameOptions = null;
protected boolean enableYearLimits = false;
@@ -173,12 +181,12 @@ private void initComponents() {
//region Unit Preview Pane
panePreview = new EntityViewPane(frame, null);
+ panePreview.setMinimumSize(new Dimension(0,0));
+ panePreview.setPreferredSize(new Dimension(0,0));
//endregion Unit Preview Pane
//region Selection Panel
- JPanel selectionPanel = new JPanel(new GridBagLayout());
- selectionPanel.setMinimumSize(new Dimension(500, 500));
- selectionPanel.setPreferredSize(new Dimension(500, 600));
+ selectionPanel = new JPanel(new GridBagLayout());
tableUnits = new JTable(unitModel);
tableUnits.setColumnModel(unitColumnModel);
@@ -199,27 +207,19 @@ private void initComponents() {
refreshUnitView();
}
});
- for (int i = 0; i < MechTableModel.N_COL; i++) {
- TableColumn column = tableUnits.getColumnModel().getColumn(i);
- if (i == MechTableModel.COL_CHASSIS) {
- column.setPreferredWidth(125);
- } else if ((i == MechTableModel.COL_MODEL) || (i == MechTableModel.COL_COST)) {
- column.setPreferredWidth(75);
- } else if ((i == MechTableModel.COL_WEIGHT) || (i == MechTableModel.COL_BV)) {
- column.setPreferredWidth(50);
- } else {
- column.setPreferredWidth(25);
- }
+
+ for (int i = 0; i < unitModel.getColumnCount(); i++) {
+ tableUnits.getColumnModel().getColumn(i).setPreferredWidth(unitModel.getPreferredWidth(i));
}
bvColumn = tableUnits.getColumnModel().getColumn(MechTableModel.COL_BV);
pvColumn = tableUnits.getColumnModel().getColumn(MechTableModel.COL_PV);
- tableUnits.setFont(new Font("Monospaced", Font.PLAIN, 12));
+ tableUnits.setFont(new Font(MMConstants.FONT_MONOSPACED, Font.PLAIN, 12));
togglePV(false);
- JScrollPane scrollTableUnits = new JScrollPane(tableUnits);
+ scrollTableUnits = new JScrollPane(tableUnits);
scrollTableUnits.setName("scrollTableUnits");
- scrollTableUnits.setMinimumSize(new Dimension(500, 400));
- scrollTableUnits.setPreferredSize(new Dimension(500, 400));
+
+ gridBagConstraints.insets = new Insets(5, 0, 0, 0);
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 2;
gridBagConstraints.fill = GridBagConstraints.BOTH;
@@ -228,20 +228,17 @@ private void initComponents() {
gridBagConstraints.weighty = 1.0;
selectionPanel.add(scrollTableUnits, gridBagConstraints);
- JPanel panelFilterButtons = new JPanel(new GridBagLayout());
- panelFilterButtons.setMinimumSize(new Dimension(300, 180));
- panelFilterButtons.setPreferredSize(new Dimension(300, 180));
+ panelFilterButtons = new JPanel(new GridBagLayout());
JLabel labelType = new JLabel(Messages.getString("MechSelectorDialog.m_labelType"));
labelType.setToolTipText(Messages.getString("MechSelectorDialog.m_labelType.ToolTip"));
+ gridBagConstraintsWest.insets = new Insets(5, 0, 0, 0);
gridBagConstraintsWest.gridx = 0;
gridBagConstraintsWest.gridy = 2;
panelFilterButtons.add(labelType, gridBagConstraintsWest);
listTechLevel.setToolTipText(Messages.getString("MechSelectorDialog.m_labelType.ToolTip"));
- JScrollPane techLevelScroll = new JScrollPane(listTechLevel);
- techLevelScroll.setMinimumSize(new Dimension(300, 100));
- techLevelScroll.setPreferredSize(new Dimension(300, 100));
+ techLevelScroll = new JScrollPane(listTechLevel);
gridBagConstraintsWest.gridx = 1;
gridBagConstraintsWest.gridy = 2;
panelFilterButtons.add(techLevelScroll, gridBagConstraintsWest);
@@ -259,8 +256,6 @@ private void initComponents() {
weightModel.addElement(Messages.getString("MechSelectorDialog.All"));
comboWeight.setModel(weightModel);
comboWeight.setName("comboWeight");
- comboWeight.setMinimumSize(new Dimension(300, 27));
- comboWeight.setPreferredSize(new Dimension(300, 27));
comboWeight.addActionListener(this);
gridBagConstraintsWest.gridx = 1;
gridBagConstraintsWest.gridy = 1;
@@ -283,8 +278,6 @@ private void initComponents() {
unitTypeModel.addElement(Messages.getString("MechSelectorDialog.SupportVee"));
comboUnitType.setModel(unitTypeModel);
comboUnitType.setName("comboUnitType");
- comboUnitType.setMinimumSize(new Dimension(300, 27));
- comboUnitType.setPreferredSize(new Dimension(300, 27));
comboUnitType.addActionListener(this);
gridBagConstraintsWest.gridx = 1;
gridBagConstraintsWest.gridy = 0;
@@ -292,8 +285,6 @@ private void initComponents() {
textFilter = new JTextField("");
textFilter.setName("textFilter");
- textFilter.setMinimumSize(new Dimension(300, 28));
- textFilter.setPreferredSize(new Dimension(300, 28));
textFilter.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent e) {
@@ -312,7 +303,9 @@ public void removeUpdate(DocumentEvent e) {
});
gridBagConstraintsWest.gridx = 1;
gridBagConstraintsWest.gridy = 3;
+ gridBagConstraintsWest.fill = GridBagConstraints.HORIZONTAL;
panelFilterButtons.add(textFilter, gridBagConstraintsWest);
+ gridBagConstraintsWest.fill = GridBagConstraints.NONE;
JLabel labelFilter = new JLabel(Messages.getString("MechSelectorDialog.m_labelFilter"));
labelFilter.setName("labelFilter");
@@ -373,10 +366,13 @@ public void removeUpdate(DocumentEvent e) {
selectionPanel.add(panelSearchButtons, gridBagConstraints);
//endregion Selection Panel
+ JScrollPane selectionScrollPane = new JScrollPane(selectionPanel);
+ JScrollPane previewScrollPane = new JScrollPane(panePreview);
+
JPanel panelButtons = createButtonsPanel();
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true,
- selectionPanel, panePreview);
+ selectionScrollPane, previewScrollPane);
splitPane.setResizeWeight(0);
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = gridBagConstraints.gridy = 0;
@@ -637,6 +633,10 @@ public void setVisible(boolean visible) {
buttonResetSearch.setEnabled(false);
filterUnits();
+ if (visible) {
+ adaptToGUIScale();
+ }
+
super.setVisible(visible);
}
@@ -796,6 +796,29 @@ public int getColumnCount() {
return N_COL;
}
+ public int getPreferredWidth(int col) {
+ switch (col) {
+ case COL_MODEL:
+ return 75;
+ case COL_CHASSIS:
+ return 125;
+ case COL_WEIGHT:
+ return 50;
+ case COL_BV:
+ return 25;
+ case COL_PV:
+ return 25;
+ case COL_YEAR:
+ return 25;
+ case COL_COST:
+ return 25;
+ case COL_LEVEL:
+ return 25;
+ default:
+ return 0;
+ }
+ }
+
@Override
public String getColumnName(int column) {
switch (column) {
@@ -879,4 +902,12 @@ public Object getValueAt(int row, int col) {
}
}
}
+
+ private void adaptToGUIScale() {
+ UIUtil.adjustDialog(this, UIUtil.FONT_SCALE1);
+ textFilter.setMinimumSize(new Dimension(UIUtil.scaleForGUI(200), UIUtil.scaleForGUI(28)));
+ textFilter.setPreferredSize(new Dimension(UIUtil.scaleForGUI(200), UIUtil.scaleForGUI(28)));
+ techLevelScroll.setMinimumSize(new Dimension(UIUtil.scaleForGUI(300), UIUtil.scaleForGUI(100)));
+ techLevelScroll.setPreferredSize(new Dimension(UIUtil.scaleForGUI(300), UIUtil.scaleForGUI(100)));
+ }
}
diff --git a/megamek/src/megamek/client/ui/swing/dialog/AdvancedSearchDialog2.java b/megamek/src/megamek/client/ui/swing/dialog/AdvancedSearchDialog2.java
index cc1d5368a83..e75f58876eb 100644
--- a/megamek/src/megamek/client/ui/swing/dialog/AdvancedSearchDialog2.java
+++ b/megamek/src/megamek/client/ui/swing/dialog/AdvancedSearchDialog2.java
@@ -21,6 +21,7 @@
import megamek.client.ui.baseComponents.AbstractButtonDialog;
import megamek.client.ui.swing.unitSelector.ASAdvancedSearchPanel;
import megamek.client.ui.swing.unitSelector.TWAdvancedSearchPanel;
+import megamek.client.ui.swing.util.UIUtil;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
@@ -50,6 +51,9 @@ public AdvancedSearchDialog2(JFrame parent, int allowedYear) {
@Override
public void setVisible(boolean b) {
alphaStrikeTab.saveValues();
+ if (b) {
+ adaptToGUIScale();
+ }
super.setVisible(b);
}
@@ -75,7 +79,8 @@ protected JPanel createButtonPanel() {
@Override
protected Container createCenterPane() {
- return advancedSearchPane;
+ JScrollPane advScrollpane = new JScrollPane(advancedSearchPane);
+ return advScrollpane;
}
/** Deactivates the search fields in both search tabs so that no units are filtered out. */
@@ -91,4 +96,9 @@ public ASAdvancedSearchPanel getASAdvancedSearch() {
public TWAdvancedSearchPanel getTWAdvancedSearch() {
return totalWarTab;
}
+
+ private void adaptToGUIScale() {
+ UIUtil.adjustDialog(this, UIUtil.FONT_SCALE1);
+ totalWarTab.adaptToGUIScale();
+ }
}
diff --git a/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/AbstractGameConnectionDialog.java b/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/AbstractGameConnectionDialog.java
index 4d7694e06b4..5b24838e690 100644
--- a/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/AbstractGameConnectionDialog.java
+++ b/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/AbstractGameConnectionDialog.java
@@ -25,6 +25,7 @@
import megamek.client.ui.swing.CloseAction;
import megamek.client.ui.swing.OkayAction;
import megamek.client.ui.swing.dialog.DialogButton;
+import megamek.client.ui.swing.util.UIUtil;
import megamek.codeUtilities.StringUtility;
import megamek.common.preference.ClientPreferences;
import megamek.common.preference.PreferenceManager;
@@ -145,7 +146,7 @@ public void setPlayerName(String playerName) {
if (playerNameCombo == null) {
playerNameCombo = new JComboBox<>(playerNames);
Dimension preferredSize = playerNameCombo.getPreferredSize();
- preferredSize.setSize(180, preferredSize.getHeight());
+ preferredSize.setSize(UIUtil.scaleForGUI(180), UIUtil.scaleForGUI(25));
playerNameCombo.setPreferredSize(preferredSize);
playerNameCombo.setEditable(true);
}
diff --git a/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/ConnectDialog.java b/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/ConnectDialog.java
index 8b0f11e8e16..8b6d892bf63 100644
--- a/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/ConnectDialog.java
+++ b/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/ConnectDialog.java
@@ -111,9 +111,13 @@ public void actionPerformed(ActionEvent e) {
@Override
public void setVisible(boolean b) {
if (b) {
- UIUtil.adjustDialog(getContentPane());
+ adaptToGUIScale();
pack();
}
super.setVisible(b);
}
+
+ private void adaptToGUIScale() {
+ UIUtil.adjustDialog(this, UIUtil.FONT_SCALE1);
+ }
}
diff --git a/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/HostDialog.java b/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/HostDialog.java
index 16a0644021f..1c0a8eaacc4 100644
--- a/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/HostDialog.java
+++ b/megamek/src/megamek/client/ui/swing/gameConnectionDialogs/HostDialog.java
@@ -178,9 +178,13 @@ public void actionPerformed(ActionEvent e) {
@Override
public void setVisible(boolean b) {
if (b) {
- UIUtil.adjustDialog(getContentPane());
+ adaptToGUIScale();
pack();
}
super.setVisible(b);
}
+
+ private void adaptToGUIScale() {
+ UIUtil.adjustDialog(this, UIUtil.FONT_SCALE1);
+ }
}
diff --git a/megamek/src/megamek/client/ui/swing/lobby/ChatLounge.java b/megamek/src/megamek/client/ui/swing/lobby/ChatLounge.java
index eea8f45e2e6..d488719e034 100644
--- a/megamek/src/megamek/client/ui/swing/lobby/ChatLounge.java
+++ b/megamek/src/megamek/client/ui/swing/lobby/ChatLounge.java
@@ -20,6 +20,7 @@
*/
package megamek.client.ui.swing.lobby;
+import megamek.MMConstants;
import megamek.client.Client;
import megamek.client.bot.BotClient;
import megamek.client.bot.princess.BehaviorSettings;
@@ -43,7 +44,6 @@
import megamek.client.ui.swing.widget.SkinSpecification;
import megamek.common.*;
import megamek.common.annotations.Nullable;
-import megamek.common.enums.GamePhase;
import megamek.common.event.*;
import megamek.common.force.Force;
import megamek.common.force.Forces;
@@ -122,35 +122,31 @@ public class ChatLounge extends AbstractPhaseDisplay implements
private JLabel lblTechLevel = new JLabel("");
// Game Setup
- private JButton butOptions = new JButton(Messages.getString("ChatLounge.butOptions"));
- //private JToggleButton butGroundMap = new JToggleButton("Ground Map");
- private JToggleButton butGroundMap = new JToggleButton(Messages.getString("ChatLounge.butGroundMap"));
- //private JToggleButton butLowAtmoMap = new JToggleButton("Low Altitude Map");
- private JToggleButton butLowAtmoMap = new JToggleButton("Low Altitude Map");
- //private JToggleButton butHighAtmoMap = new JToggleButton("High Altitude Map");
- private JToggleButton butHighAtmoMap = new JToggleButton("High Altitude Map");
- //private JToggleButton butSpaceMap = new JToggleButton("Space Map");
- private JToggleButton butSpaceMap = new JToggleButton("Space Map");
+ private JButton butOptions = new JButton(MSG_BUTOPTIONS);
+ private JToggleButton butGroundMap = new JToggleButton(MSG_BUTGROUNDMAP);
+ private JToggleButton butLowAtmoMap = new JToggleButton(MSG_NAMELOWALTITUDEMAP);
+ private JToggleButton butHighAtmoMap = new JToggleButton(MSG_NAMEHIGHALTITUDEMAP);
+ private JToggleButton butSpaceMap = new JToggleButton(MSG_NAMESPACEMAP);
private ButtonGroup grpMap = new ButtonGroup();
/* Unit Configuration Panel */
private FixedYPanel panUnitInfo = new FixedYPanel();
- private JButton butAdd = new JButton(Messages.getString("ChatLounge.butLoad"));
- private JButton butArmy = new JButton(Messages.getString("ChatLounge.butArmy"));
- private JButton butSkills = new JButton(Messages.getString("ChatLounge.butSkills"));
- private JButton butNames = new JButton(Messages.getString("ChatLounge.butNames"));
- private JButton butLoadList = new JButton(Messages.getString("ChatLounge.butLoadList"));
- private JButton butSaveList = new JButton(Messages.getString("ChatLounge.butSaveList"));
+ private JButton butAdd = new JButton(MSG_BUTLOAD);
+ private JButton butArmy = new JButton(MSG_BUTARMY);
+ private JButton butSkills = new JButton(MSG_BUTSKILLS);
+ private JButton butNames = new JButton(MSG_BUTNAMES);
+ private JButton butLoadList = new JButton(MSG_BUTLOADLIST);
+ private JButton butSaveList = new JButton(MSG_BUTSAVELIST);
/* Unit Table */
private JTable mekTable;
public JScrollPane scrMekTable;
- private MMToggleButton butCompact = new MMToggleButton(Messages.getString("ChatLounge.butCompact"));
- private MMToggleButton butShowUnitID = new MMToggleButton(Messages.getString("ChatLounge.butShowUnitID"));
- private JToggleButton butListView = new JToggleButton("Sortable View");
- private JToggleButton butForceView = new JToggleButton("Force View");
- private JButton butCollapse = new JButton("<<");
- private JButton butExpand = new JButton(">>");
+ private MMToggleButton butCompact = new MMToggleButton(MSG_BUTCOMPACT);
+ private MMToggleButton butShowUnitID = new MMToggleButton(MSG_BUTSHOWUNITID);
+ private JToggleButton butListView = new JToggleButton(MSG_BUTSORTABLEVIEW);
+ private JToggleButton butForceView = new JToggleButton(MSG_BUTFORCEVIEW);
+ private JButton butCollapse = new JButton(MSG_BUTCOLLAPSE);
+ private JButton butExpand = new JButton(MSG_BUTEXPAND);
private MekTableModel mekModel;
/* Force Tree */
@@ -162,53 +158,51 @@ public class ChatLounge extends AbstractPhaseDisplay implements
private FixedYPanel panPlayerInfo;
private JComboBox comboTeam = new JComboBox<>();
private JButton butCamo = new JButton();
- private JButton butAddBot = new JButton(Messages.getString("ChatLounge.butAddBot"));
- private JButton butRemoveBot = new JButton(Messages.getString("ChatLounge.butRemoveBot"));
-// private JButton butBotSettings = new JButton("Bot Settings...");
-// private JButton butConfigPlayer = new JButton("Configure Player...");
- private JButton butConfigPlayer = new JButton(Messages.getString("ChatLounge.butConfigPlayer"));
- private JButton butBotSettings = new JButton(Messages.getString("ChatLounge.butBotSettings"));
-
+ private JButton butAddBot = new JButton(MSG_BUTADDBOT);
+ private JButton butRemoveBot = new JButton(MSG_BUTREMOVEBOT);
+ private JButton butConfigPlayer = new JButton(MSG_BUTCONFIGPLAYER);
+ private JButton butBotSettings = new JButton(MSG_BUTSETTINGS);
+
private MekTableMouseAdapter mekTableMouseAdapter = new MekTableMouseAdapter();
private PlayerTableModel playerModel = new PlayerTableModel();
private PlayerTable tablePlayers = new PlayerTable(playerModel, this);
private JScrollPane scrPlayers = new JScrollPane(tablePlayers);
/* Map Settings Panel */
- private JLabel lblMapWidth = new JLabel("Map Width:");
- private JButton butMapGrowW = new JButton(">");
- private JButton butMapShrinkW = new JButton("<");
+ private JLabel lblMapWidth = new JLabel(MSG_LABELMAPWIDTH);
+ private JButton butMapGrowW = new JButton(MSG_BUTGROW);
+ private JButton butMapShrinkW = new JButton(MSG_BUTSHRINK);
private JTextField fldMapWidth = new JTextField(3);
- private JLabel lblMapHeight = new JLabel("Map Height:");
- private JButton butMapGrowH = new JButton(">");
- private JButton butMapShrinkH = new JButton("<");
+ private JLabel lblMapHeight = new JLabel(MSG_LABELMAPHEIGHT);
+ private JButton butMapGrowH = new JButton(MSG_BUTGROW);
+ private JButton butMapShrinkH = new JButton(MSG_BUTSHRINK);
private JTextField fldMapHeight = new JTextField(3);
private FixedYPanel panMapHeight = new FixedYPanel();
private FixedYPanel panMapWidth = new FixedYPanel();
- private JLabel lblSpaceBoardWidth = new JLabel("Board Width:");
+ private JLabel lblSpaceBoardWidth = new JLabel(MSG_LABELBOARDWIDTH);
private JTextField fldSpaceBoardWidth = new JTextField(3);
- private JLabel lblSpaceBoardHeight = new JLabel("Board Height:");
+ private JLabel lblSpaceBoardHeight = new JLabel(MSG_LABELBOARDHEIGHT);
private JTextField fldSpaceBoardHeight = new JTextField(3);
private FixedYPanel panSpaceBoardHeight = new FixedYPanel();
private FixedYPanel panSpaceBoardWidth = new FixedYPanel();
- private JLabel lblBoardSize = new JLabel("Board Size: ");
- private JButton butHelp = new JButton(" ? ");
-
- private JButton butConditions = new JButton(Messages.getString("ChatLounge.butConditions"));
- private JButton butRandomMap = new JButton(Messages.getString("BoardSelectionDialog.GeneratedMapSettings"));
+ private JLabel lblBoardSize = new JLabel(MSG_LABELBOARDSIZE);
+ private JButton butHelp = new JButton(" " + MSG_BUTHELP + " ");
+
+ private JButton butConditions = new JButton(MSG_BUTCONDITIONS);
+ private JButton butRandomMap = new JButton(MSG_BUTRANDOMMAP);
ArrayList mapButtons = new ArrayList<>(20);
MapSettings mapSettings;
private JPanel panGroundMap;
@SuppressWarnings("rawtypes")
private JComboBox comMapSizes;
- private JButton butBoardPreview = new JButton(Messages.getString("BoardSelectionDialog.ViewGameBoard"));
+ private JButton butBoardPreview = new JButton(MSG_VIEWGAMEBOARD);
private JPanel panMapButtons = new JPanel();
private JLabel lblBoardsAvailable = new JLabel();
private JList lisBoardsAvailable;
private JScrollPane scrBoardsAvailable;
- private JButton butSpaceSize = new JButton(Messages.getString("ChatLounge.MapSize"));
+ private JButton butSpaceSize = new JButton(MSG_BUTMAPSIZE);
private Set mapSizes = new TreeSet<>();
boolean resetAvailBoardSelection = false;
boolean resetSelectedBoards = true;
@@ -221,22 +215,23 @@ public class ChatLounge extends AbstractPhaseDisplay implements
private ArrayList serverBoards = new ArrayList<>();
private JSplitPane splGroundMap;
- private JLabel lblSearch = new JLabel("Search: ");
+ private JLabel lblSearch = new JLabel(MSG_LABELSEARCH);
private JTextField fldSearch = new JTextField(10);
- private JButton butCancelSearch = new JButton("X");
+ private JButton butCancelSearch = new JButton(MSG_BUTCANCELSEARCH);
private MekTableSorter activeSorter;
private ArrayList unitSorters = new ArrayList<>();
private ArrayList bvSorters = new ArrayList<>();
- private JButton butAddY = new JButton("+");
- private JButton butAddX = new JButton("+");
- private JButton butSaveMapSetup = new JButton(Messages.getString("ChatLounge.map.saveMapSetup") + " *");
- private JButton butLoadMapSetup = new JButton(Messages.getString("ChatLounge.map.loadMapSetup"));
+ private JButton butAddY = new JButton(MSG_BUTADD);
+ private JButton butAddX = new JButton(MSG_BUTADD);
+ private JButton butSaveMapSetup = new JButton(MSG_MAPSAVESETUP + " *");
+ private JButton butLoadMapSetup = new JButton(MSG_MAPLOADSETUP);
/* Team Overview Panel */
private TeamOverviewPanel panTeamOverview;
- JButton butDetach = new JButton("Detach to Window");
+ JButton butDetach = new JButton(MSG_BUTDETACH);
+ private JSplitPane splitPaneMain;
ClientDialog teamOverviewWindow;
private ImageLoader loader;
@@ -249,18 +244,124 @@ public class ChatLounge extends AbstractPhaseDisplay implements
private Map boardTags = new HashMap<>();
LobbyKeyDispatcher lobbyKeyDispatcher = new LobbyKeyDispatcher(this);
-
+
+ private static final String CL_KEY_FILEEXTENTION_BOARD = ".board";
+ private static final String CL_KEY_FILEEXTENTION_XML = ".xml";
+ private static final String CL_KEY_FILEPATH_MAPASSEMBLYHELP = "docs/Boards Stuff/MapAssemblyHelp.html";
+ private static final String CL_KEY_FILEPATH_MAPSETUP = "/mapsetup";
+ private static final String CL_KEY_NAMEHELPPANE = "helpPane";
+
+ private static final String CL_ACTIONCOMMAND_LOADLIST = "load_list";
+ private static final String CL_ACTIONCOMMAND_SAVELIST = "save_list";
+ private static final String CL_ACTIONCOMMAND_LOADMECH = "load_mech";
+ private static final String CL_ACTIONCOMMAND_ADDBOT = "add_bot";
+ private static final String CL_ACTIONCOMMAND_REMOVEBOT = "remove_bot";
+ private static final String CL_ACTIONCOMMAND_BOTCONFIG = "BOTCONFIG";
+ private static final String CL_ACTIONCOMMAND_CONFIGURE = "CONFIGURE";
+ private static final String CL_ACTIONCOMMAND_CAMO= "camo";
+
+ private static final String MSG_ERROR = Messages.getString("Error");
+ private static final String MSG_OKAY = Messages.getString("Okay");
+ private static final String MSG_ALERTBOTTITLE = Messages.getString("ChatLounge.AlertBot.title");
+ private static final String MSG_ALERTBOTMESSAGE = Messages.getString("ChatLounge.AlertBot.message");
+ private static final String MSG_BOARDGENERATEDMESSAGE = Messages.getString("ChatLounge.board.generatedMessage");
+ private static final String MSG_BOARDRANDOMLYSELECTEDMESSAGE = Messages.getString("ChatLounge.board.randomlySelectedMessage");
+ private static final String MSG_BOARDSEVERSIDB = Messages.getString("ChatLounge.board.serverSide");
+ private static final String MSG_BUTOPTIONS = Messages.getString("ChatLounge.butOptions");
+ private static final String MSG_BUTGROUNDMAP = Messages.getString("ChatLounge.butGroundMap");
+ private static final String MSG_BUTLOAD = Messages.getString("ChatLounge.butLoad");
+ private static final String MSG_BUTARMY = Messages.getString("ChatLounge.butArmy");
+ private static final String MSG_BUTSKILLS = Messages.getString("ChatLounge.butSkills");
+ private static final String MSG_BUTNAMES = Messages.getString("ChatLounge.butNames");
+ private static final String MSG_BUTLOADLIST = Messages.getString("ChatLounge.butLoadList");
+ private static final String MSG_BUTSAVELIST = Messages.getString("ChatLounge.butSaveList");
+ private static final String MSG_BUTCOMPACT = Messages.getString("ChatLounge.butCompact");
+ private static final String MSG_BUTSHOWUNITID = Messages.getString("ChatLounge.butShowUnitID");
+ private static final String MSG_BUTADDBOT = Messages.getString("ChatLounge.butAddBot");
+ private static final String MSG_BUTREMOVEBOT = Messages.getString("ChatLounge.butRemoveBot");
+ private static final String MSG_BUTCONFIGPLAYER = Messages.getString("ChatLounge.butConfigPlayer");
+ private static final String MSG_BUTSETTINGS = Messages.getString("ChatLounge.butBotSettings");
+ private static final String MSG_BUTCONDITIONS = Messages.getString("ChatLounge.butConditions");
+ private static final String MSG_BUTRANDOMMAP = Messages.getString("BoardSelectionDialog.GeneratedMapSettings");
+ private static final String MSG_BUTMAPSIZE= Messages.getString("ChatLounge.MapSize");
+ private static final String MSG_BUTHELP = Messages.getString("ChatLounge.butHelp");
+ private static final String MSG_BUTCANCELSEARCH = Messages.getString("ChatLounge.butCancelSearch");
+ private static final String MSG_BUTADD = Messages.getString("ChatLounge.butAdd");
+ private static final String MSG_BUTDETACH = Messages.getString("ChatLounge.butDetach");
+ private static final String MSG_BUTCOLLAPSE = Messages.getString("ChatLounge.butCollapse");
+ private static final String MSG_BUTEXPAND = Messages.getString("ChatLounge.butExpand");
+ private static final String MSG_BUTGROW = Messages.getString("ChatLounge.butGrow");
+ private static final String MSG_BUTSHRINK = Messages.getString("ChatLounge.butShrink");
+ private static final String MSG_BUTSORTABLEVIEW = Messages.getString("ChatLounge.butSortableView");
+ private static final String MSG_BUTFORCEVIEW = Messages.getString("ChatLounge.butForceView");
+ private static final String MSG_CUSTOMMAPSIZE = Messages.getString("ChatLounge.CustomMapSize");
+ private static final String MSG_FILENOTFOUND = Messages.getString("ChatLounge.fileNotFound");
+ private static final String MSG_IMPROPERCOMMAND = Messages.getString("ChatLounge.ImproperCommand");
+ private static final String MSG_GAMEYEAR = Messages.getString("ChatLounge.GameYear");
+ private static final String MSG_IMDONE = Messages.getString("ChatLounge.imDone");
+ private static final String MSG_LABELSEARCH = Messages.getString("ChatLounge.labSearch");
+ private static final String MSG_LABELBOARDWIDTH = Messages.getString("ChatLounge.labBoardWidth");
+ private static final String MSG_LABELBOARDHEIGHT = Messages.getString("ChatLounge.labBoardHeight");
+ private static final String MSG_LABELBOARDSIZE = Messages.getString("ChatLounge.labBoardSize");
+ private static final String MSG_LABELMAPWIDTH = Messages.getString("ChatLounge.labMapWidth");
+ private static final String MSG_LABELMAPHEIGHT = Messages.getString("ChatLounge.labMapHeight");
+ private static final String MSG_MAPLOADSETUP = Messages.getString("ChatLounge.map.loadMapSetup");
+ private static final String MSG_MAPSUMMARY = Messages.getString("ChatLounge.MapSummary");
+ private static final String MSG_NAMESELECTUNITS = Messages.getString("ChatLounge.name.selectUnits");
+ private static final String MSG_NAMESELECTMAP = Messages.getString("ChatLounge.name.SelectMap");
+ private static final String MSG_NAMETEAMOVERVIEW = Messages.getString("ChatLounge.name.teamOverview");
+ private static final String MSG_NAMEUNITSETUP = Messages.getString("ChatLounge.name.unitSetup");
+ private static final String MSG_NAMEPLAYERSETUP = Messages.getString("ChatLounge.name.playerSetup");
+ private static final String MSG_NAMEGROUNDMAP = Messages.getString("ChatLounge.name.groundMap");
+ private static final String MSG_NAMEATMOSPHERICMAP = Messages.getString("ChatLounge.name.atmosphericMap");
+ private static final String MSG_NAMESPACEMAP = Messages.getString("ChatLounge.name.spaceMap");
+ private static final String MSG_NAMELOWALTITUDEMAP = Messages.getString("ChatLounge.name.lowAltitudeMap");
+ private static final String MSG_NAMEHIGHALTITUDEMAP = Messages.getString("ChatLounge.name.HighAltitudeMap");
+ private static final String MSG_NOCMDRTITLE = Messages.getString("ChatLounge.noCmdr.title");
+ private static final String MSG_NOCMDRMSG = Messages.getString("ChatLounge.noCmdr.msg");
+ private static final String MSG_NOTDONE = Messages.getString("ChatLounge.notDone");
+ private static final String MSG_OVERLAPDEPLOYTITLE = Messages.getString("ChatLounge.OverlapDeploy.title");
+ private static final String MSG_OVERLAPDEPLOYMSG = Messages.getString("ChatLounge.OverlapDeploy.msg");
+ private static final String MSG_PROBLEMLOADINGMAPSETUP = Messages.getString("ChatLounge.map.problemLoadMapSetup");
+ private static final String MSG_MAPPROBLEMSAVING = Messages.getString("ChatLounge.map.problemSaving");
+ private static final String MSG_MAPSUMMARYSELECTEDMAPS = Messages.getString("ChatLounge.MapSummarySelectedMaps");
+ private static final String MSG_MAPCONFIRMREPLACE = Messages.getString("ChatLounge.map.confirmReplace");
+ private static final String MSG_MAPSERVERSIDETIP = Messages.getString("ChatLounge.map.serverSideTip");
+ private static final String MSG_MAPSAVESETUPREPLACE = Messages.getString("ChatLounge.map.saveMapSetupReplace");
+ private static final String MSG_MAPSAVESETUP = Messages.getString("ChatLounge.map.saveMapSetup");
+ private static final String MSG_SELECTBOTORPLAYER = Messages.getString("ChatLounge.SelectBotOrPlayer");
+ private static final String MSG_MAPSEARCHTIP = Messages.getString("ChatLounge.map.searchTip");
+ private static final String MSG_MAPSAVESETUPTIP = Messages.getString("ChatLounge.map.saveMapSetupTip");
+ private static final String MSG_MAPTITLEMAPASSEMBLYHELP = Messages.getString("ChatLounge.map.title.mapAssemblyHelp");
+ private static final String MSG_TECHYEAR = Messages.getString("ChatLounge.TechLevel");
+ private static final String MSG_TOOLTIPTECHYEAR = Messages.getString("ChatLounge.tooltip.techYear");
+ private static final String MSG_TREEPATHMETHODREQUIRESENTITYFORCE = Messages.getString("ChatLounge.TreePath.methodRequiresEntityForce");
+ private static final String MSG_ABSTRACTHELPDIALOGNOHELPTITLE = Messages.getString("AbstractHelpDialog.noHelp.title");
+ private static final String MSG_ABSTRACTHELPDIALOGERRORREADING = Messages.getString("AbstractHelpDialog.errorReading");
+ private static final String MSG_BOARDEDITORCOULDNTINITIALIZE = Messages.getString("BoardEditor.CouldntInitialize");
+ private static final String MSG_BOARDEDITORFATALERROR = Messages.getString("BoardEditor.FatalError");
+ private static final String MSG_MAPSAVAILABLE = Messages.getString("BoardSelectionDialog.mapsAvailable");
+ private static final String MSG_VIEWGAMEBOARDTOOLTIP = Messages.getString("BoardSelectionDialog.ViewGameBoardTooltip");
+ private static final String MSG_VIEWGAMEBOARD = Messages.getString("BoardSelectionDialog.ViewGameBoard");
+ private static final String MSG_FIGHTERSQUADRONBOMBERROR = Messages.getString("FighterSquadron.bomberror");
+
/** Creates a new chat lounge for the clientgui.getClient(). */
public ChatLounge(ClientGUI clientgui) {
super(clientgui, SkinSpecification.UIComponents.ChatLounge.getComp(),
SkinSpecification.UIComponents.ChatLoungeDoneButton.getComp());
setLayout(new BorderLayout());
- panTabs.add("Select Units", panUnits);
- panTabs.add("Select Map", panMap);
- panTabs.add("Team Overview", panTeam);
- add(panTabs, BorderLayout.CENTER);
-
+ splitPaneMain = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
+ splitPaneMain.setDividerSize(15);
+ splitPaneMain.setResizeWeight(0.95);
+ JPanel p = new JPanel(new BorderLayout());
+ panTabs.add(MSG_NAMESELECTUNITS, panUnits);
+ panTabs.add(MSG_NAMESELECTMAP, panMap);
+ panTabs.add(MSG_NAMETEAMOVERVIEW, panTeam);
+ p.add(panTabs, BorderLayout.CENTER);
+ splitPaneMain.setTopComponent(p);
+ add(splitPaneMain);
+
setupSorters();
setupTeamOverview();
setupPlayerConfig();
@@ -273,6 +374,10 @@ public ChatLounge(ClientGUI clientgui) {
adaptToGUIScale();
setupListeners();
}
+
+ public void setBottom(JComponent comp) {
+ splitPaneMain.setBottomComponent(comp);
+ }
/** Sets up all the listeners that the lobby works with. */
private void setupListeners() {
@@ -405,7 +510,7 @@ private void setupTeamOverview() {
panTeam.add(panTeamOverview);
// setup (but don't show) the detached team overview window
- teamOverviewWindow = new ClientDialog(clientgui.frame, "Team Overview", false);
+ teamOverviewWindow = new ClientDialog(clientgui.frame, MSG_NAMETEAMOVERVIEW, false);
teamOverviewWindow.setSize(clientgui.frame.getWidth() / 2, clientgui.frame.getHeight() / 2);
}
@@ -413,7 +518,7 @@ private void setupTeamOverview() {
WindowListener teamOverviewWindowListener = new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
- int i = panTabs.indexOfTab("Team Overview");
+ int i = panTabs.indexOfTab(MSG_NAMETEAMOVERVIEW);
Component cp = panTabs.getComponentAt(i);
if (cp instanceof JPanel) {
((JPanel) cp).add(panTeamOverview);
@@ -486,15 +591,15 @@ private void setupUnitConfig() {
MechSummaryCache mechSummaryCache = MechSummaryCache.getInstance();
boolean mscLoaded = mechSummaryCache.isInitialized();
- butLoadList.setActionCommand("load_list");
+ butLoadList.setActionCommand(CL_ACTIONCOMMAND_LOADLIST);
butLoadList.setEnabled(mscLoaded);
- butSaveList.setActionCommand("save_list");
+ butSaveList.setActionCommand(CL_ACTIONCOMMAND_SAVELIST);
butSaveList.setEnabled(false);
butAdd.setEnabled(mscLoaded);
- butAdd.setActionCommand("load_mech");
+ butAdd.setActionCommand(CL_ACTIONCOMMAND_LOADMECH);
butArmy.setEnabled(mscLoaded);
- panUnitInfo.setBorder(BorderFactory.createTitledBorder(" Unit Setup "));
+ panUnitInfo.setBorder(BorderFactory.createTitledBorder(MSG_NAMEUNITSETUP));
panUnitInfo.setLayout(new BoxLayout(panUnitInfo, BoxLayout.PAGE_AXIS));
JPanel panUnitInfoAdd = new JPanel(new GridLayout(2, 1, 2, 2));
panUnitInfoAdd.setBorder(new EmptyBorder(0, 0, 2, 1));
@@ -514,20 +619,20 @@ private void setupUnitConfig() {
private void setupPlayerConfig() {
scrPlayers.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
- butAddBot.setActionCommand("add_bot");
+ butAddBot.setActionCommand(CL_ACTIONCOMMAND_ADDBOT);
butRemoveBot.setEnabled(false);
- butRemoveBot.setActionCommand("remove_bot");
+ butRemoveBot.setActionCommand(CL_ACTIONCOMMAND_REMOVEBOT);
butBotSettings.setEnabled(false);
- butBotSettings.setActionCommand("BOTCONFIG");
+ butBotSettings.setActionCommand(CL_ACTIONCOMMAND_BOTCONFIG);
butConfigPlayer.setEnabled(false);
- butConfigPlayer.setActionCommand("CONFIGURE");
+ butConfigPlayer.setActionCommand(CL_ACTIONCOMMAND_CONFIGURE);
setButUnitIDState();
setupTeamCombo();
- butCamo.setActionCommand("camo");
+ butCamo.setActionCommand(CL_ACTIONCOMMAND_CAMO);
refreshCamoButton();
panPlayerInfo = new FixedYPanel(new GridLayout(1, 2, 2, 2));
- panPlayerInfo.setBorder(BorderFactory.createTitledBorder("Player Setup"));
+ panPlayerInfo.setBorder(BorderFactory.createTitledBorder(MSG_NAMEPLAYERSETUP));
JPanel panPlayerInfoBts = new JPanel(new GridLayout(4, 1, 2, 2));
panPlayerInfoBts.add(comboTeam);
@@ -673,7 +778,7 @@ public void componentResized(ComponentEvent e) {
bottomPanel.add(butSaveMapSetup);
bottomPanel.add(butLoadMapSetup);
- butBoardPreview.setToolTipText(Messages.getString("BoardSelectionDialog.ViewGameBoardTooltip"));
+ butBoardPreview.setToolTipText(MSG_VIEWGAMEBOARDTOOLTIP);
// The left side panel including the game map preview
JPanel panMapPreview = new JPanel();
@@ -722,7 +827,7 @@ public void componentShown(ComponentEvent e) {
// setup the board preview window.
boardPreviewW = new ClientDialog(clientgui.frame,
- Messages.getString("BoardSelectionDialog.ViewGameBoard"),
+ MSG_VIEWGAMEBOARD,
false);
boardPreviewW.setLocationRelativeTo(clientgui.frame);
@@ -739,9 +844,8 @@ public void componentShown(ComponentEvent e) {
previewBV.zoomOut();
boardPreviewW.center();
} catch (IOException e) {
- JOptionPane.showMessageDialog(this,
- Messages.getString("BoardEditor.CouldntInitialize") + e,
- Messages.getString("BoardEditor.FatalError"), JOptionPane.ERROR_MESSAGE);
+ JOptionPane.showMessageDialog(this, MSG_BOARDEDITORCOULDNTINITIALIZE + e,
+ MSG_BOARDEDITORFATALERROR, JOptionPane.ERROR_MESSAGE);
}
refreshMapButtons();
}
@@ -858,7 +962,7 @@ private void refreshMapSizes() {
for (BoardDimensions size : mapSizes) {
comMapSizes.addItem(size);
}
- comMapSizes.addItem(Messages.getString("ChatLounge.CustomMapSize"));
+ comMapSizes.addItem(MSG_CUSTOMMAPSIZE);
comMapSizes.setSelectedIndex(oldSelection != -1 ? oldSelection : 0);
comMapSizes.addActionListener(lobbyListener);
}
@@ -870,7 +974,7 @@ private void refreshMapSizes() {
private void refreshMapUI() {
boolean inSpace = mapSettings.getMedium() == MapSettings.MEDIUM_SPACE;
boolean onGround = mapSettings.getMedium() == MapSettings.MEDIUM_GROUND;
- boolean customSize = comMapSizes.getSelectedItem().equals(Messages.getString("ChatLounge.CustomMapSize"));
+ boolean customSize = comMapSizes.getSelectedItem().equals(MSG_CUSTOMMAPSIZE);
lisBoardsAvailable.setEnabled(!inSpace);
mapIcons.clear();
butConditions.setEnabled(!inSpace);
@@ -939,7 +1043,7 @@ private void refreshBoardsAvailable() {
private void refreshBoardTags() {
boardTags.clear();
for (String boardName : mapSettings.getBoardsAvailableVector()) {
- File boardFile = new MegaMekFile(Configuration.boardsDir(), boardName + ".board").getFile();
+ File boardFile = new MegaMekFile(Configuration.boardsDir(), boardName + CL_KEY_FILEEXTENTION_BOARD).getFile();
Set tags = Board.getTags(boardFile);
boardTags.put(boardName, String.join("||", tags).toLowerCase());
}
@@ -1035,12 +1139,12 @@ private void refreshMapButtons() {
boardForImage = boardForImage.replace(Board.BOARD_REQUEST_ROTATION, "");
}
- File boardFile = new MegaMekFile(Configuration.boardsDir(), boardForImage + ".board").getFile();
+ File boardFile = new MegaMekFile(Configuration.boardsDir(), boardForImage + CL_KEY_FILEEXTENTION_BOARD).getFile();
if (boardFile.exists()) {
buttonBoard = new Board(16, 17);
- buttonBoard.load(new MegaMekFile(Configuration.boardsDir(), boardForImage + ".board").getFile());
+ buttonBoard.load(new MegaMekFile(Configuration.boardsDir(), boardForImage + CL_KEY_FILEEXTENTION_BOARD).getFile());
StringBuffer errs = new StringBuffer();
- try (InputStream is = new FileInputStream(new MegaMekFile(Configuration.boardsDir(), boardForImage + ".board").getFile())) {
+ try (InputStream is = new FileInputStream(new MegaMekFile(Configuration.boardsDir(), boardForImage +CL_KEY_FILEEXTENTION_BOARD).getFile())) {
buttonBoard.load(is, errs, true);
BoardUtilities.flip(buttonBoard, rotateBoard, rotateBoard);
} catch (IOException ex) {
@@ -1073,7 +1177,7 @@ private void refreshMapButtons() {
panMapButtons.setVisible(true);
lblBoardsAvailable.setText(mapSettings.getBoardWidth() + "x" + mapSettings.getBoardHeight() + " "
- + Messages.getString("BoardSelectionDialog.mapsAvailable"));
+ + MSG_MAPSAVAILABLE);
comMapSizes.removeActionListener(lobbyListener);
int items = comMapSizes.getItemCount();
@@ -1099,9 +1203,9 @@ private void markServerSideBoard(BufferedImage image) {
GUIPreferences.AntiAliasifSet(g);
int w = image.getWidth();
int h = image.getHeight();
- String text = "Server-side board";
+ String text = MSG_BOARDSEVERSIDB;
int fontSize = Math.min(w / 10, UIUtil.scaleForGUI(16));
- g.setFont(new Font("Dialog", Font.ITALIC, fontSize));
+ g.setFont(new Font(MMConstants.FONT_DIALOG, Font.ITALIC, fontSize));
FontMetrics fm = g.getFontMetrics(g.getFont());
int cx = (w - fm.stringWidth(text)) / 2;
int cy = h / 10 + fm.getAscent();
@@ -1151,7 +1255,7 @@ public Board getPossibleGameBoard(boolean onlyFixedBoards) {
name = name.substring(Board.BOARD_REQUEST_ROTATION.length());
}
- sheetBoards[i].load(new MegaMekFile(Configuration.boardsDir(), name + ".board").getFile());
+ sheetBoards[i].load(new MegaMekFile(Configuration.boardsDir(), name + CL_KEY_FILEEXTENTION_BOARD).getFile());
BoardUtilities.flip(sheetBoards[i], flipBoard, flipBoard);
}
}
@@ -1306,7 +1410,7 @@ private void refreshMapSettings() {
* condition.
*/
private void refreshDoneButton(boolean done) {
- butDone.setText(done ? Messages.getString("ChatLounge.notDone") : Messages.getString("ChatLounge.imDone"));
+ butDone.setText(done ? MSG_NOTDONE : MSG_IMDONE);
}
/** Refreshes the state of the Done button with the state of the local player. */
@@ -1336,8 +1440,8 @@ void loadOnto(Entity carried, int carrierId, int bayNumber) {
}
// We can't load all of the squadrons bombs
if (numLoadedBombs > ((IBomber) carried).getMaxBombPoints()) {
- JOptionPane.showMessageDialog(clientgui.frame, Messages.getString("FighterSquadron.bomberror"),
- Messages.getString("FighterSquadron.error"), JOptionPane.ERROR_MESSAGE);
+ JOptionPane.showMessageDialog(clientgui.frame, MSG_FIGHTERSQUADRONBOMBERROR,
+ MSG_FIGHTERSQUADRONBOMBERROR, JOptionPane.ERROR_MESSAGE);
return;
}
}
@@ -1655,7 +1759,7 @@ public void gamePhaseChange(GamePhaseChangeEvent e) {
return;
}
- if (clientgui.getClient().getGame().getPhase() == GamePhase.LOUNGE) {
+ if (clientgui.getClient().getGame().getPhase().isLounge()) {
refreshDoneButton();
refreshGameSettings();
refreshPlayerTable();
@@ -1737,8 +1841,7 @@ public void actionPerformed(ActionEvent ev) {
// list of entities with a list from a file.
Client c = getSelectedClient();
if (c == null) {
- clientgui.doAlertDialog(Messages.getString("ChatLounge.ImproperCommand"),
- Messages.getString("ChatLounge.SelectBotOrPlayer"));
+ clientgui.doAlertDialog(MSG_IMPROPERCOMMAND, MSG_SELECTBOTORPLAYER);
return;
}
clientgui.loadListFile(c.getLocalPlayer());
@@ -1748,8 +1851,7 @@ public void actionPerformed(ActionEvent ev) {
// list of entities to a file.
Client c = getSelectedClient();
if (c == null) {
- clientgui.doAlertDialog(Messages.getString("ChatLounge.ImproperCommand"),
- Messages.getString("ChatLounge.SelectBotOrPlayer"));
+ clientgui.doAlertDialog(MSG_IMPROPERCOMMAND, MSG_SELECTBOTORPLAYER);
return;
}
clientgui.saveListFile(c.getGame().getPlayerEntities(c.getLocalPlayer(), false),
@@ -1781,7 +1883,7 @@ public void actionPerformed(ActionEvent ev) {
previewGameBoard();
} else if (ev.getSource().equals(comMapSizes)) {
- if (comMapSizes.getSelectedItem().equals(Messages.getString("ChatLounge.CustomMapSize"))) {
+ if (comMapSizes.getSelectedItem().equals(MSG_CUSTOMMAPSIZE)) {
refreshMapUI();
} else if (comMapSizes.getSelectedItem() != null) {
BoardDimensions size = (BoardDimensions) comMapSizes.getSelectedItem();
@@ -1863,13 +1965,13 @@ public void actionPerformed(ActionEvent ev) {
fldSearch.setText("");
} else if (ev.getSource() == butHelp) {
- File helpfile = new File("docs/Boards Stuff/MapAssemblyHelp.html");
- final JDialog dialog = new ClientDialog(clientgui.frame, "Map Assembly Help", true, true);
+ File helpfile = new File(CL_KEY_FILEPATH_MAPASSEMBLYHELP);
+ final JDialog dialog = new ClientDialog(clientgui.frame, MSG_MAPTITLEMAPASSEMBLYHELP, true, true);
final int height = 600;
final int width = 600;
final JEditorPane pane = new JEditorPane();
- pane.setName("helpPane");
+ pane.setName(CL_KEY_NAMEHELPPANE);
pane.setEditable(false);
pane.setFont(UIUtil.getScaledFont());
try {
@@ -1880,12 +1982,12 @@ public void actionPerformed(ActionEvent ev) {
tScroll.getVerticalScrollBar().setUnitIncrement(16);
dialog.add(tScroll, BorderLayout.CENTER);
} catch (Exception e) {
- dialog.setTitle(Messages.getString("AbstractHelpDialog.noHelp.title"));
- pane.setText(Messages.getString("AbstractHelpDialog.errorReading") + e.getMessage());
+ dialog.setTitle(MSG_ABSTRACTHELPDIALOGNOHELPTITLE);
+ pane.setText(MSG_ABSTRACTHELPDIALOGERRORREADING + e.getMessage());
LogManager.getLogger().error("", e);
}
- JButton button = new DialogButton(Messages.getString("Okay"));
+ JButton button = new DialogButton(MSG_OKAY);
button.addActionListener(e -> dialog.setVisible(false));
JPanel okayPanel = new JPanel(new FlowLayout());
okayPanel.add(button);
@@ -1948,8 +2050,7 @@ private void configAndCreateBot(@Nullable Player toReplace) {
botClient.connect();
clientgui.getBots().put(bcd.getBotName(), botClient);
} catch (Exception e) {
- clientgui.doAlertDialog(Messages.getString("ChatLounge.AlertBot.title"),
- Messages.getString("ChatLounge.AlertBot.message"));
+ clientgui.doAlertDialog(MSG_ALERTBOTTITLE, MSG_ALERTBOTMESSAGE);
botClient.die();
}
}
@@ -1961,8 +2062,8 @@ private void configAndCreateBot(@Nullable Player toReplace) {
* @see MapSetup
*/
private void saveMapSetup() {
- JFileChooser fc = new JFileChooser(Configuration.dataDir() + "/mapsetup");
- fc.setDialogTitle(Messages.getString("ChatLounge.map.saveMapSetup"));
+ JFileChooser fc = new JFileChooser(Configuration.dataDir() + CL_KEY_FILEPATH_MAPSETUP);
+ fc.setDialogTitle(MSG_MAPSAVESETUP);
fc.setMultiSelectionEnabled(false);
fc.setAcceptAllFileFilterUsed(false);
fc.setFileFilter(XMLFileFilter);
@@ -1972,20 +2073,19 @@ private void saveMapSetup() {
if ((returnVal != JFileChooser.APPROVE_OPTION) || (selectedFile == null)) {
return;
}
- if (!selectedFile.getName().toLowerCase().endsWith(".xml")) {
- selectedFile = new File(selectedFile.getPath() + ".xml");
+ if (!selectedFile.getName().toLowerCase().endsWith(CL_KEY_FILEEXTENTION_XML)) {
+ selectedFile = new File(selectedFile.getPath() + CL_KEY_FILEEXTENTION_XML);
}
if (selectedFile.exists()) {
- String msg = Messages.getString("ChatLounge.map.saveMapSetupReplace", selectedFile.getName());
- if (!MMConfirmDialog.confirm(clientgui.frame, "Confirm replace", msg)) {
+ String msg = Messages.getFormattedString(MSG_MAPSAVESETUPREPLACE, selectedFile.getName());
+ if (!MMConfirmDialog.confirm(clientgui.frame, MSG_MAPCONFIRMREPLACE, msg)) {
return;
}
}
try (OutputStream os = new FileOutputStream(selectedFile)) {
MapSetup.save(os, mapSettings);
} catch (Exception ex) {
- JOptionPane.showMessageDialog(clientgui.frame,
- "There was a problem while saving the map setup!", "Error", JOptionPane.ERROR_MESSAGE);
+ JOptionPane.showMessageDialog(clientgui.frame, MSG_MAPPROBLEMSAVING, MSG_ERROR, JOptionPane.ERROR_MESSAGE);
LogManager.getLogger().error("", ex);
}
}
@@ -1996,8 +2096,8 @@ private void saveMapSetup() {
* @see MapSetup
*/
private void loadMapSetup() {
- JFileChooser fc = new JFileChooser(Configuration.dataDir() + "/mapsetup");
- fc.setDialogTitle(Messages.getString("ChatLounge.map.loadMapSetup"));
+ JFileChooser fc = new JFileChooser(Configuration.dataDir() + CL_KEY_FILEPATH_MAPSETUP);
+ fc.setDialogTitle(MSG_MAPLOADSETUP);
fc.setMultiSelectionEnabled(false);
fc.setAcceptAllFileFilterUsed(false);
fc.setFileFilter(XMLFileFilter);
@@ -2007,7 +2107,7 @@ private void loadMapSetup() {
return;
}
if (!fc.getSelectedFile().exists()) {
- JOptionPane.showMessageDialog(clientgui.frame, "File not found.");
+ JOptionPane.showMessageDialog(clientgui.frame, MSG_FILENOTFOUND);
return;
}
try (InputStream os = new FileInputStream(fc.getSelectedFile())) {
@@ -2017,8 +2117,8 @@ private void loadMapSetup() {
mapSettings.setBoardsSelectedVector(setup.getBoards());
clientgui.getClient().sendMapSettings(mapSettings);
} catch (Exception ex) {
- JOptionPane.showMessageDialog(clientgui.frame,
- "There was a problem while loading the map setup!", "Error", JOptionPane.ERROR_MESSAGE);
+ JOptionPane.showMessageDialog(clientgui.frame,
+ MSG_PROBLEMLOADINGMAPSETUP, MSG_ERROR, JOptionPane.ERROR_MESSAGE);
LogManager.getLogger().error("", ex);
}
}
@@ -2049,7 +2149,7 @@ private void doBotSettings() {
FileFilter XMLFileFilter = new FileFilter() {
@Override
public boolean accept(File f) {
- return (f.getPath().toLowerCase().endsWith(".xml") || f.isDirectory());
+ return (f.getPath().toLowerCase().endsWith(CL_KEY_FILEEXTENTION_XML) || f.isDirectory());
}
@Override
@@ -2124,39 +2224,35 @@ public void updateMapSettings(MapSettings newSettings) {
/**OK Refreshes the Map Summary, Tech Level and Game Year labels. */
private void refreshLabels() {
- Font scaledFont = UIUtil.getScaledFont();
GameOptions opts = clientgui.getClient().getGame().getOptions();
- String txt = Messages.getString("ChatLounge.GameYear");
+ String txt = MSG_GAMEYEAR;
txt += opts.intOption(OptionsConstants.ALLOWED_YEAR);
lblGameYear.setText(txt);
- lblGameYear.setFont(scaledFont);
- lblGameYear.setToolTipText(scaleStringForGUI(Messages.getString("ChatLounge.tooltip.techYear")));
+ lblGameYear.setToolTipText(scaleStringForGUI(MSG_TOOLTIPTECHYEAR));
String tlString = TechConstants.getLevelDisplayableName(TechConstants.T_TECH_UNKNOWN);
IOption tlOpt = opts.getOption(OptionsConstants.ALLOWED_TECHLEVEL);
if (tlOpt != null) {
tlString = tlOpt.stringValue();
}
- lblTechLevel.setText(Messages.getString("ChatLounge.TechLevel") + tlString);
- lblTechLevel.setFont(scaledFont);
- lblTechLevel.setToolTipText(scaleStringForGUI(Messages.getString("ChatLounge.tooltip.techYear")));
+ lblTechLevel.setText(MSG_TECHYEAR + tlString);
+ lblTechLevel.setToolTipText(scaleStringForGUI(MSG_TOOLTIPTECHYEAR));
- txt = Messages.getString("ChatLounge.MapSummary");
+ txt = MSG_MAPSUMMARY;
txt += (mapSettings.getBoardWidth() * mapSettings.getMapWidth()) + " x "
+ (mapSettings.getBoardHeight() * mapSettings.getMapHeight());
if (butGroundMap.isSelected()) {
- txt += " Ground Map";
+ txt += MSG_NAMEGROUNDMAP;
} else if (butLowAtmoMap.isSelected()) {
- txt += " Atmospheric Map";
+ txt += " " + MSG_NAMEATMOSPHERICMAP;
} else {
- txt += " Space Map";
+ txt += " " + MSG_NAMESPACEMAP;
}
lblMapSummary.setText(txt);
- lblMapSummary.setFont(scaledFont);
StringBuilder selectedMaps = new StringBuilder();
- selectedMaps.append(Messages.getString("ChatLounge.MapSummarySelectedMaps"));
+ selectedMaps.append(MSG_MAPSUMMARYSELECTEDMAPS);
for (String map: mapSettings.getBoardsSelectedVector()) {
selectedMaps.append(" ");
if (map.startsWith(MapSettings.BOARD_SURPRISE)) {
@@ -2178,8 +2274,7 @@ public void ready() {
// enforce exclusive deployment zones in double blind
for (Player player: client.getGame().getPlayersVector()) {
if (!isValidStartPos(game, player)) {
- clientgui.doAlertDialog(Messages.getString("ChatLounge.OverlapDeploy.title"),
- Messages.getString("ChatLounge.OverlapDeploy.msg"));
+ clientgui.doAlertDialog(MSG_OVERLAPDEPLOYTITLE, MSG_OVERLAPDEPLOYMSG);
return;
}
}
@@ -2200,8 +2295,8 @@ public void ready() {
}
if (!players.isEmpty()) {
- String title = Messages.getString("ChatLounge.noCmdr.title");
- String msg = Messages.getString("ChatLounge.noCmdr.msg");
+ String title = MSG_NOCMDRTITLE;
+ String msg = MSG_NOCMDRMSG;
for (String player : players) {
msg += player + "\n";
}
@@ -2944,7 +3039,7 @@ private TreePath getPath(Object outdatedEntry) {
pathObjs[index++] = game().getEntity(entityId);
return new TreePath(pathObjs);
} else {
- throw new IllegalArgumentException("Method requires Entity or Force object.");
+ throw new IllegalArgumentException(MSG_TREEPATHMETHODREQUIRESENTITYFORCE);
}
}
@@ -3064,69 +3159,23 @@ private void setColumnWidth(TableColumn column) {
/** Adapts the whole Lobby UI (both panels) to the current guiScale. */
private void adaptToGUIScale() {
updateTableHeaders();
- setTableRowHeights();
refreshLabels();
refreshCamoButton();
refreshMapButtons();
mekModel.refreshCells();
- panTeamOverview.adaptToGUIScale();
Font scaledFont = UIUtil.getScaledFont();
- Font scaledBigFont = new Font("Dialog", Font.PLAIN, UIUtil.scaleForGUI(UIUtil.FONT_SCALE1 + 3));
-
- butCompact.setFont(scaledFont);
- butOptions.setFont(scaledBigFont);
- butLoadList.setFont(scaledFont);
- butSaveList.setFont(scaledFont);
- butSkills.setFont(scaledFont);
- butNames.setFont(scaledFont);
- butAddBot.setFont(scaledFont);
- butRemoveBot.setFont(scaledFont);
- butConfigPlayer.setFont(scaledFont);
- butBotSettings.setFont(scaledFont);
- butShowUnitID.setFont(scaledFont);
- butConditions.setFont(scaledFont);
- butRandomMap.setFont(scaledFont);
- butSpaceSize.setFont(scaledFont);
- butBoardPreview.setFont(scaledFont);
- butAddX.setFont(scaledFont);
- butAddY.setFont(scaledFont);
- comMapSizes.setFont(scaledFont);
- comboTeam.setFont(scaledFont);
- lblBoardsAvailable.setFont(scaledFont);
- lblMapWidth.setFont(scaledFont);
- butMapGrowW.setFont(scaledFont);
- butMapShrinkW.setFont(scaledFont);
- fldMapWidth.setFont(scaledFont);
- lblMapHeight.setFont(scaledFont);
- butMapGrowH.setFont(scaledFont);
- butMapShrinkH.setFont(scaledFont);
- fldMapHeight.setFont(scaledFont);
- lblSpaceBoardWidth.setFont(scaledFont);
- lblSpaceBoardHeight.setFont(scaledFont);
- fldSpaceBoardWidth.setFont(scaledFont);
- fldSpaceBoardHeight.setFont(scaledFont);
- butGroundMap.setFont(scaledFont);
- butLowAtmoMap.setFont(scaledFont);
- butHighAtmoMap.setFont(scaledFont);
- butSpaceMap.setFont(scaledFont);
- lblBoardSize.setFont(scaledFont);
- butSaveMapSetup.setFont(scaledFont);
- butLoadMapSetup.setFont(scaledFont);
- butDetach.setFont(scaledFont);
- butCancelSearch.setFont(scaledFont);
- butListView.setFont(scaledFont);
- butForceView.setFont(scaledFont);
- butCollapse.setFont(scaledFont);
- butExpand.setFont(scaledFont);
-
- butAdd.setFont(scaledBigFont);
- butArmy.setFont(scaledBigFont);
- panTabs.setFont(scaledBigFont);
-
- lblSearch.setFont(scaledFont);
- fldSearch.setFont(scaledFont);
- String searchTip = Messages.getString("ChatLounge.map.searchTip") + " ";
+
+ UIUtil.adjustContainer(splitPaneMain, UIUtil.FONT_SCALE1);
+ UIUtil.scaleComp(butDone, UIUtil.FONT_SCALE2);
+ UIUtil.scaleComp(butOptions, UIUtil.FONT_SCALE2);
+ UIUtil.scaleComp(butAdd, UIUtil.FONT_SCALE2);
+ UIUtil.scaleComp(butArmy, UIUtil.FONT_SCALE2);
+
+
+ setTableRowHeights();
+
+ String searchTip = MSG_MAPSEARCHTIP + " ";
searchTip += autoTagHTMLTable();
fldSearch.setToolTipText(UIUtil.scaleStringForGUI(searchTip));
@@ -3136,10 +3185,10 @@ private void adaptToGUIScale() {
int scaledBorder = UIUtil.scaleForGUI(TEAMOVERVIEW_BORDER);
panTeam.setBorder(new EmptyBorder(scaledBorder, scaledBorder, scaledBorder, scaledBorder));
- butBoardPreview.setToolTipText(scaleMessageForGUI("BoardSelectionDialog.ViewGameBoardTooltip"));
- butSaveMapSetup.setToolTipText(scaleMessageForGUI("ChatLounge.map.saveMapSetupTip"));
-
- Font scaledHelpFont = new Font("Dialog", Font.PLAIN, UIUtil.scaleForGUI(UIUtil.FONT_SCALE1 + 33));
+ butBoardPreview.setToolTipText(scaleStringForGUI(MSG_VIEWGAMEBOARDTOOLTIP));
+ butSaveMapSetup.setToolTipText(scaleStringForGUI(MSG_MAPSAVESETUPTIP));
+
+ Font scaledHelpFont = new Font(MMConstants.FONT_DIALOG, Font.PLAIN, UIUtil.scaleForGUI(UIUtil.FONT_SCALE1 + 33));
butHelp.setFont(scaledHelpFont);
// Makes a new tooltip appear immediately (rescaled and possibly for a different unit)
@@ -3181,10 +3230,8 @@ private String autoTagHTMLTable() {
* Saves column widths of the Mek Table when the mouse button is released.
* Also switches between table sorting types
*/
- MouseListener mekTableHeaderMouseListener = new MouseAdapter()
- {
- private void changeSorter(MouseEvent e)
- {
+ MouseListener mekTableHeaderMouseListener = new MouseAdapter() {
+ private void changeSorter(MouseEvent e) {
// Save table widths
for (int i = 0; i < MekTableModel.N_COL; i++) {
TableColumn column = mekTable.getColumnModel().getColumn(i);
@@ -3230,7 +3277,6 @@ private void sorterPopup(MouseEvent e) {
}
popup.show(e.getComponent(), e.getX(), e.getY());
}
-
};
/**
@@ -3313,7 +3359,6 @@ private void redrawMapTable(Image image) {
lisBoardsAvailable.repaint();
}
}
-
class ImageLoader extends SwingWorker {
@@ -3330,7 +3375,7 @@ private synchronized void add(String name) {
}
private Image prepareImage(String boardName) {
- File boardFile = new MegaMekFile(Configuration.boardsDir(), boardName + ".board").getFile();
+ File boardFile = new MegaMekFile(Configuration.boardsDir(), boardName + CL_KEY_FILEEXTENTION_BOARD).getFile();
Board board;
StringBuffer errs = new StringBuffer();
if (boardFile.exists()) {
@@ -3425,7 +3470,7 @@ public Component getListCellRendererComponent(JList> list, Object value,
String board = (String) value;
// For generated boards, add the size to have different images for different sizes
if (board.startsWith(MapSettings.BOARD_GENERATED)) {
- board += mapSettings.getBoardSize().toString();
+ board += mapSettings.getBoardSize();
}
// If the gui scaling has changed, clear out all images, triggering a reload
@@ -3595,9 +3640,9 @@ private boolean hasSpecialBoard(String boardName, Collection list) {
String createBoardTooltip(String boardName) {
String result = "";
if (boardName.startsWith(MapSettings.BOARD_GENERATED)) {
- result = "This board is generated using the current Generated Map Settings when the game is started.";
+ result = MSG_BOARDGENERATEDMESSAGE;
} else if (boardName.startsWith(MapSettings.BOARD_SURPRISE)) {
- result = "This board is selected randomly from the following list of boards when the game is started: ";
+ result = MSG_BOARDRANDOMLYSELECTEDMESSAGE;
result += boardName.substring(MapSettings.BOARD_SURPRISE.length()).replace("\n", " ");
} else {
result = boardName;
@@ -3606,7 +3651,7 @@ String createBoardTooltip(String boardName) {
result += invalidBoardTip();
}
if (hasServerSideBoard(boardName)) {
- result += Messages.getString("ChatLounge.map.serverSideTip");
+ result += MSG_MAPSERVERSIDETIP;
}
return result;
}
diff --git a/megamek/src/megamek/client/ui/swing/lobby/LobbyUtility.java b/megamek/src/megamek/client/ui/swing/lobby/LobbyUtility.java
index eb192bf68cb..f7749f40e9e 100644
--- a/megamek/src/megamek/client/ui/swing/lobby/LobbyUtility.java
+++ b/megamek/src/megamek/client/ui/swing/lobby/LobbyUtility.java
@@ -18,18 +18,7 @@
*/
package megamek.client.ui.swing.lobby;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.StringTokenizer;
-
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.util.UIUtil;
@@ -38,6 +27,10 @@
import megamek.common.options.GameOptions;
import megamek.common.options.OptionsConstants;
+import java.awt.*;
+import java.io.File;
+import java.util.*;
+
/**
* This class provides static helper functions for the Lobby aka ChatLounge.
* @author Simon
@@ -153,7 +146,7 @@ static void drawMinimapLabel(String text, int w, int h, Graphics g, boolean inva
// The text size may grow with the width of the image, but no bigger than 16*guiscale
// to avoid huge text
int fontSize = Math.min(w / 10, UIUtil.scaleForGUI(16));
- Font font = new Font("Dialog", Font.PLAIN, fontSize);
+ Font font = new Font(MMConstants.FONT_DIALOG, Font.PLAIN, fontSize);
g.setFont(font);
FontMetrics fm = g.getFontMetrics(font);
int th = fm.getAscent() + fm.getDescent(); // The text height
diff --git a/megamek/src/megamek/client/ui/swing/lobby/MapPreviewButton.java b/megamek/src/megamek/client/ui/swing/lobby/MapPreviewButton.java
index 873392de7f6..0e0fe5b16ed 100644
--- a/megamek/src/megamek/client/ui/swing/lobby/MapPreviewButton.java
+++ b/megamek/src/megamek/client/ui/swing/lobby/MapPreviewButton.java
@@ -18,6 +18,7 @@
*/
package megamek.client.ui.swing.lobby;
+import megamek.MMConstants;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.util.UIUtil;
import megamek.common.MapSettings;
@@ -189,7 +190,7 @@ private void drawIndex(Graphics g, int w, int h) {
String text = Integer.toString(index + 1);
int fontSize = Math.min(w, h) / 4;
fontSize = Math.min(fontSize, UIUtil.scaleForGUI(45));
- g.setFont(new Font("Dialog", Font.PLAIN, fontSize));
+ g.setFont(new Font(MMConstants.FONT_DIALOG, Font.PLAIN, fontSize));
FontMetrics fm = g.getFontMetrics(g.getFont());
int cx = (w - fm.stringWidth(text)) / 2;
int cy = (h + fm.getAscent() - fm.getDescent()) / 2;
@@ -200,7 +201,7 @@ private void drawIndex(Graphics g, int w, int h) {
private void drawExample(Graphics g, int w, int h) {
String text = "Example board";
int fontSize = Math.min(w / 10, UIUtil.scaleForGUI(25));
- g.setFont(new Font("Dialog", Font.ITALIC, fontSize));
+ g.setFont(new Font(MMConstants.FONT_DIALOG, Font.ITALIC, fontSize));
FontMetrics fm = g.getFontMetrics(g.getFont());
int cx = (w - fm.stringWidth(text)) / 2;
int cy = h / 10 + fm.getAscent();
diff --git a/megamek/src/megamek/client/ui/swing/lobby/MekForceTreeRenderer.java b/megamek/src/megamek/client/ui/swing/lobby/MekForceTreeRenderer.java
index fddc4fe7b00..0a344d70165 100644
--- a/megamek/src/megamek/client/ui/swing/lobby/MekForceTreeRenderer.java
+++ b/megamek/src/megamek/client/ui/swing/lobby/MekForceTreeRenderer.java
@@ -18,6 +18,7 @@
*/
package megamek.client.ui.swing.lobby;
+import megamek.MMConstants;
import megamek.client.ui.swing.tooltip.UnitToolTip;
import megamek.client.ui.swing.util.UIUtil;
import megamek.common.Configuration;
@@ -69,7 +70,7 @@ public Component getTreeCellRendererComponent(JTree tree, Object value, boolean
}
if (value instanceof Entity) {
- Font scaledFont = new Font("Dialog", Font.PLAIN, UIUtil.scaleForGUI(UIUtil.FONT_SCALE1));
+ Font scaledFont = new Font(MMConstants.FONT_DIALOG, Font.PLAIN, UIUtil.scaleForGUI(UIUtil.FONT_SCALE1));
setFont(scaledFont);
entity = (Entity) value;
this.row = row;
@@ -95,7 +96,7 @@ public Component getTreeCellRendererComponent(JTree tree, Object value, boolean
}
} else if (value instanceof Force) {
entity = null;
- Font scaledFont = new Font("Dialog", Font.PLAIN, UIUtil.scaleForGUI(UIUtil.FONT_SCALE1 + 3));
+ Font scaledFont = new Font(MMConstants.FONT_DIALOG, Font.PLAIN, UIUtil.scaleForGUI(UIUtil.FONT_SCALE1 + 3));
setFont(scaledFont);
Force force = (Force) value;
if (lobby.isCompact()) {
diff --git a/megamek/src/megamek/client/ui/swing/lobby/MekTableModel.java b/megamek/src/megamek/client/ui/swing/lobby/MekTableModel.java
index f2350aed68e..68c423a0be6 100644
--- a/megamek/src/megamek/client/ui/swing/lobby/MekTableModel.java
+++ b/megamek/src/megamek/client/ui/swing/lobby/MekTableModel.java
@@ -241,6 +241,10 @@ private Player ownerOf(Entity entity) {
/** Creates and returns the display content of the "Player" column for the given entity. */
private String playerCellContent(final Entity entity) {
+ if (entity == null) {
+ return "";
+ }
+
StringBuilder result = new StringBuilder("");
Player owner = ownerOf(entity);
boolean isEnemy = clientGui.getClient().getLocalPlayer().isEnemyOf(owner);
diff --git a/megamek/src/megamek/client/ui/swing/lobby/PlayerSettingsDialog.java b/megamek/src/megamek/client/ui/swing/lobby/PlayerSettingsDialog.java
index b604616d70d..f7374d79502 100644
--- a/megamek/src/megamek/client/ui/swing/lobby/PlayerSettingsDialog.java
+++ b/megamek/src/megamek/client/ui/swing/lobby/PlayerSettingsDialog.java
@@ -70,12 +70,13 @@ public PlayerSettingsDialog(ClientGUI cg, Client cl) {
numFormatter.setMinimum(0);
numFormatter.setCommitsOnValidEdit(true);
+
initialize();
}
@Override
protected void finalizeInitialization() throws Exception {
- UIUtil.adjustDialog(this);
+ adaptToGUIScale();
super.finalizeInitialization();
}
@@ -416,5 +417,7 @@ private int parseField(JTextField field) {
return 0;
}
}
-
+ private void adaptToGUIScale() {
+ UIUtil.adjustDialog(this, UIUtil.FONT_SCALE1);
+ }
}
diff --git a/megamek/src/megamek/client/ui/swing/lobby/TeamOverviewPanel.java b/megamek/src/megamek/client/ui/swing/lobby/TeamOverviewPanel.java
index 031a0692ee1..873664c679b 100644
--- a/megamek/src/megamek/client/ui/swing/lobby/TeamOverviewPanel.java
+++ b/megamek/src/megamek/client/ui/swing/lobby/TeamOverviewPanel.java
@@ -18,6 +18,7 @@
*/
package megamek.client.ui.swing.lobby;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.ClientGUI;
import megamek.client.ui.swing.GUIPreferences;
@@ -77,8 +78,7 @@ public TeamOverviewPanel(ClientGUI cg) {
colModel.getColumn(TOMCOLS.HIDDEN.ordinal()).setCellRenderer(centerRenderer);
scrTeams.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
add(scrTeams);
-
- adaptToGUIScale();
+
refreshData();
}
@@ -124,12 +124,6 @@ public void mouseReleased(MouseEvent e) {
}
};
- /** Adapts the row heights and headers to the current GUI scaling. */
- public void adaptToGUIScale() {
- teamOverviewModel.updateRowHeights();
- refreshTableHeader();
- }
-
/** Refreshes the headers, setting the header names and gui scaling them. */
public void refreshTableHeader() {
JTableHeader header = teamOverviewTable.getTableHeader();
@@ -422,7 +416,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole
Vector> playerList = (Vector>) value;
int baseSize = FONT_SCALE1 - (isDetached ? 2 : 0);
int size = scaleForGUI(2 * baseSize);
- Font font = new Font("Dialog", Font.PLAIN, scaleForGUI(baseSize));
+ Font font = new Font(MMConstants.FONT_DIALOG, Font.PLAIN, scaleForGUI(baseSize));
for (Object obj: playerList) {
if (!(obj instanceof Player)) {
continue;
diff --git a/megamek/src/megamek/client/ui/swing/minimap/Minimap.java b/megamek/src/megamek/client/ui/swing/minimap/Minimap.java
index 963cf161d57..59bdb212b50 100644
--- a/megamek/src/megamek/client/ui/swing/minimap/Minimap.java
+++ b/megamek/src/megamek/client/ui/swing/minimap/Minimap.java
@@ -20,6 +20,7 @@
*/
package megamek.client.ui.swing.minimap;
+import megamek.MMConstants;
import megamek.client.Client;
import megamek.client.event.BoardViewEvent;
import megamek.client.event.BoardViewListener;
@@ -33,7 +34,6 @@
import megamek.common.actions.EntityAction;
import megamek.common.actions.WeaponAttackAction;
import megamek.common.annotations.Nullable;
-import megamek.common.enums.GamePhase;
import megamek.common.event.*;
import megamek.common.preference.IPreferenceChangeListener;
import megamek.common.preference.PreferenceChangeEvent;
@@ -509,7 +509,7 @@ private synchronized void drawMap(boolean forceDraw) {
}
addRoadElements(h, j, k);
// Color invalid hexes red when in the Map Editor
- if ((game != null) && (game.getPhase() == GamePhase.UNKNOWN) && !h.isValid(null)) {
+ if ((game != null) && game.getPhase().isUnknown() && !h.isValid(null)) {
gg.setColor(GUIPreferences.getInstance().getWarningColor());
paintCoord(gg, j, k, true);
}
@@ -570,8 +570,7 @@ private synchronized void drawMap(boolean forceDraw) {
/** Indicates the deployment hexes. */
private void drawDeploymentZone(Graphics g) {
- if ((null != client) && (null != game)
- && (GamePhase.DEPLOYMENT == game.getPhase()) && (dialog != null)
+ if ((null != client) && (null != game) && game.getPhase().isDeployment() && (dialog != null)
&& (bv.getDeployingEntity() != null)) {
GameTurn turn = game.getTurn();
if ((turn != null) && (turn.getPlayerNum() == client.getLocalPlayer().getId())) {
@@ -896,7 +895,7 @@ private void paintUnit(Graphics g, Entity entity) {
if (EntityVisibilityUtils.onlyDetectedBySensors(bv.getLocalPlayer(), entity)) {
// This unit is visible only as a sensor Return
String sensorReturn = "?";
- Font font = new Font("SansSerif", Font.BOLD, FONT_SIZE[zoom]);
+ Font font = new Font(MMConstants.FONT_SANS_SERIF, Font.BOLD, FONT_SIZE[zoom]);
int width = getFontMetrics(font).stringWidth(sensorReturn) / 2;
int height = getFontMetrics(font).getHeight() / 2 - 2;
g.setFont(font);
@@ -940,14 +939,12 @@ private void paintUnit(Graphics g, Entity entity) {
Path2D form = MinimapUnitSymbols.getForm(entity);
- Color borderColor = Color.WHITE;
+ Color borderColor = entity.moved != EntityMovementType.MOVE_NONE ? Color.BLACK : Color.WHITE;
Color fontColor = Color.BLACK;
- if (entity.moved != EntityMovementType.MOVE_NONE) {
- borderColor = Color.BLACK;
- }
-
+
float outerBorderWidth = 30f;
- float innerBorderWidth = 20f;
+ float innerBorderWidth = 10f;
+ float formStrokeWidth = 20f;
if (stratOpsSymbols) {
// White border to set off the icon from the background
@@ -959,15 +956,12 @@ private void paintUnit(Graphics g, Entity entity) {
g2.setColor(fontColor);
g2.fill(STRAT_BASERECT);
- // Rectangle border for all units
- g2.setColor(borderColor);
- g2.setStroke(new BasicStroke(innerBorderWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
- g2.draw(STRAT_BASERECT);
-
// Set a thin brush for filled areas (leave a thick brush for line symbols
if ((entity instanceof Mech) || (entity instanceof Protomech)
|| (entity instanceof VTOL) || (entity.isAero())) {
g2.setStroke(new BasicStroke(1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
+ } else {
+ g2.setStroke(new BasicStroke(formStrokeWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
}
// Fill the form in player color / team color
@@ -987,7 +981,7 @@ private void paintUnit(Graphics g, Entity entity) {
}
if (!s.isBlank()) {
var fontContext = new FontRenderContext(null, true, true);
- var font = new Font("SansSerif", Font.BOLD, 100);
+ var font = new Font(MMConstants.FONT_SANS_SERIF, Font.BOLD, 100);
FontMetrics currentMetrics = getFontMetrics(font);
int stringWidth = currentMetrics.stringWidth(s);
GlyphVector gv = font.createGlyphVector(fontContext, s);
@@ -1001,6 +995,11 @@ private void paintUnit(Graphics g, Entity entity) {
// Draw the unit icon in black
g2.draw(form);
+ // Rectangle border for all units
+ g2.setColor(borderColor);
+ g2.setStroke(new BasicStroke(innerBorderWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
+ g2.draw(STRAT_BASERECT);
+
} else {
// Standard symbols
// White border to set off the icon from the background
@@ -1343,10 +1342,11 @@ public void boardChangedHex(BoardEvent b) {
private final GameListener gameListener = new GameListenerAdapter() {
@Override
public void gamePhaseChange(GamePhaseChangeEvent e) {
- if (GUIPreferences.getInstance().getGameSummaryMinimap() && ((e.getOldPhase() == GamePhase.DEPLOYMENT)
- || (e.getOldPhase() == GamePhase.MOVEMENT) || (e.getOldPhase() == GamePhase.TARGETING)
- || (e.getOldPhase() == GamePhase.PREMOVEMENT) || (e.getOldPhase() == GamePhase.PREFIRING)
- || (e.getOldPhase() == GamePhase.FIRING) || (e.getOldPhase() == GamePhase.PHYSICAL))) {
+ if (GUIPreferences.getInstance().getGameSummaryMinimap()
+ && (e.getOldPhase().isDeployment() || e.getOldPhase().isMovement()
+ || e.getOldPhase().isTargeting() || e.getOldPhase().isPremovement()
+ || e.getOldPhase().isPrefiring() || e.getOldPhase().isFiring()
+ || e.getOldPhase().isPhysical())) {
File dir = new File(Configuration.gameSummaryImagesMMDir(), game.getUUIDString());
if (!dir.exists()) {
dir.mkdirs();
@@ -1358,7 +1358,6 @@ public void gamePhaseChange(GamePhaseChangeEvent e) {
} catch (Exception ex) {
LogManager.getLogger().error("", ex);
}
-
}
refreshMap();
}
diff --git a/megamek/src/megamek/client/ui/swing/tooltip/PilotToolTip.java b/megamek/src/megamek/client/ui/swing/tooltip/PilotToolTip.java
index 195d0b31f2b..e3b5c2a5bde 100644
--- a/megamek/src/megamek/client/ui/swing/tooltip/PilotToolTip.java
+++ b/megamek/src/megamek/client/ui/swing/tooltip/PilotToolTip.java
@@ -33,7 +33,6 @@
import static megamek.client.ui.swing.tooltip.TipUtil.getOptionList;
import static megamek.client.ui.swing.tooltip.TipUtil.scaledHTMLSpacer;
import static megamek.client.ui.swing.util.UIUtil.guiScaledFontHTML;
-import static megamek.client.ui.swing.util.UIUtil.scaleForGUI;
import static megamek.client.ui.swing.util.UIUtil.uiQuirksColor;
public final class PilotToolTip {
@@ -133,7 +132,7 @@ private static StringBuilder crewPortraits(final Entity entity, boolean showDefa
try {
// Adjust the portrait size to the GUI scale and number of pilots
- float imgSize = scaleForGUI(PORTRAIT_BASESIZE);
+ float imgSize = UIUtil.scaleForGUI(PORTRAIT_BASESIZE);
imgSize /= 0.2f * (crew.getSlotCount() - 1) + 1;
Image portrait = crew.getPortrait(i).getBaseImage().getScaledInstance(-1, (int) imgSize, Image.SCALE_SMOOTH);
// Write the scaled portrait to file
diff --git a/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java b/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java
index 7be100109fd..28bd4d59a42 100644
--- a/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java
+++ b/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java
@@ -13,18 +13,12 @@
*/
package megamek.client.ui.swing.tooltip;
-import java.awt.Color;
-import java.text.MessageFormat;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.stream.Collectors;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.util.UIUtil;
import megamek.common.*;
import megamek.common.annotations.Nullable;
-import megamek.common.enums.GamePhase;
-import megamek.common.options.*;
+import megamek.common.options.OptionsConstants;
import megamek.common.preference.PreferenceManager;
import megamek.common.templates.TROView;
import megamek.common.weapons.LegAttack;
@@ -33,9 +27,18 @@
import megamek.common.weapons.SwarmWeaponAttack;
import org.apache.logging.log4j.LogManager;
+import java.awt.*;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+
+import static megamek.client.ui.Messages.getString;
import static megamek.client.ui.swing.tooltip.TipUtil.*;
import static megamek.client.ui.swing.util.UIUtil.*;
-import static megamek.client.ui.Messages.*;
public final class UnitToolTip {
@@ -614,10 +617,10 @@ private static StringBuilder inGameValues(Entity entity, Player localPlayer) {
// Actual Movement
if (!isGunEmplacement) {
// "Has not yet moved" only during movement phase
- if (!entity.isDone() && game.getPhase() == GamePhase.MOVEMENT) {
+ if (!entity.isDone() && game.getPhase().isMovement()) {
result.append(addToTT("NotYetMoved", BR));
- } else if ((entity.isDone() && game.getPhase() == GamePhase.MOVEMENT)
- || game.getPhase() == GamePhase.FIRING) {
+ } else if ((entity.isDone() && game.getPhase().isMovement())
+ || game.getPhase().isFiring()) {
result.append(guiScaledFontHTML(GUIPreferences.getInstance().getColorForMovement(entity.moved)));
int tmm = Compute.getTargetMovementModifier(game, entity.getId()).getValue();
if (entity.moved == EntityMovementType.MOVE_NONE) {
diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/ExtraPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/ExtraPanel.java
index 171b880d0bb..0a24bbc6010 100644
--- a/megamek/src/megamek/client/ui/swing/unitDisplay/ExtraPanel.java
+++ b/megamek/src/megamek/client/ui/swing/unitDisplay/ExtraPanel.java
@@ -7,10 +7,13 @@
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.HeatEffects;
import megamek.client.ui.swing.Slider;
+import megamek.client.ui.swing.util.UIUtil;
import megamek.client.ui.swing.widget.*;
import megamek.common.*;
import megamek.common.enums.GamePhase;
import megamek.common.options.OptionsConstants;
+import megamek.common.preference.IPreferenceChangeListener;
+import megamek.common.preference.PreferenceChangeEvent;
import megamek.common.util.fileUtils.MegaMekFile;
import javax.swing.*;
@@ -24,9 +27,11 @@
/**
* This class shows information about a unit that doesn't belong elsewhere.
*/
-class ExtraPanel extends PicMap implements ActionListener, ItemListener {
+class ExtraPanel extends PicMap implements ActionListener, ItemListener, IPreferenceChangeListener {
private final UnitDisplay unitDisplay;
+ private JPanel panelMain;
+ private JScrollPane scrollPane;
private JLabel lblLastTarget;
private JLabel curSensorsL;
private JLabel narcLabel;
@@ -154,7 +159,7 @@ public Component getListCellRendererComponent(JList> list, Object value, int i
gridbag = new GridBagLayout();
c = new GridBagConstraints();
- setLayout(gridbag);
+ panelMain = new JPanel(gridbag);
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(15, 9, 1, 9);
@@ -163,65 +168,71 @@ public Component getListCellRendererComponent(JList> list, Object value, int i
c.weighty = 1.0;
gridbag.setConstraints(curSensorsL, c);
- add(curSensorsL);
+ panelMain.add(curSensorsL);
gridbag.setConstraints(chSensors, c);
- add(chSensors);
+ panelMain.add(chSensors);
gridbag.setConstraints(narcLabel, c);
- add(narcLabel);
+ panelMain.add(narcLabel);
c.insets = new Insets(1, 9, 1, 9);
- JScrollPane scrollPane = new JScrollPane(narcList);
+ scrollPane = new JScrollPane(narcList);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
gridbag.setConstraints(scrollPane, c);
- add(scrollPane);
+ panelMain.add(scrollPane);
gridbag.setConstraints(unusedL, c);
- add(unusedL);
+ panelMain.add(unusedL);
gridbag.setConstraints(unusedR, c);
- add(unusedR);
+ panelMain.add(unusedR);
gridbag.setConstraints(carrysL, c);
- add(carrysL);
+ panelMain.add(carrysL);
gridbag.setConstraints(carrysR, c);
- add(carrysR);
+ panelMain.add(carrysR);
gridbag.setConstraints(dumpBombs, c);
- add(dumpBombs);
+ panelMain.add(dumpBombs);
gridbag.setConstraints(sinksL, c);
- add(sinksL);
+ panelMain.add(sinksL);
gridbag.setConstraints(sinksR, c);
- add(sinksR);
+ panelMain.add(sinksR);
gridbag.setConstraints(sinks2B, c);
- add(sinks2B);
+ panelMain.add(sinks2B);
gridbag.setConstraints(heatL, c);
- add(heatL);
+ panelMain.add(heatL);
c.insets = new Insets(1, 9, 18, 9);
gridbag.setConstraints(heatR, c);
- add(heatR);
+ panelMain.add(heatR);
c.insets = new Insets(0, 0, 0, 0);
gridbag.setConstraints(lblLastTarget, c);
- add(lblLastTarget);
+ panelMain.add(lblLastTarget);
c.insets = new Insets(1, 9, 18, 9);
gridbag.setConstraints(lastTargetR, c);
- add(lastTargetR);
+ panelMain.add(lastTargetR);
c.insets = new Insets(1, 9, 1, 9);
gridbag.setConstraints(activateHidden, c);
c.insets = new Insets(1, 9, 6, 9);
gridbag.setConstraints(comboActivateHiddenPhase, c);
- add(activateHidden);
- add(comboActivateHiddenPhase);
+ panelMain.add(activateHidden);
+ panelMain.add(comboActivateHiddenPhase);
+
+ adaptToGUIScale();
+ GUIPreferences.getInstance().addPreferenceChangeListener(this);
+ setLayout(new BorderLayout());
+ add(panelMain);
+ panelMain.setOpaque(false);
setBackGround();
onResize();
@@ -610,4 +621,18 @@ public void actionPerformed(ActionEvent ae) {
clientgui.getClient().sendActivateHidden(myMechId, (phase == null) ? GamePhase.UNKNOWN : phase);
}
}
+
+ private void adaptToGUIScale() {
+ UIUtil.adjustContainer(panelMain, UIUtil.FONT_SCALE1);
+ scrollPane.setMinimumSize(new Dimension(200, UIUtil.scaleForGUI(100)));
+ scrollPane.setPreferredSize(new Dimension(200, UIUtil.scaleForGUI(100)));
+ }
+
+ @Override
+ public void preferenceChange(PreferenceChangeEvent e) {
+ // Update the text size when the GUI scaling changes
+ if (e.getName().equals(GUIPreferences.GUI_SCALE)) {
+ adaptToGUIScale();
+ }
+ }
}
diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/SystemPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/SystemPanel.java
index 4f58d3c069f..88899be49ef 100644
--- a/megamek/src/megamek/client/ui/swing/unitDisplay/SystemPanel.java
+++ b/megamek/src/megamek/client/ui/swing/unitDisplay/SystemPanel.java
@@ -4,10 +4,13 @@
import megamek.client.ui.Messages;
import megamek.client.ui.swing.ChoiceDialog;
import megamek.client.ui.swing.ClientGUI;
+import megamek.client.ui.swing.GUIPreferences;
+import megamek.client.ui.swing.util.UIUtil;
import megamek.client.ui.swing.widget.*;
import megamek.common.*;
-import megamek.common.enums.GamePhase;
import megamek.common.options.OptionsConstants;
+import megamek.common.preference.IPreferenceChangeListener;
+import megamek.common.preference.PreferenceChangeEvent;
import megamek.common.util.fileUtils.MegaMekFile;
import javax.swing.*;
@@ -24,7 +27,7 @@
/**
* This class shows the critical hits and systems for a mech
*/
-class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSelectionListener {
+class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSelectionListener, IPreferenceChangeListener {
private static int LOC_ALL_EQUIP = 0;
private static int LOC_ALL_WEAPS = 1;
@@ -35,6 +38,8 @@ class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSe
private static final long serialVersionUID = 6660316427898323590L;
+ private JPanel panelMain;
+ private JScrollPane tSlotScroll;
private JLabel locLabel;
private JLabel slotLabel;
private JLabel modeLabel;
@@ -91,7 +96,7 @@ class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSe
// layout main panel
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
- setLayout(gridbag);
+ panelMain = new JPanel(gridbag);
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(15, 9, 1, 1);
@@ -102,7 +107,7 @@ class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSe
c.gridwidth = 1;
c.gridheight = 1;
gridbag.setConstraints(locLabel, c);
- add(locLabel);
+ panelMain.add(locLabel);
c.weightx = 0.0;
c.gridy = 0;
@@ -110,7 +115,7 @@ class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSe
c.gridwidth = GridBagConstraints.REMAINDER;
c.insets = new Insets(15, 1, 1, 9);
gridbag.setConstraints(slotLabel, c);
- add(slotLabel);
+ panelMain.add(slotLabel);
c.weightx = 0.5;
// c.weighty = 1.0;
@@ -120,7 +125,7 @@ class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSe
c.insets = new Insets(1, 9, 15, 1);
c.gridheight = 1;
gridbag.setConstraints(locList, c);
- add(locList);
+ panelMain.add(locList);
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(15, 9, 1, 1);
@@ -131,7 +136,7 @@ class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSe
c.gridwidth = 1;
c.gridheight = 1;
gridbag.setConstraints(unitLabel, c);
- add(unitLabel);
+ panelMain.add(unitLabel);
c.weightx = 0.5;
// c.weighty = 1.0;
@@ -141,7 +146,7 @@ class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSe
c.insets = new Insets(1, 9, 15, 1);
c.gridheight = GridBagConstraints.REMAINDER;
gridbag.setConstraints(unitList, c);
- add(unitList);
+ panelMain.add(unitList);
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridheight = 1;
@@ -150,10 +155,10 @@ class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSe
c.weightx = 0.0;
c.weighty = 1.0;
c.insets = new Insets(1, 1, 1, 9);
- JScrollPane tSlotScroll = new JScrollPane(slotList);
+ tSlotScroll = new JScrollPane(slotList);
tSlotScroll.setMinimumSize(new Dimension(200, 100));
gridbag.setConstraints(tSlotScroll, c);
- add(tSlotScroll);
+ panelMain.add(tSlotScroll);
c.gridwidth = 1;
c.gridy = 2;
@@ -162,7 +167,7 @@ class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSe
c.weighty = 0.0;
gridbag.setConstraints(modeLabel, c);
c.insets = new Insets(1, 1, 1, 1);
- add(modeLabel);
+ panelMain.add(modeLabel);
c.weightx = 1.0;
c.gridwidth = GridBagConstraints.REMAINDER;
@@ -170,7 +175,7 @@ class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSe
c.gridx = 2;
c.insets = new Insets(1, 1, 1, 9);
gridbag.setConstraints(m_chMode, c);
- add(m_chMode);
+ panelMain.add(m_chMode);
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridheight = GridBagConstraints.REMAINDER;
@@ -178,7 +183,13 @@ class SystemPanel extends PicMap implements ItemListener, ActionListener, ListSe
c.gridx = 1;
c.insets = new Insets(4, 4, 15, 9);
gridbag.setConstraints(m_bDumpAmmo, c);
- add(m_bDumpAmmo);
+ panelMain.add(m_bDumpAmmo);
+
+ adaptToGUIScale();
+ GUIPreferences.getInstance().addPreferenceChangeListener(this);
+ setLayout(new BorderLayout());
+ add(panelMain);
+ panelMain.setOpaque(false);
setBackGround();
onResize();
@@ -460,7 +471,7 @@ public void itemStateChanged(ItemEvent ev) {
if ((m.getType() instanceof MiscType)
&& m.getType().hasSubType(MiscType.S_RETRACTABLE_BLADE)
- && (clientgui.getClient().getGame().getPhase() != GamePhase.MOVEMENT)) {
+ && !clientgui.getClient().getGame().getPhase().isMovement()) {
clientgui.systemMessage(Messages.getString("MechDisplay.RetractableBladeModePhase"));
return;
}
@@ -486,7 +497,7 @@ public void itemStateChanged(ItemEvent ev) {
this.unitDisplay.wPan.displayMech(en);
this.unitDisplay.wPan.selectWeapon(weap);
} else {
- if (GamePhase.DEPLOYMENT == clientgui.getClient().getGame().getPhase()) {
+ if (clientgui.getClient().getGame().getPhase().isDeployment()) {
clientgui.systemMessage(Messages.getString("MechDisplay.willSwitchAtStart",
m.getName(), m.pendingMode().getDisplayableName()));
} else {
@@ -723,8 +734,8 @@ public void valueChanged(ListSelectionEvent event) {
if ((m != null)
&& bOwner
&& (m.getType() instanceof AmmoType)
- && (client.getGame().getPhase() != GamePhase.DEPLOYMENT)
- && (client.getGame().getPhase() != GamePhase.MOVEMENT)
+ && !client.getGame().getPhase().isDeployment()
+ && !client.getGame().getPhase().isMovement()
&& (m.getUsableShotsLeft() > 0)
&& !m.isDumping()
&& en.isActive()
@@ -829,4 +840,18 @@ private void removeListeners() {
m_chMode.removeItemListener(this);
m_bDumpAmmo.removeActionListener(this);
}
+
+ private void adaptToGUIScale() {
+ UIUtil.adjustContainer(panelMain, UIUtil.FONT_SCALE1);
+ tSlotScroll.setMinimumSize(new Dimension(200, UIUtil.scaleForGUI(100)));
+ tSlotScroll.setPreferredSize(new Dimension(200, UIUtil.scaleForGUI(100)));
+ }
+
+ @Override
+ public void preferenceChange(PreferenceChangeEvent e) {
+ // Update the text size when the GUI scaling changes
+ if (e.getName().equals(GUIPreferences.GUI_SCALE)) {
+ adaptToGUIScale();
+ }
+ }
}
\ No newline at end of file
diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java
index 613a58e6c33..0acb416fcc5 100644
--- a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java
+++ b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java
@@ -1,15 +1,19 @@
package megamek.client.ui.swing.unitDisplay;
+import megamek.MMConstants;
import megamek.client.event.MechDisplayEvent;
import megamek.client.ui.GBC;
import megamek.client.ui.Messages;
import megamek.client.ui.baseComponents.MMComboBox;
import megamek.client.ui.swing.*;
+import megamek.client.ui.swing.util.UIUtil;
import megamek.client.ui.swing.widget.*;
import megamek.common.*;
import megamek.common.annotations.Nullable;
import megamek.common.enums.WeaponSortOrder;
import megamek.common.options.OptionsConstants;
+import megamek.common.preference.IPreferenceChangeListener;
+import megamek.common.preference.PreferenceChangeEvent;
import megamek.common.util.fileUtils.MegaMekFile;
import megamek.common.weapons.bayweapons.BayWeapon;
import megamek.common.weapons.gaussrifles.HAGWeapon;
@@ -24,13 +28,13 @@
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
-import java.util.*;
import java.util.List;
+import java.util.*;
/**
* This class contains the all the gizmos for firing the mech's weapons.
*/
-public class WeaponPanel extends PicMap implements ListSelectionListener, ActionListener {
+public class WeaponPanel extends PicMap implements ListSelectionListener, ActionListener, IPreferenceChangeListener {
/**
* Mouse adaptor for the weapon list. Supports rearranging the weapons
* to define a custom ordering.
@@ -289,6 +293,8 @@ public void sort(Comparator comparator) {
* after the forced target.
*/
private Targetable prevTarget = null;
+ private JPanel panelMain;
+ private JScrollPane tWeaponScroll;
private JComboBox m_chAmmo;
public JComboBox m_chBayWeapon;
@@ -358,7 +364,7 @@ public void sort(Comparator comparator) {
WeaponPanel(UnitDisplay unitDisplay) {
this.unitDisplay = unitDisplay;
- setLayout(new GridBagLayout());
+ panelMain = new JPanel(new GridBagLayout());
int gridy = 0;
wSortOrder = new JLabel(
@@ -366,10 +372,10 @@ public void sort(Comparator comparator) {
SwingConstants.LEFT);
wSortOrder.setOpaque(false);
wSortOrder.setForeground(Color.WHITE);
- add(wSortOrder, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wSortOrder, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(15, 9, 1, 1).gridy(gridy).gridx(0));
comboWeaponSortOrder = new MMComboBox<>("comboWeaponSortOrder", WeaponSortOrder.values());
- add(comboWeaponSortOrder,
+ panelMain.add(comboWeaponSortOrder,
GBC.eol().insets(15, 9, 15, 1)
.fill(GridBagConstraints.HORIZONTAL)
.anchor(GridBagConstraints.CENTER).gridy(gridy)
@@ -381,10 +387,10 @@ public void sort(Comparator comparator) {
WeaponListMouseAdapter mouseAdapter = new WeaponListMouseAdapter();
weaponList.addMouseListener(mouseAdapter);
weaponList.addMouseMotionListener(mouseAdapter);
- JScrollPane tWeaponScroll = new JScrollPane(weaponList);
+ tWeaponScroll = new JScrollPane(weaponList);
tWeaponScroll.setMinimumSize(new Dimension(200, 100));
tWeaponScroll.setPreferredSize(new Dimension(200, 100));
- add(tWeaponScroll,
+ panelMain.add(tWeaponScroll,
GBC.eol().insets(15, 9, 15, 9)
.fill(GridBagConstraints.HORIZONTAL)
.anchor(GridBagConstraints.CENTER).gridy(gridy)
@@ -407,14 +413,14 @@ public void sort(Comparator comparator) {
wBayWeapon.setForeground(Color.WHITE);
m_chBayWeapon = new JComboBox<>();
- add(wBayWeapon, GBC.std().insets(15, 1, 1, 1).gridy(gridy).gridx(0));
+ panelMain.add(wBayWeapon, GBC.std().insets(15, 1, 1, 1).gridy(gridy).gridx(0));
- add(m_chBayWeapon, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(m_chBayWeapon, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 1, 15, 1).gridy(gridy).gridx(1));
gridy++;
- add(wAmmo, GBC.std().insets(15, 9, 1, 1).gridy(gridy).gridx(0));
+ panelMain.add(wAmmo, GBC.std().insets(15, 9, 1, 1).gridy(gridy).gridx(0));
- add(m_chAmmo,
+ panelMain.add(m_chAmmo,
GBC.eol().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 15, 1).gridy(gridy).gridx(1));
gridy++;
@@ -427,12 +433,12 @@ public void sort(Comparator comparator) {
currentHeatBuildupR.setOpaque(false);
currentHeatBuildupR.setForeground(Color.WHITE);
- add(currentHeatBuildupL,
+ panelMain.add(currentHeatBuildupL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.anchor(GridBagConstraints.EAST).insets(9, 1, 1, 9)
.gridy(gridy).gridx(0));
- add(currentHeatBuildupR,
+ panelMain.add(currentHeatBuildupR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 1, 9, 9).gridy(gridy).gridx(1));
gridy++;
@@ -470,40 +476,40 @@ public void sort(Comparator comparator) {
wDamageTrooperR.setOpaque(false);
wDamageTrooperR.setForeground(Color.WHITE);
- add(wNameL,
+ panelMain.add(wNameL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(0));
- add(wHeatL,
+ panelMain.add(wHeatL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(1));
- add(wDamL,
+ panelMain.add(wDamL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(2));
- add(wArcHeatL, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wArcHeatL, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(3));
- add(wDamageTrooperL, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wDamageTrooperL, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(3));
gridy++;
- add(wNameR,
+ panelMain.add(wNameR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(0));
- add(wHeatR,
+ panelMain.add(wHeatR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(1));
- add(wDamR,
+ panelMain.add(wDamR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(2));
- add(wArcHeatR, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wArcHeatR, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(3));
- add(wDamageTrooperR, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wDamageTrooperR, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(3));
gridy++;
// Adding range labels
@@ -590,103 +596,103 @@ public void sort(Comparator comparator) {
wInfantryRange5R.setOpaque(false);
wInfantryRange5R.setForeground(Color.WHITE);
- add(wMinL,
+ panelMain.add(wMinL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(0));
- add(wShortL,
+ panelMain.add(wShortL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(1));
- add(wMedL,
+ panelMain.add(wMedL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(2));
- add(wLongL,
+ panelMain.add(wLongL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(3));
- add(wExtL,
+ panelMain.add(wExtL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(4));
- add(wInfantryRange0L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange0L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(0));
- add(wInfantryRange1L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange1L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(1));
- add(wInfantryRange2L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange2L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(2));
- add(wInfantryRange3L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange3L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(3));
- add(wInfantryRange4L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange4L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(4));
- add(wInfantryRange5L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange5L, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(4));
gridy++;
// ----------------
- add(wMinR,
+ panelMain.add(wMinR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(0));
- add(wShortR,
+ panelMain.add(wShortR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(1));
- add(wMedR,
+ panelMain.add(wMedR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(2));
- add(wLongR,
+ panelMain.add(wLongR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(3));
- add(wExtR,
+ panelMain.add(wExtR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(4));
- add(wInfantryRange0R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange0R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(0));
- add(wInfantryRange1R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange1R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(1));
- add(wInfantryRange2R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange2R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(2));
- add(wInfantryRange3R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange3R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(3));
- add(wInfantryRange4R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange4R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(4));
- add(wInfantryRange5R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wInfantryRange5R, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(5));
gridy++;
// ----------------
- add(wAVL,
+ panelMain.add(wAVL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(0));
- add(wShortAVR, GBC.std().fill(GridBagConstraints.HORIZONTAL)
+ panelMain.add(wShortAVR, GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(1));
- add(wMedAVR,
+ panelMain.add(wMedAVR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(2));
- add(wLongAVR,
+ panelMain.add(wLongAVR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(3));
- add(wExtAVR,
+ panelMain.add(wExtAVR,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 9, 1).gridy(gridy).gridx(4));
@@ -715,29 +721,29 @@ public void sort(Comparator comparator) {
wToHitR.setOpaque(false);
wToHitR.setForeground(Color.WHITE);
- add(wTargetL,
+ panelMain.add(wTargetL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(0));
- add(wTargetR,
+ panelMain.add(wTargetR,
GBC.eol().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(1));
gridy++;
- add(wRangeL,
+ panelMain.add(wRangeL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(0));
- add(wRangeR,
+ panelMain.add(wRangeR,
GBC.eol().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(1));
gridy++;
- add(wToHitL,
+ panelMain.add(wToHitL,
GBC.std().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(0));
- add(wToHitR,
+ panelMain.add(wToHitR,
GBC.eol().fill(GridBagConstraints.HORIZONTAL)
.insets(1, 9, 1, 1).gridy(gridy).gridx(1));
gridy++;
@@ -746,15 +752,21 @@ public void sort(Comparator comparator) {
toHitText = new JTextArea("", 2, 20);
toHitText.setEditable(false);
toHitText.setLineWrap(true);
- toHitText.setFont(new Font("SansSerif", Font.PLAIN, 10));
- add(toHitText,
+ toHitText.setFont(new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 10));
+ panelMain.add(toHitText,
GBC.eol().fill(GridBagConstraints.BOTH)
.insets(15, 9, 15, 9).gridy(gridy).gridx(0)
.gridheight(2));
gridy++;
addListeners();
-
+
+ adaptToGUIScale();
+ GUIPreferences.getInstance().addPreferenceChangeListener(this);
+ setLayout(new BorderLayout());
+ add(panelMain);
+ panelMain.setOpaque(false);
+
setBackGround();
onResize();
}
@@ -2672,4 +2684,18 @@ public Targetable getPrevTarget() {
public void setPrevTarget(Targetable prevTarget) {
this.prevTarget = prevTarget;
}
+
+ private void adaptToGUIScale() {
+ UIUtil.adjustContainer(panelMain, UIUtil.FONT_SCALE1);
+ tWeaponScroll.setMinimumSize(new Dimension(200, UIUtil.scaleForGUI(200)));
+ tWeaponScroll.setPreferredSize(new Dimension(200, UIUtil.scaleForGUI(200)));
+ }
+
+ @Override
+ public void preferenceChange(PreferenceChangeEvent e) {
+ // Update the text size when the GUI scaling changes
+ if (e.getName().equals(GUIPreferences.GUI_SCALE)) {
+ adaptToGUIScale();
+ }
+ }
}
diff --git a/megamek/src/megamek/client/ui/swing/unitSelector/TWAdvancedSearchPanel.java b/megamek/src/megamek/client/ui/swing/unitSelector/TWAdvancedSearchPanel.java
index 2538ea8a78d..087e11f31e4 100644
--- a/megamek/src/megamek/client/ui/swing/unitSelector/TWAdvancedSearchPanel.java
+++ b/megamek/src/megamek/client/ui/swing/unitSelector/TWAdvancedSearchPanel.java
@@ -19,8 +19,10 @@
*/
package megamek.client.ui.swing.unitSelector;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.table.MegamekTable;
+import megamek.client.ui.swing.util.UIUtil;
import megamek.common.*;
import javax.swing.*;
@@ -221,8 +223,6 @@ public TWAdvancedSearchPanel(int year) {
// Set up Weapon Class table
- scrTableWeaponType.setMinimumSize(new Dimension(850, 150));
- scrTableWeaponType.setPreferredSize(new Dimension(850, 150));
weaponTypesModel = new WeaponClassTableModel();
tblWeaponType = new MegamekTable(weaponTypesModel,WeaponClassTableModel.COL_NAME);
TableColumn wpsTypeCol = tblWeaponType.getColumnModel().getColumn(WeaponClassTableModel.COL_QTY);
@@ -231,22 +231,14 @@ public TWAdvancedSearchPanel(int year) {
weaponTypesSorter = new TableRowSorter<>(weaponTypesModel);
tblWeaponType.setRowSorter(weaponTypesSorter);
tblWeaponType.addKeyListener(this);
- for (int i = 0; i < WeaponClassTableModel.N_COL; i++) {
- TableColumn column = tblWeaponType.getColumnModel().getColumn(i);
- if ((i == WeaponClassTableModel.COL_QTY)) {
- column.setPreferredWidth(40);
- } else {
- column.setPreferredWidth(310);
- }
- }
- tblWeaponType.setFont(new Font("Monospaced", Font.PLAIN, 12));
+ tblWeaponType.setFont(new Font(MMConstants.FONT_MONOSPACED, Font.PLAIN, 12));
tblWeaponType.getSelectionModel().addListSelectionListener(this);
+ for (int i = 0; i < weaponTypesModel.getColumnCount(); i++) {
+ tblWeaponType.getColumnModel().getColumn(i).setPreferredWidth(weaponTypesModel.getPreferredWidth(i));
+ }
scrTableWeaponType.setViewportView(tblWeaponType);
-
// Setup Weapons Table
- scrTableWeapons.setMinimumSize(new Dimension(850, 150));
- scrTableWeapons.setPreferredSize(new Dimension(850, 150));
weaponsModel = new WeaponsTableModel();
tblWeapons = new MegamekTable(weaponsModel, WeaponsTableModel.COL_NAME);
TableColumn wpsCol = tblWeapons.getColumnModel().getColumn(
@@ -256,27 +248,14 @@ public TWAdvancedSearchPanel(int year) {
weaponsSorter = new TableRowSorter<>(weaponsModel);
tblWeapons.setRowSorter(weaponsSorter);
tblWeapons.addKeyListener(this);
- for (int i = 0; i < WeaponsTableModel.N_COL; i++) {
- TableColumn column = tblWeapons.getColumnModel().getColumn(i);
- if (i == WeaponsTableModel.COL_QTY) {
- column.setPreferredWidth(40);
- } else if (i == WeaponsTableModel.COL_IS_CLAN) {
- column.setPreferredWidth(75);
- } else if (i == WeaponsTableModel.COL_NAME) {
- column.setPreferredWidth(310);
- } else if (i == WeaponsTableModel.COL_LEVEL) {
- column.setPreferredWidth(100);
- } else {
- column.setPreferredWidth(50);
- }
- }
- tblWeapons.setFont(new Font("Monospaced", Font.PLAIN, 12));
+ tblWeapons.setFont(new Font(MMConstants.FONT_MONOSPACED, Font.PLAIN, 12));
tblWeapons.getSelectionModel().addListSelectionListener(this);
+ for (int i = 0; i < weaponsModel.getColumnCount(); i++) {
+ tblWeapons.getColumnModel().getColumn(i).setPreferredWidth(weaponsModel.getPreferredWidth(i));
+ }
scrTableWeapons.setViewportView(tblWeapons);
// Setup Equipment Table
- scrTableEquipment.setMinimumSize(new java.awt.Dimension(850, 150));
- scrTableEquipment.setPreferredSize(new java.awt.Dimension(850, 150));
equipmentModel = new EquipmentTableModel();
tblEquipment = new MegamekTable(equipmentModel,
EquipmentTableModel.COL_NAME);
@@ -287,22 +266,11 @@ public TWAdvancedSearchPanel(int year) {
equipmentSorter = new TableRowSorter<>(equipmentModel);
tblEquipment.setRowSorter(equipmentSorter);
tblEquipment.addKeyListener(this);
- for (int i = 0; i < EquipmentTableModel.N_COL; i++) {
- TableColumn column = tblEquipment.getColumnModel().getColumn(i);
- if (i == EquipmentTableModel.COL_NAME) {
- column.setPreferredWidth(400);
- } else if (i == EquipmentTableModel.COL_COST) {
- column.setPreferredWidth(175);
- } else if (i == EquipmentTableModel.COL_LEVEL) {
- column.setPreferredWidth(100);
- } else if (i == EquipmentTableModel.COL_QTY) {
- column.setPreferredWidth(40);
- } else {
- column.setPreferredWidth(75);
- }
- }
- tblEquipment.setFont(new Font("Monospaced", Font.PLAIN, 12));
+ tblEquipment.setFont(new Font(MMConstants.FONT_MONOSPACED, Font.PLAIN, 12));
tblEquipment.getSelectionModel().addListSelectionListener(this);
+ for (int i = 0; i < equipmentModel.getColumnCount(); i++) {
+ tblEquipment.getColumnModel().getColumn(i).setPreferredWidth(equipmentModel.getPreferredWidth(i));
+ }
scrTableEquipment.setViewportView(tblEquipment);
// Populate Tables
@@ -328,18 +296,14 @@ public TWAdvancedSearchPanel(int year) {
txtEqExp.setEditable(false);
txtEqExp.setLineWrap(true);
txtEqExp.setWrapStyleWord(true);
- Dimension size = new Dimension(325, 50);
- txtEqExp.setPreferredSize(size);
- expScroller.setPreferredSize(size);
- expScroller.setMaximumSize(size);
// Layout
GridBagConstraints c = new GridBagConstraints();
setLayout(new GridBagLayout());
+ c.weighty = 0;
+ c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.WEST;
- c.insets = new Insets(0, 0, 0, 0);
-
c.insets = new Insets(0, 10, 0, 0);
c.gridx = 0; c.gridy = 0;
this.add(lblWalk, c);
@@ -352,15 +316,12 @@ public TWAdvancedSearchPanel(int year) {
this.add(panWalk, c);
c.gridx = 3; c.gridy = 0;
c.insets = new Insets(0, 40, 0, 0);
- c.weighty = 1;
c.anchor = GridBagConstraints.WEST;
JPanel cockpitPanel = new JPanel();
cockpitPanel.add(cbxEnableCockpitSearch,BorderLayout.WEST);
cockpitPanel.add(lblCockpitType,BorderLayout.WEST);
cockpitPanel.add(cboCockpitType,BorderLayout.EAST);
this.add(cockpitPanel, c);
- c.insets = new Insets(0, 0, 0, 0);
- c.weighty = 0;
c.gridx = 0; c.gridy = 1;
c.anchor = GridBagConstraints.WEST;
@@ -375,15 +336,12 @@ public TWAdvancedSearchPanel(int year) {
this.add(panJump, c);
c.anchor = GridBagConstraints.WEST;
c.gridx = 3; c.gridy = 1;
- c.weighty = 1;
c.insets = new Insets(0, 40, 0, 0);
JPanel internalsPanel = new JPanel();
internalsPanel.add(cbxEnableInternalsSearch);
internalsPanel.add(lblInternalsType);
internalsPanel.add(cboInternalsType,BorderLayout.EAST);
this.add(internalsPanel, c);
- c.weighty = 0;
- c.insets = new Insets(0, 0, 0, 0);
c.anchor = GridBagConstraints.WEST;
c.gridx = 0; c.gridy++;
@@ -393,17 +351,14 @@ public TWAdvancedSearchPanel(int year) {
c.gridx = 1;
this.add(cArmor, c);
c.gridx = 3;
- c.weighty = 1;
c.insets = new Insets(0, 40, 0, 0);
JPanel armorPanel = new JPanel();
armorPanel.add(cbxEnableArmorSearch);
armorPanel.add(lblArmorType);
armorPanel.add(cboArmorType,BorderLayout.EAST);
this.add(armorPanel, c);
- c.weighty = 0;
c.anchor = GridBagConstraints.CENTER;
-
c.insets = new Insets(16, 0, 0, 0);
c.gridx = 0; c.gridy++;
this.add(lblTableFilters, c);
@@ -424,34 +379,37 @@ public TWAdvancedSearchPanel(int year) {
c.gridx = 0; c.gridy++;
this.add(lblWeaponClass, c);
+ c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(0, 0, 0, 0);
- c.gridwidth = 4;
+ c.gridwidth = 5;
c.gridx = 0; c.gridy++;
this.add(scrTableWeaponType, c);
c.gridwidth = 1;
+ c.fill = GridBagConstraints.NONE;
c.insets = new Insets(0, 0, 0, 0);
c.gridx = 0; c.gridy++;
this.add(lblWeapons, c);
+ c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(0, 0, 0, 0);
- c.gridwidth = 4;
+ c.gridwidth = 5;
c.gridx = 0; c.gridy++;
this.add(scrTableWeapons, c);
- c.gridwidth = 1;
+ c.fill = GridBagConstraints.NONE;
c.gridwidth = 1;
c.insets = new Insets(16, 0, 0, 0);
c.gridx = 0; c.gridy++;
this.add(lblEquipment, c);
-
+ c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(0, 0, 0, 0);
- c.gridwidth = 4;
+ c.gridwidth = 5;
c.gridx = 0; c.gridy++;
this.add(scrTableEquipment, c);
- c.gridwidth = 1;
+ c.fill = GridBagConstraints.NONE;
c.gridx = 0; c.gridy++;
c.gridwidth = 4;
JPanel btnPanel = new JPanel();
@@ -468,9 +426,9 @@ public TWAdvancedSearchPanel(int year) {
// Filter Expression
c.gridx = 0; c.gridy++;
this.add(lblEqExpTxt, c);
- c.fill = GridBagConstraints.BOTH;
c.gridwidth = 4;
c.gridx = 1;
+ c.fill = GridBagConstraints.HORIZONTAL;
this.add(expScroller, c);
c.fill = GridBagConstraints.NONE;
c.insets = new Insets(0, 0, 0, 0);
@@ -977,6 +935,17 @@ public int getColumnCount() {
return N_COL;
}
+ public int getPreferredWidth(int col) {
+ switch (col) {
+ case COL_QTY:
+ return 40;
+ case COL_NAME:
+ return 310;
+ default:
+ return 0;
+ }
+ }
+
@Override
public String getColumnName(int column) {
switch (column) {
@@ -1080,6 +1049,31 @@ public int getColumnCount() {
return N_COL;
}
+ public int getPreferredWidth(int col) {
+ switch (col) {
+ case COL_QTY:
+ return 40;
+ case COL_NAME:
+ return 310;
+ case COL_IS_CLAN:
+ return 75;
+ case COL_DMG:
+ return 50;
+ case COL_HEAT:
+ return 50;
+ case COL_SHORT:
+ return 50;
+ case COL_MED:
+ return 50;
+ case COL_LONG:
+ return 50;
+ case COL_LEVEL:
+ return 100;
+ default:
+ return 0;
+ }
+ }
+
@Override
public String getColumnName(int column) {
switch (column) {
@@ -1207,6 +1201,23 @@ public int getColumnCount() {
return N_COL;
}
+ public int getPreferredWidth(int col) {
+ switch (col) {
+ case COL_QTY:
+ return 40;
+ case COL_NAME:
+ return 400;
+ case COL_IS_CLAN:
+ return 75;
+ case COL_COST:
+ return 175;
+ case COL_LEVEL:
+ return 100;
+ default:
+ return 0;
+ }
+ }
+
@Override
public String getColumnName(int column) {
switch (column) {
@@ -1579,4 +1590,12 @@ public boolean matches(String name) {
}
}
+ public void adaptToGUIScale() {
+ scrTableWeaponType.setMinimumSize(new Dimension(UIUtil.scaleForGUI(650), UIUtil.scaleForGUI(150)));
+ scrTableWeaponType.setPreferredSize(new Dimension(UIUtil.scaleForGUI(650), UIUtil.scaleForGUI(150)));
+ scrTableWeapons.setMinimumSize(new Dimension(UIUtil.scaleForGUI(650), UIUtil.scaleForGUI(350)));
+ scrTableWeapons.setPreferredSize(new Dimension(UIUtil.scaleForGUI(650), UIUtil.scaleForGUI(150)));
+ scrTableEquipment.setMinimumSize(new Dimension(UIUtil.scaleForGUI(650), UIUtil.scaleForGUI(350)));
+ scrTableEquipment.setPreferredSize(new Dimension(UIUtil.scaleForGUI(650), UIUtil.scaleForGUI(150)));
+ }
}
diff --git a/megamek/src/megamek/client/ui/swing/util/KeyCommandBind.java b/megamek/src/megamek/client/ui/swing/util/KeyCommandBind.java
index 5f24f8abf49..212d3670925 100644
--- a/megamek/src/megamek/client/ui/swing/util/KeyCommandBind.java
+++ b/megamek/src/megamek/client/ui/swing/util/KeyCommandBind.java
@@ -102,6 +102,7 @@ public enum KeyCommandBind {
UNIT_DISPLAY(true, "toggleUnitDisplay", VK_D, CTRL_DOWN_MASK),
UNIT_OVERVIEW(true, "toggleUnitOverview", VK_U, CTRL_DOWN_MASK),
KEY_BINDS(true, "toggleKeybinds", VK_K, CTRL_DOWN_MASK),
+ PLANETARY_CONDITIONS(true, "togglePlanetaryConditions", VK_P, CTRL_DOWN_MASK),
CLIENT_SETTINGS(true, "clientSettings", VK_C, ALT_DOWN_MASK),
INC_GUISCALE(true, "incGuiScale", VK_ADD, CTRL_DOWN_MASK),
DEC_GUISCALE(true, "decGuiScale", VK_SUBTRACT, CTRL_DOWN_MASK),
diff --git a/megamek/src/megamek/client/ui/swing/util/TurnTimer.java b/megamek/src/megamek/client/ui/swing/util/TurnTimer.java
index fdccfec22dd..5ae5ad8e1d9 100644
--- a/megamek/src/megamek/client/ui/swing/util/TurnTimer.java
+++ b/megamek/src/megamek/client/ui/swing/util/TurnTimer.java
@@ -41,8 +41,8 @@ public class TurnTimer {
public TurnTimer(int limit, AbstractPhaseDisplay pD) {
phaseDisplay = pD;
- // make it minutes here.
- timeLimit = limit * 60;
+ // linit in seconds.
+ timeLimit = limit;
display = new JPanel();
progressBar = new JProgressBar(JProgressBar.HORIZONTAL, 0, timeLimit);
@@ -93,14 +93,18 @@ public void startTimer() {
public void stopTimer() {
display.setVisible(false);
- phaseDisplay.getClientgui().getMenuBar().remove(display);
+
+ if (phaseDisplay.getClientgui().getMenuBar() != null) {
+ phaseDisplay.getClientgui().getMenuBar().remove(display);
+ }
+
timer.stop();
}
public static TurnTimer init(AbstractPhaseDisplay phaseDisplay, Client client) {
// check if there should be a turn timer running
if (timerShouldStart(client)) {
- Option timer = (Option) client.getGame().getOptions().getOption("turn_timer");
+ Option timer = (Option) client.getGame().getOptions().getOption(OptionsConstants.BASE_TURN_TIMER);
TurnTimer tt = new TurnTimer(timer.intValue(), phaseDisplay);
tt.startTimer();
return tt;
@@ -121,7 +125,7 @@ private static boolean timerShouldStart(Client client) {
GamePhase phase = client.getGame().getPhase();
// turn timer should only kick in on firing, targeting, movement and physical attack phase
- return phase == GamePhase.MOVEMENT || phase == GamePhase.FIRING || phase == GamePhase.PHYSICAL || phase == GamePhase.TARGETING;
+ return phase.isMovement() || phase.isFiring() || phase.isPhysical() || phase.isTargeting();
}
return false;
}
diff --git a/megamek/src/megamek/client/ui/swing/util/UIUtil.java b/megamek/src/megamek/client/ui/swing/util/UIUtil.java
index 9401a025bf4..9b91ae4126a 100644
--- a/megamek/src/megamek/client/ui/swing/util/UIUtil.java
+++ b/megamek/src/megamek/client/ui/swing/util/UIUtil.java
@@ -13,6 +13,7 @@
*/
package megamek.client.ui.swing.util;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.baseComponents.MMComboBox;
import megamek.client.ui.swing.ClientGUI;
@@ -26,6 +27,8 @@
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
@@ -46,6 +49,7 @@ public final class UIUtil {
/** The style = font-size: xx value corresponding to a GUI scale of 1 */
public final static int FONT_SCALE1 = 14;
+ public final static int FONT_SCALE2 = 17;
public final static String ECM_SIGN = " \u24BA ";
public final static String LOADED_SIGN = " \u26DF ";
public final static String UNCONNECTED_SIGN = " \u26AC";
@@ -353,36 +357,63 @@ public static String scaleMessageForGUI(String str) {
}
/** Call this for {@link #adjustDialog(Container)} with a dialog as parameter. */
- public static void adjustDialog(JDialog dialog) {
- adjustDialog(dialog.getContentPane());
+ public static void adjustDialog(JDialog dialog, int fontSize) {
+ adjustContainer(dialog.getContentPane(), fontSize);
+ }
+
+ /** calculate the max row height in a table + pad */
+ public static int calRowHeights(JTable table, int sf, int pad)
+ {
+ int rowHeight = sf;
+ for (int row = 0; row < table.getRowCount(); row++) {
+ for (int col = 0; col < table.getColumnCount(); col++) {
+ // Consider the preferred height of the column
+ TableCellRenderer renderer = table.getCellRenderer(row, col);
+ Component comp = table.prepareRenderer(renderer, row, col);
+ rowHeight = Math.max(rowHeight, comp.getPreferredSize().height);
+ }
+ }
+ // Add a little margin to the rows
+ return rowHeight + pad;
}
-
+
+ /** set font size for the TitledBorder */
+ public static void setTitledBorder(Border border, int sf) {
+ if ((border instanceof TitledBorder)) {
+ ((TitledBorder) border).setTitleFont(((TitledBorder) border).getTitleFont().deriveFont((float) sf));
+ }
+ }
+
/**
* Applies the current gui scale to a given Container.
* For a dialog, pass getContentPane(). This can work well for simple dialogs,
* but it is of course "experimental". Complex dialogs must be hand-adapted to the
* gui scale.
*/
- public static void adjustDialog(Container contentPane) {
- Font scaledFont = getScaledFont();
- Component[] allComps = contentPane.getComponents();
- for (Component comp: allComps) {
+ public static void adjustContainer(Container parentCon, int fontSize) {
+ int sf = scaleForGUI(fontSize);
+ int pad = 3;
+
+ for (Component comp: parentCon.getComponents()) {
if ((comp instanceof JButton) || (comp instanceof JLabel)
|| (comp instanceof JComboBox>) || (comp instanceof JTextField) || (comp instanceof JSlider)
|| (comp instanceof JSpinner) || (comp instanceof JTextArea) || (comp instanceof JTextPane)
- || (comp instanceof JToggleButton)) {
- comp.setFont(scaledFont.deriveFont(comp.getFont().getStyle()));
+ || (comp instanceof JToggleButton) || (comp instanceof JTable) || (comp instanceof JList)
+ || (comp instanceof JEditorPane) || (comp instanceof JTree)) {
+ if ((comp.getFont() != null) && (sf != comp.getFont().getSize())) {
+ comp.setFont(comp.getFont().deriveFont((float) sf));
+ }
}
if (comp instanceof JScrollPane
&& ((JScrollPane) comp).getViewport().getView() instanceof JComponent) {
- adjustDialog(((JScrollPane) comp).getViewport());
+ JScrollPane scrollPane = (JScrollPane) comp;
+ Border border = scrollPane.getBorder();
+ setTitledBorder(border, sf);
+ adjustContainer(((JScrollPane) comp).getViewport(), fontSize);
} else if (comp instanceof JPanel) {
JPanel panel = (JPanel) comp;
Border border = panel.getBorder();
- if ((border instanceof TitledBorder)) {
- ((TitledBorder) border).setTitleFont(scaledFont);
- }
-
+ setTitledBorder(border, sf);
if ((border instanceof EmptyBorder)) {
Insets i = ((EmptyBorder) border).getBorderInsets();
int top = scaleForGUI(i.top);
@@ -391,19 +422,29 @@ public static void adjustDialog(Container contentPane) {
int right = scaleForGUI(i.right);
panel.setBorder(BorderFactory.createEmptyBorder(top, left, bottom, right));
}
- adjustDialog(panel);
+ adjustContainer(panel, fontSize);
} else if (comp instanceof JTabbedPane) {
- comp.setFont(scaledFont);
+ if ((comp.getFont() != null) && (sf != comp.getFont().getSize())) {
+ comp.setFont(comp.getFont().deriveFont((float) sf));
+ }
JTabbedPane tabbedPane = (JTabbedPane) comp;
for (int i=0; i < tabbedPane.getTabCount();i++) {
Component subComp = tabbedPane.getTabComponentAt(i);
if (subComp instanceof JPanel) {
- adjustDialog((JPanel) subComp);
+ adjustContainer((JPanel) subComp, fontSize);
}
}
- adjustDialog((JTabbedPane) comp);
+ adjustContainer((JTabbedPane) comp, fontSize);
+ } else if (comp instanceof JTable) {
+ JTable table = (JTable) comp;
+ table.setRowHeight(calRowHeights(table, sf, pad));
+ JTableHeader header = table.getTableHeader();
+ if ((header instanceof JTableHeader)) {
+ header.setFont(comp.getFont().deriveFont((float) sf));
+ }
+ adjustContainer((Container) comp, fontSize);
} else if (comp instanceof Container) {
- adjustDialog((Container) comp);
+ adjustContainer((Container) comp, fontSize);
}
}
}
@@ -414,7 +455,17 @@ public static void scaleMenu(final JComponent popup) {
if ((comp instanceof JMenuItem)) {
comp.setFont(getScaledFont());
scaleJMenuItem((JMenuItem) comp);
- }
+ }
+ }
+ }
+
+ public static void scaleComp(JComponent comp, int fontSize) {
+ int sf = scaleForGUI(fontSize);
+
+ if ((comp.getFont() != null) && (sf != comp.getFont().getSize())) {
+ comp.setFont(comp.getFont().deriveFont((float) sf));
+ Border border = comp.getBorder();
+ setTitledBorder(border, sf);
}
}
@@ -1064,7 +1115,7 @@ public static JMenuItem menuItem(String text, String cmd, boolean enabled,
* size 14 and scaled with the current gui scaling.
*/
public static Font getScaledFont() {
- return new Font("Dialog", Font.PLAIN, scaleForGUI(FONT_SCALE1));
+ return new Font(MMConstants.FONT_DIALOG, Font.PLAIN, scaleForGUI(FONT_SCALE1));
}
// PRIVATE
@@ -1187,4 +1238,13 @@ public static void updateWindowBounds(Window window) {
window.setLocation(location);
window.setSize(size);
}
+
+ /*
+ * Calculates center of view port for a given point
+ */
+ public static int calculateCenter(int vh, int h, int th, int y) {
+ y = Math.max(0, y - ((vh - th)/2));
+ y = Math.min(y, h - vh);
+ return y;
+ }
}
diff --git a/megamek/src/megamek/client/ui/swing/widget/AeroMapSet.java b/megamek/src/megamek/client/ui/swing/widget/AeroMapSet.java
index a1c87ebc337..126c5066d3c 100644
--- a/megamek/src/megamek/client/ui/swing/widget/AeroMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/AeroMapSet.java
@@ -15,24 +15,16 @@
package megamek.client.ui.swing.widget;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Image;
-import java.awt.Polygon;
-import java.util.Vector;
-
-import javax.swing.JComponent;
-
+import megamek.MMConstants;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
-import megamek.common.Aero;
-import megamek.common.Configuration;
-import megamek.common.Dropship;
-import megamek.common.Entity;
-import megamek.common.SmallCraft;
+import megamek.common.*;
import megamek.common.util.fileUtils.MegaMekFile;
+import javax.swing.*;
+import java.awt.*;
+import java.util.Vector;
+
/**
* Class which keeps set of all areas required to represent ASF unit in
* MechDisplay.ArmorPanel class.
@@ -67,9 +59,9 @@ public class AeroMapSet implements DisplayMapSet {
private Polygon aftArmor = new Polygon(new int[] { 45, 45, 30, 30, 95, 95,
80, 80 }, new int[] { 160, 180, 190, 200, 200, 190, 180, 160 }, 8);
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
public AeroMapSet(JComponent c, UnitDisplay unitDisplay) {
diff --git a/megamek/src/megamek/client/ui/swing/widget/ArmlessMechMapSet.java b/megamek/src/megamek/client/ui/swing/widget/ArmlessMechMapSet.java
index 364454f61c0..07b9fe14f32 100644
--- a/megamek/src/megamek/client/ui/swing/widget/ArmlessMechMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/ArmlessMechMapSet.java
@@ -15,6 +15,7 @@
*/
package megamek.client.ui.swing.widget;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
@@ -121,9 +122,9 @@ public class ArmlessMechMapSet implements DisplayMapSet {
private Image heatImage;
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
public ArmlessMechMapSet(JComponent c, UnitDisplay unitDisplay) {
diff --git a/megamek/src/megamek/client/ui/swing/widget/BattleArmorMapSet.java b/megamek/src/megamek/client/ui/swing/widget/BattleArmorMapSet.java
index c14d753b67b..f30899d1196 100644
--- a/megamek/src/megamek/client/ui/swing/widget/BattleArmorMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/BattleArmorMapSet.java
@@ -15,6 +15,7 @@
*/
package megamek.client.ui.swing.widget;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.common.BattleArmor;
@@ -50,7 +51,7 @@ public class BattleArmorMapSet implements DisplayMapSet {
private int stepY = 53;
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
/**
diff --git a/megamek/src/megamek/client/ui/swing/widget/CapitalFighterMapSet.java b/megamek/src/megamek/client/ui/swing/widget/CapitalFighterMapSet.java
index 1ab5f96b596..1098b337b80 100644
--- a/megamek/src/megamek/client/ui/swing/widget/CapitalFighterMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/CapitalFighterMapSet.java
@@ -14,15 +14,7 @@
*/
package megamek.client.ui.swing.widget;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Image;
-import java.util.Vector;
-
-import javax.swing.JComponent;
-
+import megamek.MMConstants;
import megamek.client.ui.swing.GUIPreferences;
import megamek.common.Aero;
import megamek.common.Configuration;
@@ -30,6 +22,10 @@
import megamek.common.options.OptionsConstants;
import megamek.common.util.fileUtils.MegaMekFile;
+import javax.swing.*;
+import java.awt.*;
+import java.util.Vector;
+
/**
* Class which keeps set of all areas required to represent Capital Fighter unit
* in MechDisplay.ArmorPanel class.
@@ -68,7 +64,7 @@ public class CapitalFighterMapSet implements DisplayMapSet {
private int armorRows = 8;
private int armorCols = 6;
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
public CapitalFighterMapSet(JComponent c) {
diff --git a/megamek/src/megamek/client/ui/swing/widget/GeneralInfoMapSet.java b/megamek/src/megamek/client/ui/swing/widget/GeneralInfoMapSet.java
index 6bed21ead56..6f7581e2032 100644
--- a/megamek/src/megamek/client/ui/swing/widget/GeneralInfoMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/GeneralInfoMapSet.java
@@ -15,6 +15,7 @@
*/
package megamek.client.ui.swing.widget;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.common.*;
@@ -43,9 +44,9 @@ public class GeneralInfoMapSet implements DisplayMapSet {
elevationR, fuelR, curSensorsR, visualRangeR;
private PMMultiLineLabel quirksAndPartReps;
private Vector bgDrawers = new Vector<>();
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayLargeFontSize"));
- private static final Font FONT_TITLE = new Font("SansSerif", Font.ITALIC,
+ private static final Font FONT_TITLE = new Font(MMConstants.FONT_SANS_SERIF, Font.ITALIC,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayLargeFontSize"));
private int yCoord = 1;
diff --git a/megamek/src/megamek/client/ui/swing/widget/InfantryMapSet.java b/megamek/src/megamek/client/ui/swing/widget/InfantryMapSet.java
index 6d98a18f1cb..0775e71bcd0 100644
--- a/megamek/src/megamek/client/ui/swing/widget/InfantryMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/InfantryMapSet.java
@@ -14,6 +14,7 @@
*/
package megamek.client.ui.swing.widget;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.common.Configuration;
@@ -47,7 +48,7 @@ public class InfantryMapSet implements DisplayMapSet {
// Set of Background drawers
private Vector bgDrawers = new Vector<>();
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorMediumFontSize"));
public InfantryMapSet(JComponent c) {
diff --git a/megamek/src/megamek/client/ui/swing/widget/JumpshipMapSet.java b/megamek/src/megamek/client/ui/swing/widget/JumpshipMapSet.java
index d7193364657..d3c2151eead 100644
--- a/megamek/src/megamek/client/ui/swing/widget/JumpshipMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/JumpshipMapSet.java
@@ -14,15 +14,7 @@
*/
package megamek.client.ui.swing.widget;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Image;
-import java.awt.Polygon;
-import java.util.Vector;
-
-import javax.swing.JComponent;
-
+import megamek.MMConstants;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
import megamek.common.Configuration;
@@ -31,6 +23,10 @@
import megamek.common.Jumpship;
import megamek.common.util.fileUtils.MegaMekFile;
+import javax.swing.*;
+import java.awt.*;
+import java.util.Vector;
+
/**
* Class which keeps set of all areas required to
* represent ASF unit in MechDisplay.ArmorPanel class.
@@ -70,13 +66,11 @@ public class JumpshipMapSet implements DisplayMapSet{
private Polygon aftArmor = new Polygon (new int[] { 20, 0, 40, 40, 60, 60, 100, 80 },
new int[] { 160, 200, 190, 200, 200, 190, 200, 160 }, 8);
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
-
-
public JumpshipMapSet(JComponent c, UnitDisplay unitDisplay) {
this.unitDisplay = unitDisplay;
comp = c;
diff --git a/megamek/src/megamek/client/ui/swing/widget/LargeSupportTankMapSet.java b/megamek/src/megamek/client/ui/swing/widget/LargeSupportTankMapSet.java
index f5dfb9322eb..e8ea622df99 100644
--- a/megamek/src/megamek/client/ui/swing/widget/LargeSupportTankMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/LargeSupportTankMapSet.java
@@ -14,15 +14,7 @@
*/
package megamek.client.ui.swing.widget;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Image;
-import java.awt.Polygon;
-import java.util.Vector;
-
-import javax.swing.JComponent;
-
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
@@ -32,6 +24,10 @@
import megamek.common.SupportTank;
import megamek.common.util.fileUtils.MegaMekFile;
+import javax.swing.*;
+import java.awt.*;
+import java.util.Vector;
+
/**
* Class which keeps set of all areas required to represent Tank unit in
* MechDisplay.ArmorPanel class.
@@ -119,9 +115,9 @@ public class LargeSupportTankMapSet implements DisplayMapSet {
new int[] { 65, 65, 80, 100, 115, 115 },
new int[] { 125, 142, 165, 165, 142, 125 }, 6);
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
public LargeSupportTankMapSet(JComponent c, UnitDisplay unitDisplay) {
diff --git a/megamek/src/megamek/client/ui/swing/widget/MechMapSet.java b/megamek/src/megamek/client/ui/swing/widget/MechMapSet.java
index 10afa38523e..6e677875c93 100644
--- a/megamek/src/megamek/client/ui/swing/widget/MechMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/MechMapSet.java
@@ -14,6 +14,7 @@
*/
package megamek.client.ui.swing.widget;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
@@ -144,9 +145,9 @@ public class MechMapSet implements DisplayMapSet {
private Image heatImage;
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
public MechMapSet(JComponent c, UnitDisplay unitDisplay) {
@@ -179,8 +180,7 @@ public void setEntity(Entity e) {
a = m.getArmor(i);
a0 = m.getOArmor(i);
vLabels[i].setValue(m.getArmorString(i));
- WidgetUtils.setAreaColor(areas[i], vLabels[i], (double) a
- / (double) a0);
+ WidgetUtils.setAreaColor(areas[i], vLabels[i], (double) a / (double) a0);
if (m.hasRearArmor(i)) {
a = m.getArmor(i, true);
a0 = m.getOArmor(i, true);
diff --git a/megamek/src/megamek/client/ui/swing/widget/PilotMapSet.java b/megamek/src/megamek/client/ui/swing/widget/PilotMapSet.java
index a60edc7659e..ad318d9202f 100644
--- a/megamek/src/megamek/client/ui/swing/widget/PilotMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/PilotMapSet.java
@@ -14,16 +14,7 @@
*/
package megamek.client.ui.swing.widget;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Image;
-import java.awt.image.BufferedImage;
-import java.util.Enumeration;
-import java.util.Vector;
-
-import javax.swing.JComponent;
-
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.common.Configuration;
@@ -34,6 +25,12 @@
import megamek.common.options.OptionsConstants;
import megamek.common.util.fileUtils.MegaMekFile;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.util.Enumeration;
+import java.util.Vector;
+
/**
* Set of elements to represent pilot information in MechDisplay
*/
@@ -48,9 +45,9 @@ public class PilotMapSet implements DisplayMapSet {
private PMSimpleLabel pilotR, gunneryR, gunneryLR, gunneryMR, gunneryBR, toughBR, initBR, commandBR, hitsR;
private PMSimpleLabel[] advantagesR;
private Vector bgDrawers = new Vector<>();
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayLargeFontSize"));
- private static final Font FONT_TITLE = new Font("SansSerif", Font.ITALIC,
+ private static final Font FONT_TITLE = new Font(MMConstants.FONT_SANS_SERIF, Font.ITALIC,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayLargeFontSize"));
private int yCoord = 1;
diff --git a/megamek/src/megamek/client/ui/swing/widget/ProtomechMapSet.java b/megamek/src/megamek/client/ui/swing/widget/ProtomechMapSet.java
index 94ce9ba9a72..b8b0c3a36d9 100644
--- a/megamek/src/megamek/client/ui/swing/widget/ProtomechMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/ProtomechMapSet.java
@@ -15,6 +15,7 @@
*/
package megamek.client.ui.swing.widget;
+import megamek.MMConstants;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
import megamek.common.Configuration;
@@ -64,7 +65,7 @@ public class ProtomechMapSet implements DisplayMapSet {
// Set of Background drawers which will be sent to PicMap component
private Vector bgDrawers = new Vector<>();
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
/**
diff --git a/megamek/src/megamek/client/ui/swing/widget/QuadMapSet.java b/megamek/src/megamek/client/ui/swing/widget/QuadMapSet.java
index 8f6fe252a36..8ed29e0f682 100644
--- a/megamek/src/megamek/client/ui/swing/widget/QuadMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/QuadMapSet.java
@@ -15,6 +15,7 @@
*/
package megamek.client.ui.swing.widget;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
@@ -123,9 +124,9 @@ public class QuadMapSet implements DisplayMapSet {
private Image heatImage;
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
public QuadMapSet(JComponent c, UnitDisplay unitDisplay) {
diff --git a/megamek/src/megamek/client/ui/swing/widget/SpheroidMapSet.java b/megamek/src/megamek/client/ui/swing/widget/SpheroidMapSet.java
index 283519a7602..4d290f20ba9 100644
--- a/megamek/src/megamek/client/ui/swing/widget/SpheroidMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/SpheroidMapSet.java
@@ -14,24 +14,16 @@
*/
package megamek.client.ui.swing.widget;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Image;
-import java.awt.Polygon;
-import java.util.Vector;
-
-import javax.swing.JComponent;
-
+import megamek.MMConstants;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
-import megamek.common.Aero;
-import megamek.common.Configuration;
-import megamek.common.Dropship;
-import megamek.common.Entity;
-import megamek.common.SmallCraft;
+import megamek.common.*;
import megamek.common.util.fileUtils.MegaMekFile;
+import javax.swing.*;
+import java.awt.*;
+import java.util.Vector;
+
/**
* Class which keeps set of all areas required to
* represent ASF unit in MechDisplay.ArmorPanel class.
@@ -66,9 +58,9 @@ public class SpheroidMapSet implements DisplayMapSet{
private Polygon aftArmor = new Polygon (new int[] { 0, 20, 80, 100 },
new int[] { 150, 200, 200, 150 }, 4);
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
public SpheroidMapSet(JComponent c, UnitDisplay unitDisplay) {
diff --git a/megamek/src/megamek/client/ui/swing/widget/SquadronMapSet.java b/megamek/src/megamek/client/ui/swing/widget/SquadronMapSet.java
index 69e602568d7..21733c8a218 100644
--- a/megamek/src/megamek/client/ui/swing/widget/SquadronMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/SquadronMapSet.java
@@ -14,24 +14,16 @@
*/
package megamek.client.ui.swing.widget;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Image;
-import java.util.List;
-import java.util.Vector;
-
-import javax.swing.JComponent;
-
-import megamek.common.Configuration;
-import megamek.common.Entity;
-import megamek.common.FighterSquadron;
-import megamek.common.IAero;
-import megamek.common.Game;
+import megamek.MMConstants;
+import megamek.common.*;
import megamek.common.options.OptionsConstants;
import megamek.common.util.fileUtils.MegaMekFile;
+import javax.swing.*;
+import java.awt.*;
+import java.util.List;
+import java.util.Vector;
+
/**
* Class which keeps set of all areas required to represent Capital Fighter unit
* in MechDisplay.ArmorPanel class.
@@ -72,7 +64,7 @@ public class SquadronMapSet implements DisplayMapSet {
private int max_size;
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN, 9);
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 9);
public SquadronMapSet(JComponent c, Game g) {
comp = c;
diff --git a/megamek/src/megamek/client/ui/swing/widget/SuperHeavyTankMapSet.java b/megamek/src/megamek/client/ui/swing/widget/SuperHeavyTankMapSet.java
index a40f7e14999..2c805d44ba8 100644
--- a/megamek/src/megamek/client/ui/swing/widget/SuperHeavyTankMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/SuperHeavyTankMapSet.java
@@ -14,15 +14,7 @@
*/
package megamek.client.ui.swing.widget;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Image;
-import java.awt.Polygon;
-import java.util.Vector;
-
-import javax.swing.JComponent;
-
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
@@ -31,6 +23,10 @@
import megamek.common.SuperHeavyTank;
import megamek.common.util.fileUtils.MegaMekFile;
+import javax.swing.*;
+import java.awt.*;
+import java.util.Vector;
+
/**
* Class which keeps set of all areas required to represent Tank unit in
* MechDisplay.ArmorPanel class.
@@ -118,9 +114,9 @@ public class SuperHeavyTankMapSet implements DisplayMapSet {
new int[] { 65, 65, 80, 100, 115, 115 },
new int[] { 125, 142, 165, 165, 142, 125 }, 6);
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
public SuperHeavyTankMapSet(JComponent c, UnitDisplay unitDisplay) {
diff --git a/megamek/src/megamek/client/ui/swing/widget/TankMapSet.java b/megamek/src/megamek/client/ui/swing/widget/TankMapSet.java
index fb3743583a0..1b56ae48501 100644
--- a/megamek/src/megamek/client/ui/swing/widget/TankMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/TankMapSet.java
@@ -14,6 +14,7 @@
*/
package megamek.client.ui.swing.widget;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
@@ -84,9 +85,9 @@ public class TankMapSet implements DisplayMapSet {
new int[] { 39, 39, 54, 74, 89, 89 }, new int[] { 139, 160, 187,
187, 160, 139 }, 6);
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
public TankMapSet(JComponent c, UnitDisplay unitDisplay) {
diff --git a/megamek/src/megamek/client/ui/swing/widget/TripodMechMapSet.java b/megamek/src/megamek/client/ui/swing/widget/TripodMechMapSet.java
index 3817799f54d..0deb75cc66e 100644
--- a/megamek/src/megamek/client/ui/swing/widget/TripodMechMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/TripodMechMapSet.java
@@ -15,6 +15,7 @@
*/
package megamek.client.ui.swing.widget;
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
@@ -152,9 +153,9 @@ public class TripodMechMapSet implements DisplayMapSet {
private Image heatImage;
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
public TripodMechMapSet(JComponent c, UnitDisplay unitDisplay) {
diff --git a/megamek/src/megamek/client/ui/swing/widget/VTOLMapSet.java b/megamek/src/megamek/client/ui/swing/widget/VTOLMapSet.java
index 4f71771c475..512c9a124d2 100644
--- a/megamek/src/megamek/client/ui/swing/widget/VTOLMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/VTOLMapSet.java
@@ -14,15 +14,7 @@
*/
package megamek.client.ui.swing.widget;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Image;
-import java.awt.Polygon;
-import java.util.Vector;
-
-import javax.swing.JComponent;
-
+import megamek.MMConstants;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
@@ -32,6 +24,10 @@
import megamek.common.VTOL;
import megamek.common.util.fileUtils.MegaMekFile;
+import javax.swing.*;
+import java.awt.*;
+import java.util.Vector;
+
/**
* Class which keeps set of all areas required to represent VTOL unit in
* MechDisplay.ArmorPanel class.
@@ -117,9 +113,9 @@ public class VTOLMapSet implements DisplayMapSet {
private Polygon rotorIS = new Polygon(new int[] { 45, 45, 105, 105 },
new int[] { 90, 75, 75, 90 }, 4);
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
public VTOLMapSet(JComponent c, UnitDisplay unitDisplay) {
diff --git a/megamek/src/megamek/client/ui/swing/widget/WarshipMapSet.java b/megamek/src/megamek/client/ui/swing/widget/WarshipMapSet.java
index e7de82e54f9..0271a30d5ae 100644
--- a/megamek/src/megamek/client/ui/swing/widget/WarshipMapSet.java
+++ b/megamek/src/megamek/client/ui/swing/widget/WarshipMapSet.java
@@ -14,15 +14,7 @@
*/
package megamek.client.ui.swing.widget;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Image;
-import java.awt.Polygon;
-import java.util.Vector;
-
-import javax.swing.JComponent;
-
+import megamek.MMConstants;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.unitDisplay.UnitDisplay;
import megamek.common.Configuration;
@@ -31,6 +23,10 @@
import megamek.common.Jumpship;
import megamek.common.util.fileUtils.MegaMekFile;
+import javax.swing.*;
+import java.awt.*;
+import java.util.Vector;
+
/**
* Class which keeps set of all areas required to
* represent ASF unit in MechDisplay.ArmorPanel class.
@@ -70,9 +66,9 @@ public class WarshipMapSet implements DisplayMapSet {
private Polygon aftArmor = new Polygon (new int[] { 0, -10, 40, 40, 60, 60, 110, 100 },
new int[] { 150, 200, 190, 200, 200, 190, 200, 150 }, 8);
- private static final Font FONT_LABEL = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_LABEL = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorSmallFontSize"));
- private static final Font FONT_VALUE = new Font("SansSerif", Font.PLAIN,
+ private static final Font FONT_VALUE = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN,
GUIPreferences.getInstance().getInt("AdvancedMechDisplayArmorLargeFontSize"));
public WarshipMapSet(JComponent c, UnitDisplay unitDisplay) {
diff --git a/megamek/src/megamek/common/Aero.java b/megamek/src/megamek/common/Aero.java
index 82ab9124474..c1f8ff8f82e 100644
--- a/megamek/src/megamek/common/Aero.java
+++ b/megamek/src/megamek/common/Aero.java
@@ -17,7 +17,6 @@
import megamek.common.battlevalue.AeroBVCalculator;
import megamek.common.cost.AeroCostCalculator;
import megamek.common.enums.AimingMode;
-import megamek.common.enums.GamePhase;
import megamek.common.options.OptionsConstants;
import org.apache.logging.log4j.LogManager;
@@ -2296,7 +2295,7 @@ public boolean canLoad(Entity unit, boolean checkFalse) {
// capital fighters can load other capital fighters (becoming squadrons)
// but not in the deployment phase
if (isCapitalFighter() && !unit.isEnemyOf(this) && unit.isCapitalFighter() && (getId() != unit.getId())
- && (game.getPhase() != GamePhase.DEPLOYMENT)) {
+ && !getGame().getPhase().isDeployment()) {
return true;
}
diff --git a/megamek/src/megamek/common/BattleArmor.java b/megamek/src/megamek/common/BattleArmor.java
index 41ae9ea6305..a81b2e13755 100644
--- a/megamek/src/megamek/common/BattleArmor.java
+++ b/megamek/src/megamek/common/BattleArmor.java
@@ -589,19 +589,25 @@ public String getMovementAbbr(EntityMovementType mtype) {
@Override
public HitData rollHitLocation(int table, int side, int aimedLocation, AimingMode aimingMode,
int cover) {
+ return rollHitLocation(side, aimedLocation, aimingMode, false);
+ }
+ /**
+ * Battle Armor units can only get hit in undestroyed troopers.
+ *
+ * @param isAttackingConvInfantry Set to true when attacked by CI, as these cannot score TacOps crits
+ */
+ public HitData rollHitLocation(int side, int aimedLocation, AimingMode aimingMode,
+ boolean isAttackingConvInfantry) {
// If this squad was killed, target trooper 1 (just because).
if (isDoomed()) {
return new HitData(1);
}
if ((aimedLocation != LOC_NONE) && !aimingMode.isNone()) {
-
int roll = Compute.d6(2);
-
if ((5 < roll) && (roll < 9)) {
- return new HitData(aimedLocation, side == ToHitData.SIDE_REAR,
- true);
+ return new HitData(aimedLocation, side == ToHitData.SIDE_REAR, true);
}
}
@@ -612,8 +618,7 @@ public HitData rollHitLocation(int table, int side, int aimedLocation, AimingMod
// Remember that there's one more location than the number of troopers.
// In http://forums.classicbattletech.com/index.php/topic,43203.0.html,
// "previously destroyed includes the current phase" for rolling hits on
- // a squad,
- // modifying previous ruling in the AskThePM FAQ.
+ // a squad, modifying previous ruling in the AskThePM FAQ.
while ((loc >= locations())
|| (IArmorState.ARMOR_NA == this.getInternal(loc))
|| (IArmorState.ARMOR_DESTROYED == this.getInternal(loc))
@@ -621,16 +626,13 @@ public HitData rollHitLocation(int table, int side, int aimedLocation, AimingMod
loc = Compute.d6();
}
- int critLocation = Compute.d6();
- // TacOps p. 108 Trooper takes a crit if a second roll is the same
- // location as the first.
+ // TO:AR p.108: Trooper takes a crit if a second roll is the same location as the first.
if (game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_BA_CRITICALS)
- && (loc == critLocation)) {
+ && (loc == Compute.d6()) && !isAttackingConvInfantry) {
return new HitData(loc, false, HitData.EFFECT_CRITICAL);
}
// Hit that trooper.
return new HitData(loc);
-
}
@Override
@@ -1048,6 +1050,12 @@ public int getLongStealthMod() {
return longStealthMod;
}
+ // Only for ground vehicles and certain infantry
+ @Override
+ public boolean isEligibleForPavementBonus() {
+ return false;
+ }
+
/**
* Determine if this unit has an active stealth system.
*
diff --git a/megamek/src/megamek/common/Bay.java b/megamek/src/megamek/common/Bay.java
index 4ddfe375575..2ca246de34f 100644
--- a/megamek/src/megamek/common/Bay.java
+++ b/megamek/src/megamek/common/Bay.java
@@ -14,11 +14,11 @@
*/
package megamek.common;
-import megamek.common.enums.GamePhase;
-
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.Vector;
+import java.util.stream.Collectors;
/**
* Represents a volume of space set aside for carrying cargo of some sort
@@ -220,7 +220,7 @@ public void load(Entity unit) throws IllegalArgumentException {
}
currentSpace -= spaceForUnit(unit);
- if ((unit.game.getPhase() != GamePhase.DEPLOYMENT) && (unit.game.getPhase() != GamePhase.LOUNGE)) {
+ if (!unit.getGame().getPhase().isDeployment() && !unit.getGame().getPhase().isLounge()) {
loadedThisTurn += 1;
}
@@ -239,17 +239,12 @@ public void load(Entity unit) throws IllegalArgumentException {
@Override
public Vector getLoadedUnits() {
// Return a copy of our list of troops.
- Vector loaded = new Vector<>();
- for (int unit : troops) {
- Entity entity = game.getEntity(unit);
-
- if (entity != null) {
- loaded.add(game.getEntity(unit));
- }
- }
- return loaded;
+ return troops.stream()
+ .map(unit -> game.getEntity(unit))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toCollection(Vector::new));
}
-
+
/**
* Generate a raw list of the Ids stored in troops.
* Used by MHQ in cases where we can't get the entities via Game
diff --git a/megamek/src/megamek/common/BoardDimensions.java b/megamek/src/megamek/common/BoardDimensions.java
index 12785e41e1c..e7ca976c67d 100644
--- a/megamek/src/megamek/common/BoardDimensions.java
+++ b/megamek/src/megamek/common/BoardDimensions.java
@@ -1,111 +1,67 @@
-/**
- * A class for representing board sizes.
+/*
+ * Copyright (c) 2013 - Edward Cullen (eddy@obsessedcomputers.co.uk)
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
*
- * Copyright © 2013 Edward Cullen (eddy@obsessedcomputers.co.uk)
+ * This file is part of MegaMek.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful,
+ * MegaMek is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, it is available online at:
- * http://www.gnu.org/licenses/gpl-2.0.html
+ * along with MegaMek. If not, see .
*/
package megamek.common;
import java.io.Serializable;
+import java.util.Objects;
/**
* Type-safe, immutable, dimensions class for handling board sizes.
*
* @author Edward Cullen
+ * @author Simon (Juliez)
*/
-public class BoardDimensions implements Cloneable, Serializable,
- Comparable {
+public class BoardDimensions implements Serializable, Comparable {
- /**
- * See {@link java.io.Serializable}.
- */
private static final long serialVersionUID = -3562335656969231217L;
/**
* Construct a new BoardDimensions object.
*
- * @param width
- * The width.
- * @param height
- * The height.
- * @throws IllegalArgumentException
- * If either width or height is less than 1.
+ * @param width The width
+ * @param height The height
+ * @throws IllegalArgumentException If either width or height is less than 1.
*/
public BoardDimensions(final int width, final int height) {
if ((width < 1) || (height < 1)) {
- throw new IllegalArgumentException(
- "width and height must be positive non-zero values");
+ throw new IllegalArgumentException("width and height must be positive non-zero values");
}
-
w = width;
h = height;
}
- /**
- * Copy constructor.
- *
- * @param old
- * The instance to copy.
- */
- public BoardDimensions(final BoardDimensions old) {
- if (old == null) {
- throw new IllegalArgumentException(
- "must provide instance to copy constructor");
- }
- w = old.w;
- h = old.h;
- }
-
- /**
- * The width.
- *
- * @return The width.
- */
+ /** @return The board width. */
public int width() {
return w;
}
- /**
- * The height.
- *
- * @return The height.
- */
+ /** @return The board height. */
public int height() {
return h;
}
- /**
- * The total number of hexes in the board.
- *
- * @return The total number of hexes in the board.
- */
+ /** @return The total number of hexes in the board. */
public long numHexes() {
return (long) width() * height();
}
- /**
- * {@inheritDoc}
- */
- @Override
- public BoardDimensions clone() {
- return new BoardDimensions(this);
- }
-
- /**
- * {@inheritDoc}
- */
@Override
public boolean equals(final Object obj) {
boolean result;
@@ -120,51 +76,24 @@ public boolean equals(final Object obj) {
return result;
}
- /**
- * {@inheritDoc}
- */
@Override
public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = (prime * result) + h;
- result = (prime * result) + w;
- return result;
+ return Objects.hash(w, h);
}
- /**
- * Return the dimensions this object represents in the form "WIDTHxHEIGHT".
- *
- * @return A String!
- */
@Override
public String toString() {
- return w + "x" + h;
+ return w + " x " + h;
}
/**
- * Compares dimensions based width, falling back on height if the widths
- * equal
+ * Compares BoardDimensions based on width, falling back on height if the widths are equal
*/
@Override
public int compareTo(final BoardDimensions o) {
- int result = 0;
-
- if (width() < o.width()) {
- result = -1;
- } else if (width() > o.width()) {
- result = 1;
- } else {
- // width is the same, next consider height
- if (height() < o.height()) {
- result = -1;
- } else if (height() > o.height()) {
- result = 1;
- }
- }
- return result;
+ return (width() - o.width() != 0) ? width() - o.width() : height() - o.height();
}
private final int w;
private final int h;
-}
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/CompositeTechLevel.java b/megamek/src/megamek/common/CompositeTechLevel.java
index d1ec1a05559..14c6f69d0a9 100644
--- a/megamek/src/megamek/common/CompositeTechLevel.java
+++ b/megamek/src/megamek/common/CompositeTechLevel.java
@@ -307,7 +307,7 @@ private void addExtinctionRange(int start, int end) {
extinct = merged;
}
- private static class DateRange implements Serializable, Comparable {
+ public static class DateRange implements Serializable, Comparable {
private static final long serialVersionUID = 3144194494591950878L;
Integer start = null;
diff --git a/megamek/src/megamek/common/Compute.java b/megamek/src/megamek/common/Compute.java
index f305776781e..af33251ae20 100644
--- a/megamek/src/megamek/common/Compute.java
+++ b/megamek/src/megamek/common/Compute.java
@@ -6021,10 +6021,11 @@ public static Coords scatterDiveBombs(Coords coords, int moF) {
* TW pg 246. The scatter only happens in the "front" three facings.
*
* @param coords The Coords to scatter from
- * @param facing
+ * @param facing Direction we were going at the time the bomb was dropped
+ * @param moF How badly we failed
* @return the Coords scattered to and distance (moF)
*/
- public static Coords scatterAltitudeBombs(Coords coords, int facing) {
+ public static Coords scatterAltitudeBombs(Coords coords, int facing, int moF) {
int dir = 0;
int scatterDirection = Compute.d6(1);
switch (scatterDirection) {
@@ -6041,8 +6042,8 @@ public static Coords scatterAltitudeBombs(Coords coords, int facing) {
dir = (facing + 1) % 6;
break;
}
- int dist = Compute.d6(1);
- return coords.translated(dir, dist);
+
+ return coords.translated(dir, moF);
}
/**
diff --git a/megamek/src/megamek/common/Dropship.java b/megamek/src/megamek/common/Dropship.java
index e69644d51e9..5b08ed0ed37 100644
--- a/megamek/src/megamek/common/Dropship.java
+++ b/megamek/src/megamek/common/Dropship.java
@@ -14,7 +14,6 @@
import megamek.client.ui.swing.calculationReport.CalculationReport;
import megamek.common.battlevalue.DropShipBVCalculator;
import megamek.common.cost.DropShipCostCalculator;
-import megamek.common.enums.GamePhase;
import megamek.common.options.OptionsConstants;
import java.util.HashMap;
@@ -621,7 +620,7 @@ public boolean usesWeaponBays() {
if (null == game) {
return true;
}
- return (isAirborne() || isSpaceborne() || game.getPhase() == GamePhase.LOUNGE);
+ return (isAirborne() || isSpaceborne() || game.getPhase().isLounge());
}
@Override
diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java
index af419af26bc..73f815f1bc5 100644
--- a/megamek/src/megamek/common/Entity.java
+++ b/megamek/src/megamek/common/Entity.java
@@ -3901,12 +3901,10 @@ public int getFirstWeapon() {
// we can't use during this phase... do we?
for (Mounted mounted : getWeaponList()) {
// TAG only in the correct phase...
- if ((mounted.getType().hasFlag(WeaponType.F_TAG) && (game
- .getPhase() != GamePhase.OFFBOARD))
- || (!mounted.getType().hasFlag(WeaponType.F_TAG) && (game
- .getPhase() == GamePhase.OFFBOARD))
- //No AMS, unless it's in 'weapon' mode
- || (mounted.getType().hasFlag(WeaponType.F_AMS) && !mounted.curMode().equals(Weapon.MODE_AMS_MANUAL))) {
+ if ((mounted.getType().hasFlag(WeaponType.F_TAG) && !getGame().getPhase().isOffboard())
+ || (!mounted.getType().hasFlag(WeaponType.F_TAG) && getGame().getPhase().isOffboard())
+ // No AMS, unless it's in 'weapon' mode
+ || (mounted.getType().hasFlag(WeaponType.F_AMS) && !mounted.curMode().equals(Weapon.MODE_AMS_MANUAL))) {
continue;
}
@@ -3964,24 +3962,20 @@ public boolean isWeaponValidForPhase(Mounted mounted) {
|| (mounted.getLinked().getUsableShotsLeft() > 0))) {
// TAG only in the correct phase...
- if ((mounted.getType().hasFlag(WeaponType.F_TAG)
- && (game.getPhase() != GamePhase.OFFBOARD))
- || (!mounted.getType().hasFlag(WeaponType.F_TAG)
- && (game.getPhase()
- == GamePhase.OFFBOARD))) {
+ if ((mounted.getType().hasFlag(WeaponType.F_TAG) && !getGame().getPhase().isOffboard())
+ || (!mounted.getType().hasFlag(WeaponType.F_TAG) && getGame().getPhase().isOffboard())) {
return false;
}
// Artillery or Bearings-only missiles only in the targeting phase...
- if (!(mounted.getType().hasFlag(WeaponType.F_ARTILLERY)
- || mounted.isInBearingsOnlyMode()
- || (this.getAltitude() == 0
- && mounted.getType() instanceof CapitalMissileWeapon))
- && (game.getPhase() == GamePhase.TARGETING)) {
+ if (getGame().getPhase().isTargeting()
+ && !(mounted.getType().hasFlag(WeaponType.F_ARTILLERY)
+ || mounted.isInBearingsOnlyMode()
+ || ((this.getAltitude() == 0) && (mounted.getType() instanceof CapitalMissileWeapon)))) {
return false;
}
// No Bearings-only missiles in the firing phase
- if (mounted.isInBearingsOnlyMode() && game.getPhase() == GamePhase.FIRING) {
+ if (mounted.isInBearingsOnlyMode() && getGame().getPhase().isFiring()) {
return false;
}
@@ -7001,7 +6995,7 @@ TargetRoll.AUTOMATIC_FAIL, getCrew().getPiloting()
}
if (game.getOptions().booleanOption(OptionsConstants.ADVANCED_TACOPS_FATIGUE)
- && crew.isPilotingFatigued()) {
+ && crew.isPilotingFatigued()) {
roll.addModifier(1, "fatigue");
}
@@ -7009,7 +7003,7 @@ TargetRoll.AUTOMATIC_FAIL, getCrew().getPiloting()
roll.addModifier(taserInterference, "taser interference");
}
- if ((game.getPhase() == GamePhase.MOVEMENT) && isPowerReverse()) {
+ if (getGame().getPhase().isMovement() && isPowerReverse()) {
roll.addModifier(1, "power reverse");
}
@@ -7035,10 +7029,10 @@ public PilotingRollData addConditionBonuses(PilotingRollData roll,
PlanetaryConditions conditions = game.getPlanetaryConditions();
// check light conditions for "running" entities
if ((moveType == EntityMovementType.MOVE_RUN)
- || (moveType == EntityMovementType.MOVE_SPRINT)
- || (moveType == EntityMovementType.MOVE_VTOL_RUN)
- || (moveType == EntityMovementType.MOVE_OVER_THRUST)
- || (moveType == EntityMovementType.MOVE_VTOL_SPRINT)) {
+ || (moveType == EntityMovementType.MOVE_SPRINT)
+ || (moveType == EntityMovementType.MOVE_VTOL_RUN)
+ || (moveType == EntityMovementType.MOVE_OVER_THRUST)
+ || (moveType == EntityMovementType.MOVE_VTOL_SPRINT)) {
int lightPenalty = conditions.getLightPilotPenalty();
if (lightPenalty > 0) {
roll.addModifier(lightPenalty,
@@ -8097,8 +8091,10 @@ public void load(Entity unit, boolean checkElev, int bayNumber) {
while (iter.hasMoreElements()) {
Transporter next = iter.nextElement();
if (next.canLoad(unit)
- && (!checkElev || (unit.getElevation() == getElevation()))
- && ((bayNumber == -1) || (((Bay) next).getBayNumber() == bayNumber))) {
+ && (!checkElev || (unit.getElevation() == getElevation()))
+ && ((bayNumber == -1)
+ || ((next instanceof Bay) && (((Bay) next).getBayNumber() == bayNumber))
+ || ((next instanceof DockingCollar) && (((DockingCollar) next).getCollarNumber() == bayNumber)))) {
next.load(unit);
unit.setTargetBay(-1); // Reset the target bay for later.
return;
@@ -8106,8 +8102,7 @@ public void load(Entity unit, boolean checkElev, int bayNumber) {
}
// If we got to this point, then we can't load the unit.
- throw new IllegalArgumentException(getShortName() + " can not load "
- + unit.getShortName());
+ throw new IllegalArgumentException(getShortName() + " can not load " + unit.getShortName());
}
public void load(Entity unit, boolean checkElev) {
@@ -8143,7 +8138,7 @@ public void recover(Entity unit) {
choice = 2;
}
if (nextbay instanceof SmallCraftBay) {
- choice = 1;
+ choice = 1;
}
}
}
@@ -9740,13 +9735,12 @@ && isEligibleForArtyAutoHitHexes()) {
}
// Hidden units are always eligible for PRE phases
- if ((phase == GamePhase.PREMOVEMENT) || (phase == GamePhase.PREFIRING)) {
+ if (phase.isPremovement() || phase.isPrefiring()) {
return isHidden();
}
// Hidden units shouldn't be counted for turn order, unless deploying or firing (spotting)
- if (isHidden() && (phase != GamePhase.DEPLOYMENT)
- && (phase != GamePhase.FIRING)) {
+ if (isHidden() && !phase.isDeployment() && !phase.isFiring()) {
return false;
}
@@ -9774,9 +9768,7 @@ && isEligibleForArtyAutoHitHexes()) {
* future
*/
public boolean canAssist(GamePhase phase) {
- if ((phase != GamePhase.PHYSICAL)
- && (phase != GamePhase.FIRING)
- && (phase != GamePhase.OFFBOARD)) {
+ if (!phase.isPhysical() && !phase.isFiring() && !phase.isOffboard()) {
return false;
}
// if you're charging or finding a club, it's already declared
@@ -15251,8 +15243,7 @@ public int modifyPhysicalDamageForMeleeSpecialist() {
return 1;
}
-
-
+
// Getters and setters for sensor contacts and firing solutions. Currently, only used in space combat
/**
* Retrieves the IDs of all entities that this entity has detected with sensors
@@ -15524,4 +15515,9 @@ public boolean hasMulId() {
* This method does nothing by default and must be overridden for unit types that get Clan CASE.
*/
public void addClanCase() { }
+
+ /** @return True for unit types that have an automatic external searchlight (Meks and Tanks). */
+ public boolean getsAutoExternalSearchlight() {
+ return false;
+ }
}
diff --git a/megamek/src/megamek/common/EntityMovementMode.java b/megamek/src/megamek/common/EntityMovementMode.java
index 7942a4e3fd5..bdc2ad19c44 100644
--- a/megamek/src/megamek/common/EntityMovementMode.java
+++ b/megamek/src/megamek/common/EntityMovementMode.java
@@ -20,7 +20,6 @@
package megamek.common;
import megamek.MegaMek;
-import megamek.common.util.EncodeControl;
import org.apache.logging.log4j.LogManager;
import java.util.List;
@@ -67,7 +66,7 @@ public enum EntityMovementMode {
//region Constructors
EntityMovementMode(final String name) {
final ResourceBundle resources = ResourceBundle.getBundle("megamek.common.messages",
- MegaMek.getMMOptions().getLocale(), new EncodeControl());
+ MegaMek.getMMOptions().getLocale());
this.name = resources.getString(name);
}
//endregion Constructors
diff --git a/megamek/src/megamek/common/EquipmentMessages.java b/megamek/src/megamek/common/EquipmentMessages.java
index 62a4d4fe649..37c304a9b10 100644
--- a/megamek/src/megamek/common/EquipmentMessages.java
+++ b/megamek/src/megamek/common/EquipmentMessages.java
@@ -14,7 +14,6 @@
package megamek.common;
import megamek.MegaMek;
-import megamek.common.util.EncodeControl;
import java.text.MessageFormat;
import java.util.MissingResourceException;
@@ -22,7 +21,7 @@
public class EquipmentMessages {
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle("megamek.common.equipmentmessages",
- MegaMek.getMMOptions().getLocale(), new EncodeControl());
+ MegaMek.getMMOptions().getLocale());
private EquipmentMessages() {
diff --git a/megamek/src/megamek/common/EquipmentType.java b/megamek/src/megamek/common/EquipmentType.java
index 501595ff4d6..73d307a2742 100644
--- a/megamek/src/megamek/common/EquipmentType.java
+++ b/megamek/src/megamek/common/EquipmentType.java
@@ -1419,20 +1419,8 @@ public String toString() {
return "EquipmentType: " + name;
}
- protected static GameOptions getGameOptions() {
- if (Server.getServerInstance() == null) {
- return null;
- } else if (Server.getServerInstance().getGame() == null) {
- return null;
- }
- return Server.getServerInstance().getGame().getOptions();
- }
-
public String getShortName() {
- if (shortName.isBlank()) {
- return getName();
- }
- return shortName;
+ return shortName.isBlank() ? getName() : shortName;
}
public String getShortName(double size) {
diff --git a/megamek/src/megamek/common/FighterSquadron.java b/megamek/src/megamek/common/FighterSquadron.java
index 9463fc4911b..7abba14f65b 100644
--- a/megamek/src/megamek/common/FighterSquadron.java
+++ b/megamek/src/megamek/common/FighterSquadron.java
@@ -14,7 +14,6 @@
import megamek.client.ui.swing.calculationReport.CalculationReport;
import megamek.common.cost.CostCalculator;
import megamek.common.enums.AimingMode;
-import megamek.common.enums.GamePhase;
import megamek.common.options.OptionsConstants;
import org.apache.logging.log4j.LogManager;
@@ -678,7 +677,8 @@ public void load(Entity unit, boolean checkFalse) throws IllegalArgumentExceptio
// Add the unit to our squadron.
fighters.addElement(unit.getId());
}
- if (game.getPhase() != GamePhase.LOUNGE) {
+
+ if (!getGame().getPhase().isLounge()) {
computeSquadronBombLoadout();
// updateWeaponGroups() and loadAllWeapons() are called in
// computeSquadronBombLoadout()
@@ -711,7 +711,7 @@ public void load(Entity unit, boolean checkFalse, int bayNumber) {
public boolean unload(Entity unit) {
// Remove the unit if we are carrying it.
boolean success = fighters.removeElement(unit.getId());
- if (game.getPhase() != GamePhase.LOUNGE) {
+ if (!getGame().getPhase().isLounge()) {
computeSquadronBombLoadout();
// updateWeaponGroups() and loadAllWeapons() are called in
// computeSquadronBombLoadout()
diff --git a/megamek/src/megamek/common/Game.java b/megamek/src/megamek/common/Game.java
index 52ed4638ffe..6c528ecee4e 100644
--- a/megamek/src/megamek/common/Game.java
+++ b/megamek/src/megamek/common/Game.java
@@ -58,6 +58,10 @@ public class Game extends AbstractGame implements Serializable {
*/
public final Version version = MMConstants.VERSION;
+ private Vector players = new Vector<>();
+ private Hashtable playerIds = new Hashtable<>();
+ private Vector teams = new Vector<>();
+
private GameOptions options = new GameOptions();
private Board board = new Board();
diff --git a/megamek/src/megamek/common/Infantry.java b/megamek/src/megamek/common/Infantry.java
index 3e0146996e3..17cc5cef186 100644
--- a/megamek/src/megamek/common/Infantry.java
+++ b/megamek/src/megamek/common/Infantry.java
@@ -723,15 +723,12 @@ protected int doBattleValueCalculation(boolean ignoreC3, boolean ignoreSkill, Ca
public Vector victoryReport() {
Vector vDesc = new Vector<>();
- Report r = new Report(7025);
- r.type = Report.PUBLIC;
+ Report r = new Report(7025, Report.PUBLIC);
r.addDesc(this);
vDesc.addElement(r);
- r = new Report(7041);
- r.type = Report.PUBLIC;
+ r = new Report(7041, Report.PUBLIC);
r.add(getCrew().getGunnery());
- r.newlines = 0;
vDesc.addElement(r);
r = new Report(7070, Report.PUBLIC);
@@ -1031,13 +1028,13 @@ public boolean canAssaultDrop() {
@Override
public boolean isEligibleFor(GamePhase phase) {
- if ((turnsLayingExplosives > 0) && (phase != GamePhase.PHYSICAL)) {
+ if ((turnsLayingExplosives > 0) && !phase.isPhysical()) {
return false;
- }
- if ((dugIn != DUG_IN_COMPLETE) && (dugIn != DUG_IN_NONE)) {
+ } else if ((dugIn != DUG_IN_COMPLETE) && (dugIn != DUG_IN_NONE)) {
return false;
+ } else {
+ return super.isEligibleFor(phase);
}
- return super.isEligibleFor(phase);
}
@Override
@@ -1497,6 +1494,16 @@ public boolean isSquad() {
return squadCount == 1;
}
+ @Override
+ public boolean isEligibleForPavementBonus() {
+ if ((game != null)
+ && game.getOptions().booleanOption(OptionsConstants.ADVANCED_TACOPS_INF_PAVE_BONUS)) {
+ return movementMode == EntityMovementMode.TRACKED || movementMode == EntityMovementMode.WHEELED || movementMode == EntityMovementMode.INF_MOTORIZED || movementMode == EntityMovementMode.HOVER;
+ } else {
+ return false;
+ }
+ }
+
@Override
public void setMovementMode(EntityMovementMode movementMode) {
super.setMovementMode(movementMode);
diff --git a/megamek/src/megamek/common/Mech.java b/megamek/src/megamek/common/Mech.java
index 987f891c52d..c9cee154207 100644
--- a/megamek/src/megamek/common/Mech.java
+++ b/megamek/src/megamek/common/Mech.java
@@ -6544,4 +6544,9 @@ public boolean isMek() {
public boolean isIndustrialMek() {
return isIndustrial();
}
+
+ @Override
+ public boolean getsAutoExternalSearchlight() {
+ return true;
+ }
}
diff --git a/megamek/src/megamek/common/MechSummaryCache.java b/megamek/src/megamek/common/MechSummaryCache.java
index 7003bce89b6..147e7f15f90 100644
--- a/megamek/src/megamek/common/MechSummaryCache.java
+++ b/megamek/src/megamek/common/MechSummaryCache.java
@@ -158,8 +158,8 @@ private void block() {
synchronized (lock) {
try {
lock.wait();
- } catch (Exception e) {
- // Ignore
+ } catch (Exception ignored) {
+
}
}
}
@@ -232,10 +232,10 @@ public void loadMechData(boolean ignoreUnofficial) {
fin.close();
istream.close();
}
- } catch (Exception e) {
+ } catch (Exception ex) {
loadReport.append(" Unable to load unit cache: ")
- .append(e.getMessage()).append("\n");
- LogManager.getLogger().error(loadReport.toString(), e);
+ .append(ex.getMessage()).append("\n");
+ LogManager.getLogger().error(loadReport.toString(), ex);
}
}
@@ -639,7 +639,7 @@ private boolean loadMechsFromDirectory(Vector vMechs,
.append(failedEquipment.next()).append("\n");
}
}
- } catch (EntityLoadingException ex) {
+ } catch (Exception ex) {
loadReport.append(" Loading from ").append(f).append("\n");
loadReport.append("*** Unable to load file: ");
StringWriter stringWriter = new StringWriter();
@@ -680,8 +680,8 @@ private boolean loadMechsFromZipFile(Vector vMechs,
try {
zFile.close();
return false;
- } catch (IOException e) {
- LogManager.getLogger().error("", e);
+ } catch (Exception ex) {
+ LogManager.getLogger().error("", ex);
}
}
ZipEntry zEntry = (ZipEntry) i.nextElement();
@@ -773,7 +773,7 @@ private void addLookupNames() {
}
}
}
- } catch (IOException ex) {
+ } catch (Exception ex) {
LogManager.getLogger().error("", ex);
}
}
diff --git a/megamek/src/megamek/common/Messages.java b/megamek/src/megamek/common/Messages.java
index 11be48a2d3d..0a02d2a6120 100644
--- a/megamek/src/megamek/common/Messages.java
+++ b/megamek/src/megamek/common/Messages.java
@@ -14,7 +14,6 @@
package megamek.common;
import megamek.MegaMek;
-import megamek.common.util.EncodeControl;
import java.text.MessageFormat;
import java.util.MissingResourceException;
@@ -22,7 +21,7 @@
public class Messages {
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle("megamek.common.messages",
- MegaMek.getMMOptions().getLocale(), new EncodeControl());
+ MegaMek.getMMOptions().getLocale());
private Messages() {
diff --git a/megamek/src/megamek/common/PlanetaryConditions.java b/megamek/src/megamek/common/PlanetaryConditions.java
index 4bca4e7510e..dd349fd1f30 100644
--- a/megamek/src/megamek/common/PlanetaryConditions.java
+++ b/megamek/src/megamek/common/PlanetaryConditions.java
@@ -34,9 +34,21 @@ public class PlanetaryConditions implements Serializable {
public static final int L_FULL_MOON = 2;
public static final int L_MOONLESS = 3;
public static final int L_PITCH_BLACK = 4;
- private static String[] lightNames = { "Daylight", "Dusk", "Full Moon Night", "Moonless Night",
- "Pitch Black" };
+ private static final String MSG_NAME_LIGHT_DAYLIGHT = Messages.getString("PlanetaryConditions.DisplayableName.Light.Daylight");
+ private static final String MSG_NAME_LIGHT_DUSK = Messages.getString("PlanetaryConditions.DisplayableName.Light.Dusk");
+ private static final String MSG_NAME_LIGHT_FULLMOONNIGHT = Messages.getString("PlanetaryConditions.DisplayableName.Light.Full Moon Night");
+ private static final String MSG_NAME_LIGHT_MOONLESSNIGHT = Messages.getString("PlanetaryConditions.DisplayableName.Light.Moonless Night");
+ private static final String MSG_NAME_LIGHT_PITCHBLACK = Messages.getString("PlanetaryConditions.DisplayableName.Light.Pitch Black");
+ private static String[] lightNames = { MSG_NAME_LIGHT_DAYLIGHT, MSG_NAME_LIGHT_DUSK, MSG_NAME_LIGHT_FULLMOONNIGHT,
+ MSG_NAME_LIGHT_MOONLESSNIGHT, MSG_NAME_LIGHT_PITCHBLACK };
public static final int L_SIZE = lightNames.length;
+ private static final String MSG_INDICATOR_LIGHT_DAY = Messages.getString("PlanetaryConditions.Indicator.Light.Day");
+ private static final String MSG_INDICATOR_LIGHT_DUSK = Messages.getString("PlanetaryConditions.Indicator.Light.Dusk");
+ private static final String MSG_INDICATOR_LIGHT_FULL_MOON = Messages.getString("PlanetaryConditions.Indicator.Light.FullMoon");
+ private static final String MSG_INDICATOR_LIGHT_MOONLESS = Messages.getString("PlanetaryConditions.Indicator.Light.Moonless");
+ private static final String MSG_INDICATOR_LIGHT_PITCH_BLACK = Messages.getString("PlanetaryConditions.Indicator.Light.PitchBlack");
+ private static String[] lightIndicators = { MSG_INDICATOR_LIGHT_DAY, MSG_INDICATOR_LIGHT_DUSK, MSG_INDICATOR_LIGHT_FULL_MOON,
+ MSG_INDICATOR_LIGHT_MOONLESS, MSG_INDICATOR_LIGHT_PITCH_BLACK };
// Weather
public static final int WE_NONE = 0;
@@ -55,10 +67,39 @@ public class PlanetaryConditions implements Serializable {
public static final int WE_HEAVY_HAIL = 13;// NYI
public static final int WE_LIGHTNING_STORM = 14;// NYI
// public static final int WE_BLIZZARD = 11; does not exist anymore
- private static String[] weatherNames = { "Clear", "Light Rain", "Moderate Rain", "Heavy Rain", "Gusting Rain", "Torrential Downpour",
- "Light Snowfall", "Moderate Snowfall", "Snow Flurries", "Heavy Snowfall", "Sleet",
- "Ice Storm" };//, "Light Hail", "Heavy Hail", "Lightning Storm" };
+ private static final String MSG_NAME_WEATHER_CLEAR = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Clear");
+ private static final String MSG_NAME_WEATHER_LIGHTRAIN = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Light Rain");
+ private static final String MSG_NAME_WEATHER_MODRAIN = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Moderate Rain");
+ private static final String MSG_NAME_WEATHER_HEAVYGRAIN = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Heavy Rain");
+ private static final String MSG_NAME_WEATHER_GUSTINGRAIN = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Gusting Rain");
+ private static final String MSG_NAME_WEATHER_TORRDOWNPOUR = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Torrential Downpour");
+ private static final String MSG_NAME_WEATHER_LIGHTSNOWFALL = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Light Snowfall");
+ private static final String MSG_NAME_WEATHER_MODSNOWFALL = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Moderate Snowfall");
+ private static final String MSG_NAME_WEATHER_SNOWFLUFFIES = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Snow Flurries");
+ private static final String MSG_NAME_WEATHER_HEAVYSNOWFALL = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Heavy Snowfall");
+ private static final String MSG_NAME_WEATHER_SLEET = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Sleet");
+ private static final String MSG_NAME_WEATHER_ICESTORM = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Ice Storm");
+ private static String[] weatherNames = { MSG_NAME_WEATHER_CLEAR, MSG_NAME_WEATHER_LIGHTRAIN, MSG_NAME_WEATHER_MODRAIN,
+ MSG_NAME_WEATHER_HEAVYGRAIN, MSG_NAME_WEATHER_GUSTINGRAIN, MSG_NAME_WEATHER_TORRDOWNPOUR,
+ MSG_NAME_WEATHER_LIGHTSNOWFALL, MSG_NAME_WEATHER_MODSNOWFALL, MSG_NAME_WEATHER_SNOWFLUFFIES,
+ MSG_NAME_WEATHER_HEAVYSNOWFALL, MSG_NAME_WEATHER_SLEET, MSG_NAME_WEATHER_ICESTORM };//, "Light Hail", "Heavy Hail", "Lightning Storm" };
public static final int WE_SIZE = weatherNames.length;
+ private static final String MSG_INDICATOR_WEATHER_NONE = Messages.getString("PlanetaryConditions.Indicator.Weather.None");
+ private static final String MSG_INDICATOR_WEATHER_LIGHT_RAIN = Messages.getString("PlanetaryConditions.Indicator.Weather.LightRain");
+ private static final String MSG_INDICATOR_WEATHER_MOD_RAIN = Messages.getString("PlanetaryConditions.Indicator.Weather.ModRain");
+ private static final String MSG_INDICATOR_WEATHER_HEAVY_RAIN = Messages.getString("PlanetaryConditions.Indicator.Weather.HeavyRain");
+ private static final String MSG_INDICATOR_WEATHER_GUSTING_RAIN = Messages.getString("PlanetaryConditions.Indicator.Weather.GustingRain");
+ private static final String MSG_INDICATOR_WEATHER_DOWNPOUR = Messages.getString("PlanetaryConditions.Indicator.Weather.Downpour");
+ private static final String MSG_INDICATOR_WEATHER_LIGHT_SNOW = Messages.getString("PlanetaryConditions.Indicator.Weather.LightSnow");
+ private static final String MSG_INDICATOR_WEATHER_MOD_SNOW = Messages.getString("PlanetaryConditions.Indicator.Weather.ModSnow");
+ private static final String MSG_INDICATOR_WEATHER_SNOW_FLURRIES = Messages.getString("PlanetaryConditions.Indicator.Weather.SnowFlurries");
+ private static final String MSG_INDICATOR_WEATHER_HEAVY_SNOW = Messages.getString("PlanetaryConditions.Indicator.Weather.HeavySnow");
+ private static final String MSG_INDICATOR_WEATHER_SLEET = Messages.getString("PlanetaryConditions.Indicator.Weather.Sleet");
+ private static final String MSG_INDICATOR_WEATHER_ICE_STORM = Messages.getString("PlanetaryConditions.Indicator.Weather.IceStorm");
+ private static String[] weatherIndicators = { MSG_INDICATOR_WEATHER_NONE, MSG_INDICATOR_WEATHER_LIGHT_RAIN, MSG_INDICATOR_WEATHER_MOD_RAIN,
+ MSG_INDICATOR_WEATHER_HEAVY_RAIN, MSG_INDICATOR_WEATHER_GUSTING_RAIN, MSG_INDICATOR_WEATHER_DOWNPOUR,
+ MSG_INDICATOR_WEATHER_LIGHT_SNOW, MSG_INDICATOR_WEATHER_MOD_SNOW, MSG_INDICATOR_WEATHER_SNOW_FLURRIES,
+ MSG_INDICATOR_WEATHER_HEAVY_SNOW, MSG_INDICATOR_WEATHER_SLEET, MSG_INDICATOR_WEATHER_ICE_STORM};
// Wind
public static final int WI_NONE = 0;
@@ -68,15 +109,55 @@ public class PlanetaryConditions implements Serializable {
public static final int WI_STORM = 4;
public static final int WI_TORNADO_F13 = 5;
public static final int WI_TORNADO_F4 = 6;
-
- private static String[] windNames = { "Calm", "Light Gale", "Moderate Gale", "Strong Gale", "Storm", "Tornado F1-F3", "Tornado F4" };
+ private static final String MSG_NAME_WINDSTRENGTH_LIGHT_CALM = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Calm");
+ private static final String MSG_NAME_WINDSTRENGTH_LIGHT_GALE = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Light Gale");
+ private static final String MSG_NAME_WINDSTRENGTH_MOD_GALE = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Moderate Gale");
+ private static final String MSG_NAME_WINDSTRENGTH_STRONG_GALE = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Strong Gale");
+ private static final String MSG_NAME_WINDSTRENGTH_STORM = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Storm");
+ private static final String MSG_NAME_WINDSTRENGTH_TORNADO_F13 = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Tornado F1-F3");
+ private static final String MSG_NAME_WINDSTRENGTH_TORNADO_F4 = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Tornado F4");
+ private static String[] windNames = { MSG_NAME_WINDSTRENGTH_LIGHT_CALM, MSG_NAME_WINDSTRENGTH_LIGHT_GALE,
+ MSG_NAME_WINDSTRENGTH_MOD_GALE, MSG_NAME_WINDSTRENGTH_STRONG_GALE,
+ MSG_NAME_WINDSTRENGTH_STORM, MSG_NAME_WINDSTRENGTH_TORNADO_F13,
+ MSG_NAME_WINDSTRENGTH_TORNADO_F4 };
public static final int WI_SIZE = windNames.length;
+ private static final String MSG_INDICATOR_WINDSTRENGTH_LIGHT_CALM = Messages.getString("PlanetaryConditions.Indicator.WindStrength.Calm");
+ private static final String MSG_INDICATOR_WINDSTRENGTH_LIGHT_GALE = Messages.getString("PlanetaryConditions.Indicator.WindStrength.LightGale");
+ private static final String MSG_INDICATOR_WINDSTRENGTH_MOD_GALE = Messages.getString("PlanetaryConditions.Indicator.WindStrength.ModGale");
+ private static final String MSG_INDICATOR_WINDSTRENGTH_STRONG_GALE = Messages.getString("PlanetaryConditions.Indicator.WindStrength.StrongGale");
+ private static final String MSG_INDICATOR_WINDSTRENGTH_STORM = Messages.getString("PlanetaryConditions.Indicator.WindStrength.Storm");
+ private static final String MSG_INDICATOR_WINDSTRENGTH_TORNADO_F13 = Messages.getString("PlanetaryConditions.Indicator.WindStrength.TornadoF13");
+ private static final String MSG_INDICATOR_WINDSTRENGTH_TORNADO_F4 = Messages.getString("PlanetaryConditions.Indicator.WindStrength.TornadoF4");
+ private static String[] windStrengthIndicators = { MSG_INDICATOR_WINDSTRENGTH_LIGHT_CALM, MSG_INDICATOR_WINDSTRENGTH_LIGHT_GALE,
+ MSG_INDICATOR_WINDSTRENGTH_MOD_GALE, MSG_INDICATOR_WINDSTRENGTH_STRONG_GALE,
+ MSG_INDICATOR_WINDSTRENGTH_STORM, MSG_INDICATOR_WINDSTRENGTH_TORNADO_F13,
+ MSG_INDICATOR_WINDSTRENGTH_TORNADO_F4 };
// wind direction
- private static String[] dirNames = { "North", "Northeast", "Southeast", "South", "Southwest", "Northwest", "RandomWindDirection" };
+ private static final String MSG_NAME_WINDDIRECTION_NORTH = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.North");
+ private static final String MSG_NAME_WINDDIRECTION_NORTHEAST = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.Northeast");
+ private static final String MSG_NAME_WINDDIRECTION_SOUTHEAST = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.Southeast");
+ private static final String MSG_NAME_WINDDIRECTION_SOUTH = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.South");
+ private static final String MSG_NAME_WINDDIRECTION_SOUTHWEST = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.Southwest");
+ private static final String MSG_NAME_WINDDIRECTION_NORTHWEST = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.Northwest");
+ private static final String MSG_NAME_WINDDIRECTION_RANDOM = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.RandomWindDirection");
+ // no east and west, because the map uses 6 side hex tiles. east and west are skipped.
+ private static String[] dirNames = { MSG_NAME_WINDDIRECTION_NORTH, MSG_NAME_WINDDIRECTION_NORTHEAST,
+ MSG_NAME_WINDDIRECTION_SOUTHEAST, MSG_NAME_WINDDIRECTION_SOUTH, MSG_NAME_WINDDIRECTION_SOUTHWEST,
+ MSG_NAME_WINDDIRECTION_NORTHWEST, MSG_NAME_WINDDIRECTION_RANDOM };
public static final int DIR_SIZE = dirNames.length;
public static final int DIR_RANDOM = 6;
-
+ private static final String MSG_INDICATOR_WINDDIRECTION_NORTH = Messages.getString("PlanetaryConditions.Indicator.WindDirection.North");
+ private static final String MSG_INDICATOR_WINDDIRECTION_NORTHEAST = Messages.getString("PlanetaryConditions.Indicator.WindDirection.Northeast");
+ private static final String MSG_INDICATOR_WINDDIRECTION_SOUTHEAST = Messages.getString("PlanetaryConditions.Indicator.WindDirection.Southeast");
+ private static final String MSG_INDICATOR_WINDDIRECTION_SOUTH = Messages.getString("PlanetaryConditions.Indicator.WindDirection.South");
+ private static final String MSG_INDICATOR_WINDDIRECTION_SOUTHWEST = Messages.getString("PlanetaryConditions.Indicator.WindDirection.Southwest");
+ private static final String MSG_INDICATOR_WINDDIRECTION_NORTHWEST = Messages.getString("PlanetaryConditions.Indicator.WindDirection.Northwest");
+ private static final String MSG_INDICATOR_WINDDIRECTION_RANDOM = Messages.getString("PlanetaryConditions.Indicator.WindDirection.RandomWindDirection");
+ // no east and west, because the map uses 6 side hex tiles. east and west are skipped.
+ private static String[] windDirectionIndicators = { MSG_INDICATOR_WINDDIRECTION_NORTH, MSG_INDICATOR_WINDDIRECTION_NORTHEAST,
+ MSG_INDICATOR_WINDDIRECTION_SOUTHEAST, MSG_INDICATOR_WINDDIRECTION_SOUTH, MSG_INDICATOR_WINDDIRECTION_SOUTHWEST,
+ MSG_INDICATOR_WINDDIRECTION_NORTHWEST, MSG_INDICATOR_WINDDIRECTION_RANDOM };
// atmospheric pressure
public static final int ATMO_VACUUM = 0;
@@ -85,20 +166,45 @@ public class PlanetaryConditions implements Serializable {
public static final int ATMO_STANDARD = 3;
public static final int ATMO_HIGH = 4;
public static final int ATMO_VHIGH = 5;
-
- public static String[] atmoNames = { "Vacuum", "Trace", "Thin", "Standard", "High", "Very High" };
+ private static final String MSG_NAME_ATMOSPHERE_VACUUM = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.Vacuum");
+ private static final String MSG_NAME_ATMOSPHERE_TRACE = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.Trace");
+ private static final String MSG_NAME_ATMOSPHERE_THIN = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.Thin");
+ private static final String MSG_NAME_ATMOSPHERE_STANDARD = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.Standard");
+ private static final String MSG_NAME_ATMOSPHERE_HIGH = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.High");
+ private static final String MSG_NAME_ATMOSPHERE_VHIGH = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.Very High");
+ public static String[] atmoNames = { MSG_NAME_ATMOSPHERE_VACUUM, MSG_NAME_ATMOSPHERE_TRACE, MSG_NAME_ATMOSPHERE_THIN,
+ MSG_NAME_ATMOSPHERE_STANDARD, MSG_NAME_ATMOSPHERE_HIGH, MSG_NAME_ATMOSPHERE_VHIGH };
public static final int ATMO_SIZE = atmoNames.length;
+ private static final String MSG_INDICATOR_ATMOSPHERE_VACUUM = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.Vacuum");
+ private static final String MSG_INDICATOR_ATMOSPHERE_TRACE = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.Trace");
+ private static final String MSG_INDICATOR_ATMOSPHERE_THIN = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.Thin");
+ private static final String MSG_INDICATOR_ATMOSPHERE_STANDARD = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.Standard");
+ private static final String MSG_INDICATOR_ATMOSPHERE_HIGH = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.High");
+ private static final String MSG_INDICATOR_ATMOSPHERE_VHIGH = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.VHigh");
+ private static String[] atmosphereIndicators = { MSG_INDICATOR_ATMOSPHERE_VACUUM, MSG_INDICATOR_ATMOSPHERE_TRACE, MSG_INDICATOR_ATMOSPHERE_THIN,
+ MSG_INDICATOR_ATMOSPHERE_STANDARD ,MSG_INDICATOR_ATMOSPHERE_HIGH ,MSG_INDICATOR_ATMOSPHERE_VHIGH };
// fog
public static final int FOG_NONE = 0;
public static final int FOG_LIGHT = 1;
public static final int FOG_HEAVY = 2;
-
- private static String[] fogNames = { "None", "Light Fog", "Heavy Fog" };
+ private static final String MSG_NAME_FOG_NONE = Messages.getString("PlanetaryConditions.DisplayableName.Fog.None");
+ private static final String MSG_NAME_FOG_LIGHT = Messages.getString("PlanetaryConditions.DisplayableName.Fog.Light Fog");
+ private static final String MSG_NAME_FOG_HEAVY = Messages.getString("PlanetaryConditions.DisplayableName.Fog.Heavy Fog");
+ private static String[] fogNames = { MSG_NAME_FOG_NONE, MSG_NAME_FOG_LIGHT, MSG_NAME_FOG_HEAVY };
public static final int FOG_SIZE = fogNames.length;
+ private static final String MSG_INDICATOR_FOG_NONE = Messages.getString("PlanetaryConditions.Indicator.Fog.None");
+ private static final String MSG_INDICATOR_FOG_LIGHT = Messages.getString("PlanetaryConditions.Indicator.Fog.Light");
+ private static final String MSG_INDICATOR_FOG_HEAVY = Messages.getString("PlanetaryConditions.Indicator.Fog.Heavy");
+ private static String[] fogIndicators = { MSG_INDICATOR_FOG_NONE, MSG_INDICATOR_FOG_LIGHT, MSG_INDICATOR_FOG_HEAVY };
// misc
private boolean blowingSand = false;
+ private static final String MSG_NAME_BLOWINGSAND_TRUE = Messages.getString("PlanetaryConditions.DisplayableName.SandBlowing.true");
+ private static final String MSG_NAME_BLOWINGSAND_FALSE = Messages.getString("PlanetaryConditions.DisplayableName.SandBlowing.false");
+ private static final String MSG_INDICATOR_BLOWINGSAND_TRUE = Messages.getString("PlanetaryConditions.Indicator.SandBlowing.true");
+ private static final String MSG_INDICATOR_BLOWINGSAND_FALSE = Messages.getString("PlanetaryConditions.Indicator.SandBlowing.false");
+
private boolean sandStorm = false;
private boolean runOnce = false;
@@ -115,8 +221,20 @@ public class PlanetaryConditions implements Serializable {
private int fog = FOG_NONE;
private int temperature = 25;
private int oldTemperature = 25;
+ private static final String MSG_NAME_TEMPERATURE_COLD = Messages.getString("PlanetaryConditions.DisplayableName.Temperature.ExtremeCold");
+ private static final String MSG_NAME_TEMPERATURE_HEAT = Messages.getString("PlanetaryConditions.DisplayableName.Temperature.ExtremeHeat");
+ private static final String MSG_INDICATOR_TEMPERATURE_COLD = Messages.getString("PlanetaryConditions.Indicator.Temperature.ExtremeCold");
+ private static final String MSG_INDICATOR_TEMPERATURE_HEAT= Messages.getString("PlanetaryConditions.Indicator.Temperature.ExtremeHeat");
+ private static final String MSG_INDICATOR_TEMPERATURE_NORMAL = Messages.getString("PlanetaryConditions.Indicator.Temperature.Normal");
private float gravity = (float) 1.0;
+ private static final String MSG_INDICATOR_GRAVITY_LOW= Messages.getString("PlanetaryConditions.Indicator.Gravity.Low");
+ private static final String MSG_INDICATOR_GRAVITY_NORMAL = Messages.getString("PlanetaryConditions.Indicator.Gravity.Normal");
+ private static final String MSG_INDICATOR_GRAVITY_HIGH = Messages.getString("PlanetaryConditions.Indicator.Gravity.High");
private boolean emi = false;
+ private static final String MSG_NAME_EMI_TRUE = Messages.getString("PlanetaryConditions.DisplayableName.EMI.true");
+ private static final String MSG_NAME_EMI_FALSE = Messages.getString("PlanetaryConditions.DisplayableName.EMI.false");
+ private static final String MSG_INDICATOR_EMI_TRUE = Messages.getString("PlanetaryConditions.Indicator.EMI.true");
+ private static final String MSG_INDICATOR_EMI_FALSE = Messages.getString("PlanetaryConditions.Indicator.EMI.false");
private boolean terrainAffected = true;
private int maxWindStrength = PlanetaryConditions.WI_TORNADO_F4;
private int minWindStrength = PlanetaryConditions.WI_NONE;
@@ -156,23 +274,23 @@ public Object clone() {
public static String getLightDisplayableName(int type) {
if ((type >= 0) && (type < L_SIZE)) {
- return Messages.getString("PlanetaryConditions." + lightNames[type]);
+ return lightNames[type];
}
throw new IllegalArgumentException("Unknown light condition");
}
public static String getWeatherDisplayableName(int type) {
if ((type >= 0) && (type < WE_SIZE)) {
- return Messages.getString("PlanetaryConditions." + weatherNames[type]);
+ return weatherNames[type];
}
throw new IllegalArgumentException("Unknown weather condition");
}
public static String getTemperatureDisplayableName(int temp) {
if (isExtremeTemperature(temp) && (temp > 0)) {
- return String.format("%d (%s)", temp, Messages.getString("PlanetaryConditions.ExtremeHeat"));
+ return String.format("%d (%s)", temp, MSG_NAME_TEMPERATURE_HEAT);
} else if (isExtremeTemperature(temp) && (temp <= 0)) {
- return String.format("%d (%s)", temp, Messages.getString("PlanetaryConditions.ExtremeCold"));
+ return String.format("%d (%s)", temp, MSG_NAME_TEMPERATURE_COLD);
} else {
return String.valueOf(temp);
}
@@ -180,28 +298,28 @@ public static String getTemperatureDisplayableName(int temp) {
public static String getWindDirDisplayableName(int type) {
if ((type >= 0) && (type < DIR_SIZE)) {
- return Messages.getString("PlanetaryConditions." + dirNames[type]);
+ return dirNames[type];
}
throw new IllegalArgumentException("Unknown wind direction");
}
public static String getWindDisplayableName(int type) {
if ((type >= 0) && (type < WI_SIZE)) {
- return Messages.getString("PlanetaryConditions." + windNames[type]);
+ return windNames[type];
}
throw new IllegalArgumentException("Unknown wind condition");
}
public static String getAtmosphereDisplayableName(int type) {
if ((type >= 0) && (type < ATMO_SIZE)) {
- return Messages.getString("PlanetaryConditions." + atmoNames[type]);
+ return atmoNames[type];
}
throw new IllegalArgumentException("Unknown atmospheric pressure condition");
}
public static String getFogDisplayableName(int type) {
if ((type >= 0) && (type < FOG_SIZE)) {
- return Messages.getString("PlanetaryConditions." + fogNames[type]);
+ return fogNames[type];
}
throw new IllegalArgumentException("Unknown fog condition");
}
@@ -1046,4 +1164,117 @@ private void doSandStormCheck() {
public void setRunOnce(boolean run) {
runOnce = run;
}
+
+ public boolean isExtremeTemperatureHeat() {
+ return (isExtremeTemperature() && (temperature > 0));
+ }
+
+ public boolean isExtremeTemperatureCold() {
+ return (isExtremeTemperature() && (temperature < 0));
+ }
+
+ public String getLightIndicator(int type) {
+ if ((type >= 0) && (type < L_SIZE)) {
+ return lightIndicators[type];
+ }
+ throw new IllegalArgumentException("Unknown light Indicator");
+ }
+
+ public String getLightIndicator() {
+ return getLightIndicator(lightConditions);
+ }
+
+ public String getFogIndicator(int type) {
+ if ((type >= 0) && (type < FOG_SIZE)) {
+ return fogIndicators[type];
+ }
+ throw new IllegalArgumentException("Unknown Fog Indicator");
+ }
+
+ public String getFogIndicator() {
+ return getFogIndicator(fog);
+ }
+
+ public String getWindStrengthIndicator(int type) {
+ if ((type >= 0) && (type < WI_SIZE)) {
+ return windStrengthIndicators[type];
+ }
+ throw new IllegalArgumentException("Unknown Wind Strength Indicator");
+ }
+
+ public String getWindStrengthIndicator() {
+ return getWindStrengthIndicator(windStrength);
+ }
+
+ public String getWindDirectionIndicator(int type) {
+ if ((type >= 0) && (type < DIR_SIZE)) {
+ return windDirectionIndicators[type];
+ }
+ throw new IllegalArgumentException("Unknown Wind Direction Indicator");
+ }
+
+ public String getWindDirectionIndicator() {
+ return getWindDirectionIndicator(windDirection);
+ }
+
+ public String getWeatherIndicator(int type) {
+ if ((type >= 0) && (type < WE_SIZE)) {
+ return weatherIndicators[type];
+ }
+ throw new IllegalArgumentException("Unknown Weather Indicator");
+ }
+
+ public String getWeatherIndicator() {
+ return getWeatherIndicator(weatherConditions);
+ }
+
+ public String getAtmosphereIndicator(int type) {
+ if ((type >= 0) && (type < ATMO_SIZE)) {
+ return atmosphereIndicators[type];
+ }
+ throw new IllegalArgumentException("Unknown Atmosphere Indicator");
+ }
+
+ public String getAtmosphereIndicator() {
+ return getAtmosphereIndicator(atmosphere);
+ }
+
+ public String getGravityIndicator() {
+ if (gravity > 1.0) {
+ return MSG_INDICATOR_GRAVITY_HIGH;
+ }
+ else if ((gravity < 1.0)) {
+ return MSG_INDICATOR_GRAVITY_LOW;
+ }
+
+ return MSG_INDICATOR_GRAVITY_NORMAL;
+ }
+
+ public String getTemperatureIndicator() {
+ if (isExtremeTemperatureHeat()) {
+ return MSG_INDICATOR_TEMPERATURE_HEAT;
+ }
+ else if (isExtremeTemperatureCold()) {
+ return MSG_INDICATOR_TEMPERATURE_COLD;
+ }
+
+ return MSG_INDICATOR_TEMPERATURE_NORMAL;
+ }
+
+ public String getEMIIndicator() {
+ return hasEMI() ? MSG_INDICATOR_EMI_TRUE : MSG_INDICATOR_EMI_FALSE;
+ }
+
+ public String getSandBlowingIndicator() {
+ return hasEMI() ? MSG_INDICATOR_BLOWINGSAND_TRUE : MSG_INDICATOR_BLOWINGSAND_FALSE;
+ }
+
+ public String getEMIDisplayableValue() {
+ return hasEMI() ? MSG_NAME_EMI_TRUE : MSG_NAME_EMI_FALSE;
+ }
+
+ public String getSandBlowingDisplayableValue() {
+ return isSandBlowing() ? MSG_NAME_BLOWINGSAND_TRUE : MSG_NAME_BLOWINGSAND_FALSE;
+ }
+
}
diff --git a/megamek/src/megamek/common/Player.java b/megamek/src/megamek/common/Player.java
index d19e530fb46..dc2623e863d 100644
--- a/megamek/src/megamek/common/Player.java
+++ b/megamek/src/megamek/common/Player.java
@@ -14,7 +14,6 @@
package megamek.common;
import megamek.client.ui.swing.util.PlayerColour;
-import megamek.common.enums.GamePhase;
import megamek.common.event.GamePlayerChangeEvent;
import megamek.common.icons.Camouflage;
import megamek.common.options.OptionsConstants;
@@ -272,7 +271,7 @@ public void setGameMaster(boolean gameMaster) {
/** @return true if {@link #observer} flag is true and not in VICTORY phase*/
public boolean isObserver() {
- if ((game != null) && (game.getPhase() == GamePhase.VICTORY)) {
+ if ((game != null) && game.getPhase().isVictory()) {
return false;
}
return observer;
diff --git a/megamek/src/megamek/common/ReportMessages.java b/megamek/src/megamek/common/ReportMessages.java
index f7b05579630..b0f82998381 100755
--- a/megamek/src/megamek/common/ReportMessages.java
+++ b/megamek/src/megamek/common/ReportMessages.java
@@ -14,7 +14,6 @@
package megamek.common;
import megamek.MegaMek;
-import megamek.common.util.EncodeControl;
import java.text.MessageFormat;
import java.util.MissingResourceException;
@@ -22,7 +21,7 @@
public class ReportMessages {
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle("megamek.common.report-messages",
- MegaMek.getMMOptions().getLocale(), new EncodeControl());
+ MegaMek.getMMOptions().getLocale());
private ReportMessages() {
}
diff --git a/megamek/src/megamek/common/SmallCraft.java b/megamek/src/megamek/common/SmallCraft.java
index f022ec4bdb5..f2aa4b5d641 100644
--- a/megamek/src/megamek/common/SmallCraft.java
+++ b/megamek/src/megamek/common/SmallCraft.java
@@ -904,4 +904,9 @@ protected int calculateWalk() {
public boolean isLargeAerospace() {
return true;
}
+
+ @Override
+ public int getLandingLength() {
+ return 8;
+ }
}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/Tank.java b/megamek/src/megamek/common/Tank.java
index 174851a5bad..4cf67bd1a60 100644
--- a/megamek/src/megamek/common/Tank.java
+++ b/megamek/src/megamek/common/Tank.java
@@ -319,7 +319,7 @@ public int getWalkMP(boolean gravity, boolean ignoreheat,
@Override
public boolean isEligibleForPavementBonus() {
- return movementMode == EntityMovementMode.TRACKED || movementMode == EntityMovementMode.WHEELED;
+ return movementMode == EntityMovementMode.TRACKED || movementMode == EntityMovementMode.WHEELED || movementMode == EntityMovementMode.HOVER;
}
public boolean isTurretLocked(int turret) {
@@ -3040,4 +3040,9 @@ public boolean isTractor() {
public boolean isCombatVehicle() {
return !isSupportVehicle();
}
+
+ @Override
+ public boolean getsAutoExternalSearchlight() {
+ return true;
+ }
}
diff --git a/megamek/src/megamek/common/Terrain.java b/megamek/src/megamek/common/Terrain.java
index e5067f0ee77..dd278d848b9 100644
--- a/megamek/src/megamek/common/Terrain.java
+++ b/megamek/src/megamek/common/Terrain.java
@@ -440,8 +440,10 @@ public int movementCost(Entity e) {
}
return 1;
}
- if ((moveMode == EntityMovementMode.WHEELED) || (moveMode == EntityMovementMode.INF_JUMP)
- || (moveMode == EntityMovementMode.INF_LEG) || (moveMode == EntityMovementMode.INF_MOTORIZED)) {
+ if ((moveMode == EntityMovementMode.WHEELED) || (e.isConventionalInfantry() &&
+ ((moveMode == EntityMovementMode.INF_JUMP)
+ || (moveMode == EntityMovementMode.INF_LEG)
+ || (moveMode == EntityMovementMode.INF_MOTORIZED)))) {
return 1;
}
return 0;
diff --git a/megamek/src/megamek/common/WeaponType.java b/megamek/src/megamek/common/WeaponType.java
index c16a2588bbe..b20192fd5f8 100644
--- a/megamek/src/megamek/common/WeaponType.java
+++ b/megamek/src/megamek/common/WeaponType.java
@@ -1249,6 +1249,14 @@ public static void initializeTypes() {
EquipmentType.addType(new ISThunderBolt10());
EquipmentType.addType(new ISThunderBolt15());
EquipmentType.addType(new ISThunderBolt20());
+ EquipmentType.addType(new ISThunderbolt5OS());
+ EquipmentType.addType(new ISThunderbolt10OS());
+ EquipmentType.addType(new ISThunderbolt15OS());
+ EquipmentType.addType(new ISThunderbolt20OS());
+ EquipmentType.addType(new ISThunderbolt5IOS());
+ EquipmentType.addType(new ISThunderbolt10IOS());
+ EquipmentType.addType(new ISThunderbolt15IOS());
+ EquipmentType.addType(new ISThunderbolt20IOS());
// Taser
EquipmentType.addType(new ISMekTaser());
diff --git a/megamek/src/megamek/common/actions/WeaponAttackAction.java b/megamek/src/megamek/common/actions/WeaponAttackAction.java
index b3d4d2ee6ae..f55d4df1014 100644
--- a/megamek/src/megamek/common/actions/WeaponAttackAction.java
+++ b/megamek/src/megamek/common/actions/WeaponAttackAction.java
@@ -18,7 +18,6 @@
import megamek.client.ui.Messages;
import megamek.common.*;
import megamek.common.enums.AimingMode;
-import megamek.common.enums.GamePhase;
import megamek.common.options.OptionsConstants;
import megamek.common.weapons.InfantryAttack;
import megamek.common.weapons.Weapon;
@@ -352,17 +351,15 @@ private static ToHitData toHit(Game game, int attackerId, Targetable target, int
boolean isArtilleryDirect = (wtype.hasFlag(WeaponType.F_ARTILLERY) ||
(wtype instanceof CapitalMissileWeapon
&& Compute.isGroundToGround(ae, target)))
- && (game.getPhase() == GamePhase.FIRING);
+ && game.getPhase().isFiring();
boolean isArtilleryIndirect = (wtype.hasFlag(WeaponType.F_ARTILLERY) ||
(wtype instanceof CapitalMissileWeapon
&& Compute.isGroundToGround(ae, target)))
- && ((game.getPhase() == GamePhase.TARGETING)
- || (game.getPhase() == GamePhase.OFFBOARD));
+ && (game.getPhase().isTargeting() || game.getPhase().isOffboard());
boolean isBearingsOnlyMissile = (weapon.isInBearingsOnlyMode())
- && ((game.getPhase() == GamePhase.TARGETING)
- || (game.getPhase() == GamePhase.FIRING));
+ && (game.getPhase().isTargeting() || game.getPhase().isFiring());
boolean isCruiseMissile = (weapon.getType().hasFlag(WeaponType.F_CRUISE_MISSILE)
|| (wtype instanceof CapitalMissileWeapon
@@ -1288,15 +1285,15 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta
// Phase Reasons
// Only bearings-only capital missiles and indirect fire artillery can be fired in the targeting phase
- if ((game.getPhase() == GamePhase.TARGETING) && (!(isArtilleryIndirect || isBearingsOnlyMissile))) {
+ if (game.getPhase().isTargeting() && (!(isArtilleryIndirect || isBearingsOnlyMissile))) {
return Messages.getString("WeaponAttackAction.NotValidForTargPhase");
}
// Only TAG can be fired in the offboard phase
- if ((game.getPhase() == GamePhase.OFFBOARD) && !isTAG) {
+ if (game.getPhase().isOffboard() && !isTAG) {
return Messages.getString("WeaponAttackAction.OnlyTagInOffboard");
}
// TAG can't be fired in any phase but offboard
- if ((game.getPhase() != GamePhase.OFFBOARD) && isTAG) {
+ if (!game.getPhase().isOffboard() && isTAG) {
return Messages.getString("WeaponAttackAction.TagOnlyInOffboard");
}
@@ -2087,7 +2084,7 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta
return Messages.getString("WeaponAttackAction.OutOfRange");
}
// Can't fire in bearings-only mode within direct-fire range (50 hexes)
- if (game.getPhase() == GamePhase.TARGETING && distance < RangeType.RANGE_BEARINGS_ONLY_MINIMUM) {
+ if (game.getPhase().isTargeting() && distance < RangeType.RANGE_BEARINGS_ONLY_MINIMUM) {
return Messages.getString("WeaponAttackAction.BoMissileMinRange");
}
// Can't target anything but hexes
@@ -2566,7 +2563,7 @@ private static String toHitIsAutomatic(Game game, Entity ae, Targetable target,
// Capital Missiles in bearings-only mode target hexes and always hit them
if (isBearingsOnlyMissile) {
- if (game.getPhase() == GamePhase.TARGETING && distance >= RangeType.RANGE_BEARINGS_ONLY_MINIMUM) {
+ if (game.getPhase().isTargeting() && (distance >= RangeType.RANGE_BEARINGS_ONLY_MINIMUM)) {
return Messages.getString("WeaponAttackAction.BoMissileHex");
}
}
@@ -4615,7 +4612,7 @@ private static ToHitData handleSpecialWeaponAttacks(Game game, Entity ae, Target
// Battle Armor bomb racks (Micro bombs) use gunnery skill and no other mods per TWp228 2018 errata
if ((atype != null) && (atype.getAmmoType() == AmmoType.T_BA_MICRO_BOMB)) {
if (ae.getPosition().equals(target.getPosition())) {
- toHit = new ToHitData(ae.getCrew().getPiloting(), Messages.getString("WeaponAttackAction.GunSkill"));
+ toHit = new ToHitData(ae.getCrew().getGunnery(), Messages.getString("WeaponAttackAction.GunSkill"));
} else {
toHit = new ToHitData(TargetRoll.IMPOSSIBLE, Messages.getString("WeaponAttackAction.OutOfRange"));
}
diff --git a/megamek/src/megamek/common/alphaStrike/AlphaStrikeHelper.java b/megamek/src/megamek/common/alphaStrike/AlphaStrikeHelper.java
index 0ae011b1ebc..35f4c10abb5 100644
--- a/megamek/src/megamek/common/alphaStrike/AlphaStrikeHelper.java
+++ b/megamek/src/megamek/common/alphaStrike/AlphaStrikeHelper.java
@@ -140,7 +140,7 @@ public static boolean hideSpecial(BattleForceSUA sua, ASCardDisplayable element)
|| (element.isLargeAerospace() && (sua == STD))
|| (element.usesCapitalWeapons() && sua.isAnyOf(MSL, SCAP, CAP))
|| (element.isType(BM, PM) && (sua == SOA))
- || (element.isType(CV, BM) && (sua == SRCH))
+ || (element.isBattleMek() && (sua == SRCH))
|| (!element.isLargeAerospace() && sua.isDoor())
|| (hasAutoSeal(element) && (sua == SEAL));
}
diff --git a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java
index 345b5a93b47..281ed983d89 100644
--- a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java
+++ b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java
@@ -18,11 +18,14 @@
*/
package megamek.common.alphaStrike.cardDrawer;
+import megamek.MMConstants;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.util.FluffImageHelper;
import megamek.client.ui.swing.util.StringDrawer;
import megamek.common.Configuration;
-import megamek.common.alphaStrike.*;
+import megamek.common.alphaStrike.ASCardDisplayable;
+import megamek.common.alphaStrike.ASDamageVector;
+import megamek.common.alphaStrike.AlphaStrikeHelper;
import megamek.common.annotations.Nullable;
import megamek.common.util.ImageUtil;
import megamek.common.util.fileUtils.MegaMekFile;
@@ -67,9 +70,9 @@ public class ASCard {
protected final ASCardDisplayable element;
protected final Image fluffImage;
- protected Font lightFont = new Font(Font.SANS_SERIF, Font.PLAIN, 14);
- protected Font boldFont = new Font(Font.SANS_SERIF, Font.BOLD, 14);
- protected Font blackFont = new Font(Font.SANS_SERIF, Font.BOLD, 14);
+ protected Font lightFont = new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 14);
+ protected Font boldFont = new Font(MMConstants.FONT_SANS_SERIF, Font.BOLD, 14);
+ protected Font blackFont = new Font(MMConstants.FONT_SANS_SERIF, Font.BOLD, 14);
protected Font modelFont;
protected Font chassisFont;
@@ -515,7 +518,7 @@ protected void paintCardBackground(Graphics2D g, boolean isFlipSide) {
}
new StringDrawer("(C) " + LocalDate.now().getYear() + " The Topps Company. All rights reserved.").at(1014, copyrightY).rotate(-Math.PI / 2)
- .font(new Font(Font.SANS_SERIF, Font.PLAIN, 12)).center().draw(g);
+ .font(new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 12)).center().draw(g);
// Border
g.setColor(Color.BLACK);
diff --git a/megamek/src/megamek/common/alphaStrike/conversion/ASBattleArmorDamageConverter.java b/megamek/src/megamek/common/alphaStrike/conversion/ASBattleArmorDamageConverter.java
index 2f989754f0b..9f44379eeeb 100644
--- a/megamek/src/megamek/common/alphaStrike/conversion/ASBattleArmorDamageConverter.java
+++ b/megamek/src/megamek/common/alphaStrike/conversion/ASBattleArmorDamageConverter.java
@@ -98,8 +98,8 @@ protected double[] assembleSpecialDamage(BattleForceSUA dmgType, int location) {
}
@Override
- protected int[] assembleHeatDamage() {
- int[] heatDmg = super.assembleHeatDamage();
+ protected int[] assembleHeatDamage(int location) {
+ int[] heatDmg = super.assembleHeatDamage(location);
String rawValues = formatAsVector(heatDmg[0], heatDmg[1], heatDmg[2], 0, HT);
heatDmg[0] *= troopFactor;
heatDmg[1] *= troopFactor;
diff --git a/megamek/src/megamek/common/alphaStrike/conversion/ASConvInfantryDamageConverter.java b/megamek/src/megamek/common/alphaStrike/conversion/ASConvInfantryDamageConverter.java
index a2f95599228..4c21dda66a0 100644
--- a/megamek/src/megamek/common/alphaStrike/conversion/ASConvInfantryDamageConverter.java
+++ b/megamek/src/megamek/common/alphaStrike/conversion/ASConvInfantryDamageConverter.java
@@ -42,27 +42,35 @@ protected ASConvInfantryDamageConverter(Entity entity, AlphaStrikeElement elemen
@Override
protected void processDamage() {
- report.addEmptyLine();
- report.addLine("--- Damage:", "");
- int baseRange = 0;
- if ((infantry.getSecondaryWeapon() != null) && (infantry.getSecondaryWeaponsPerSquad() >= 2)) {
- baseRange = infantry.getSecondaryWeapon().getInfantryRange();
- } else if (infantry.getPrimaryWeapon() != null) {
- baseRange = infantry.getPrimaryWeapon().getInfantryRange();
- }
- int range = baseRange * 3;
- finalSDamage = ASDamage.createDualRoundedUp(getConvInfantryStandardDamage());
- String maxRangeText = "Range: S";
- if (range > 3) {
- finalMDamage = finalSDamage;
- maxRangeText = "Ranges: S, M";
- }
- if (range > 15) {
- finalLDamage = finalSDamage;
- maxRangeText = "Ranges: S, M, L";
+ if (infantry.hasFieldWeapon()) {
+ processSDamage();
+ processMDamage();
+ processLDamage();
+ processFrontSpecialDamage(AC);
+ processFrontSpecialDamage(FLK);
+ } else {
+ int baseRange = 0;
+ if ((infantry.getSecondaryWeapon() != null) && (infantry.getSecondaryWeaponsPerSquad() >= 2)) {
+ baseRange = infantry.getSecondaryWeapon().getInfantryRange();
+ } else if (infantry.getPrimaryWeapon() != null) {
+ baseRange = infantry.getPrimaryWeapon().getInfantryRange();
+ }
+ int range = baseRange * 3;
+ String maxRangeText;
+ finalSDamage = ASDamage.createDualRoundedUp(getConvInfantryStandardDamage());
+ if (range > 15) {
+ finalLDamage = finalSDamage;
+ finalMDamage = finalSDamage;
+ maxRangeText = "Ranges: S, M, L";
+ } else if (range > 3) {
+ finalMDamage = finalSDamage;
+ maxRangeText = "Ranges: S, M";
+ } else {
+ maxRangeText = "Range: S";
+ }
+ report.addLine("Final Damage", "", finalSDamage + "");
+ report.addLine("Range:", range + " hexes", maxRangeText);
}
- report.addLine("Final Damage", "", finalSDamage + "");
- report.addLine("Range:", range + " hexes", maxRangeText);
processHT();
}
diff --git a/megamek/src/megamek/common/alphaStrike/conversion/ASDamageConverter.java b/megamek/src/megamek/common/alphaStrike/conversion/ASDamageConverter.java
index da01ec8c12d..0343d744cc4 100644
--- a/megamek/src/megamek/common/alphaStrike/conversion/ASDamageConverter.java
+++ b/megamek/src/megamek/common/alphaStrike/conversion/ASDamageConverter.java
@@ -54,7 +54,7 @@ public class ASDamageConverter {
protected int rearLocation;
protected int turretLocation;
- private final Map ammoForWeapon = new HashMap<>();
+ private final Map ammoModifier = new HashMap<>();
protected final boolean hasTargetingComputer;
protected List weaponsList;
protected double rawSDamage;
@@ -163,6 +163,7 @@ protected void processTurrets() {
processSpecialDamage(IATM, turretLocation);
processSpecialDamage(TOR, turretLocation);
processSpecialDamage(REL, turretLocation);
+ processHT(turretLocation);
}
}
@@ -357,7 +358,7 @@ protected void processEDamage() { }
protected double getDamageMultiplier(Mounted weapon, WeaponType weaponType) {
// Low ammo count
- double damageModifier = ammoForWeapon.getOrDefault(weaponType, true) ? 1 : 0.75;
+ double damageModifier = ammoModifier.getOrDefault(weaponType, 1d);
// Oneshot or Fusillade
if (weaponType.hasFlag(WeaponType.F_ONESHOT) && !(weaponType instanceof CLFussilade)) {
@@ -408,7 +409,14 @@ protected void assembleAmmoCounts() {
|| weaponType.getAmmoType() == AmmoType.T_AC_ULTRA_THB) {
divisor = 2;
}
- ammoForWeapon.put(weaponType, ammoCount / weaponCount.get(weaponType) >= 10 * divisor);
+
+ if (ammoCount / weaponCount.get(weaponType) >= 10 * divisor) {
+ ammoModifier.put(weaponType, 1d);
+ } else if (ammoCount > 0) {
+ ammoModifier.put(weaponType, 0.75);
+ } else {
+ ammoModifier.put(weaponType, 0d);
+ }
}
}
@@ -529,24 +537,29 @@ protected void reportAssignToLocations(Mounted weapon, BattleForceSUA sua, Strin
/** Determines if the element has the HT ability and what the value is. Overridden for CI. */
protected void processHT() {
+ processHT(0);
+ }
+
+ /** Determines if the element has the HT ability and what the value is. Overridden for CI. */
+ protected void processHT(int location) {
report.startTentativeSection();
report.addEmptyLine();
report.addLine("--- Heat Damage (HT):", "");
- int[] heatDamageValues = assembleHeatDamage();
+ int[] heatDamageValues = assembleHeatDamage(location);
if (heatDamageValues[0] + heatDamageValues[1] + heatDamageValues[2] > 0) {
- determineFinalHT(heatDamageValues);
+ determineFinalHT(heatDamageValues, location);
report.endTentativeSection();
} else {
report.discardTentativeSection();
}
}
- protected int[] assembleHeatDamage() {
+ protected int[] assembleHeatDamage(int location) {
int totalHeatS = 0;
int totalHeatM = 0;
int totalHeatL = 0;
for (Mounted weapon : weaponsList) {
- double locationMultiplier = ASLocationMapper.damageLocationMultiplier(entity, 0, weapon);
+ double locationMultiplier = ASLocationMapper.damageLocationMultiplier(entity, location, weapon);
WeaponType weaponType = (WeaponType) weapon.getType();
int heatS = weaponType.getAlphaStrikeHeatDamage(RANGE_BAND_SHORT);
int heatM = weaponType.getAlphaStrikeHeatDamage(RANGE_BAND_MEDIUM);
@@ -564,13 +577,13 @@ protected int[] assembleHeatDamage() {
return new int[] {totalHeatS, totalHeatM, totalHeatL};
}
- protected void determineFinalHT(int[] heatDamageValues) {
+ protected void determineFinalHT(int[] heatDamageValues, int location) {
int htS = resultingHTValue(heatDamageValues[0]);
int htM = resultingHTValue(heatDamageValues[1]);
int htL = resultingHTValue(heatDamageValues[2]);
if (htS + htM + htL > 0) {
ASDamageVector finalHtValue = ASDamageVector.createNormRndDmg(htS, htM, htL);
- locations[0].setSUA(HT, finalHtValue);
+ locations[location].setSUA(HT, finalHtValue);
report.addLine("Final Ability", "", "HT" + finalHtValue);
} else {
report.addLine("Final Ability", "No HT", "");
@@ -719,9 +732,11 @@ protected double determineSpecialsDamage(WeaponType weaponType, Mounted linked,
* Only used for the damage specials LRM, SRM, TOR, IATM, AC, FLK
*/
protected static boolean qualifiesForSpecial(double[] damage, BattleForceSUA dmgType) {
- if (dmgType.isAnyOf(FLK, TOR, IF, REAR, TUR, MSL, CAP, SCAP, STD, PNT)
+ if (dmgType.isAnyOf(FLK, TOR, REAR, TUR, MSL, CAP, SCAP, STD, PNT)
&& damage[0] + damage[1] + damage[2] + damage[3] > 0) {
return true;
+ } else if (dmgType == IF) {
+ return damage[2] > 0;
} else {
return roundUpToTenth(damage[1]) >= 1;
}
diff --git a/megamek/src/megamek/common/alphaStrike/conversion/ASLocationMapper.java b/megamek/src/megamek/common/alphaStrike/conversion/ASLocationMapper.java
index 92ad9dd2dc4..7847fb6039f 100644
--- a/megamek/src/megamek/common/alphaStrike/conversion/ASLocationMapper.java
+++ b/megamek/src/megamek/common/alphaStrike/conversion/ASLocationMapper.java
@@ -57,9 +57,6 @@ static int damageLocationsCount(Entity en) {
public static double damageLocationMultiplier(Entity en, int loc, Mounted mount) {
if (locationName(en, loc).startsWith("TUR") && (en instanceof Mech) && mount.isMechTurretMounted()) {
return 1;
- } else if (locationName(en, loc).startsWith("TUR") && (en instanceof Tank)
- && (mount.isPintleTurretMounted() || mount.isSponsonTurretMounted())) {
- return 1;
} else if (en instanceof Warship) {
return getWarShipLocationMultiplier(loc, mount.getLocation());
} else if (en instanceof Jumpship) {
@@ -81,7 +78,8 @@ public static double damageLocationMultiplier(Entity en, int loc, Mounted mount)
// Don't count squad support weapons, these are handled separately
return ((mount.getLocation() <= 1) && !mount.isSquadSupportWeapon()) ? 1 : 0;
} else if (en instanceof Infantry) {
- return (loc == mount.getLocation()) ? 1 : 0;
+ // CI only ever have loc == 0 (no TUR, REAR, arcs); do not count standard weapons when it has field guns
+ return (!((Infantry) en).hasFieldWeapon() || (mount.getLocation() == Infantry.LOC_FIELD_GUNS)) ? 1 : 0;
} else if (en instanceof TripodMech) {
return getTripodMekLocationMultiplier(loc, mount.getLocation(), mount.isRearMounted());
} else if (en instanceof QuadVee) {
@@ -164,11 +162,9 @@ private static double getJumpShipLocationMultiplier(Jumpship en, int index, int
case 0:
if (location == Jumpship.LOC_NOSE) {
return 1;
- } else if (en.isSpheroid() && (location == Jumpship.LOC_FLS || location == Jumpship.LOC_FRS)
- && !rearMounted) {
- return 0.5;
+ } else {
+ return (location == Jumpship.LOC_FLS || location == Jumpship.LOC_FRS) ? 0.5 : 0;
}
- break;
case 1:
return (location == Jumpship.LOC_FLS || location == Jumpship.LOC_ALS) ? 0.5 : 0;
case 2:
diff --git a/megamek/src/megamek/common/alphaStrike/conversion/ASMovementConverter.java b/megamek/src/megamek/common/alphaStrike/conversion/ASMovementConverter.java
index e5c7d22c63d..846bc8d6dc0 100644
--- a/megamek/src/megamek/common/alphaStrike/conversion/ASMovementConverter.java
+++ b/megamek/src/megamek/common/alphaStrike/conversion/ASMovementConverter.java
@@ -142,14 +142,12 @@ private static Map convertMovementForInfantry(ASConverter.Conve
jumpingMP = ((BattleArmor)entity).getJumpMP(true, true, true);
}
- // ensure a minimum base movement of 2"
- walkingMP = Math.max(walkingMP, 1);
report.addLine("Walking MP:", Integer.toString(walkingMP));
report.addLine("Jumping MP:", Integer.toString(jumpingMP));
String movementCode = getMovementCode(conversionData);
element.setPrimaryMovementMode(movementCode);
- if (walkingMP > jumpingMP) {
+ if ((walkingMP > jumpingMP) || (jumpingMP == 0)) {
result.put(movementCode, walkingMP * 2);
report.addLine("Walking MP > Jumping MP", walkingMP + " x 2", walkingMP * 2 + "\"" + movementCode);
} else {
diff --git a/megamek/src/megamek/common/alphaStrike/conversion/ASPointValueConverter.java b/megamek/src/megamek/common/alphaStrike/conversion/ASPointValueConverter.java
index a294016c4b0..abc0150e92a 100644
--- a/megamek/src/megamek/common/alphaStrike/conversion/ASPointValueConverter.java
+++ b/megamek/src/megamek/common/alphaStrike/conversion/ASPointValueConverter.java
@@ -466,7 +466,7 @@ private double brawlerMalus() {
private double agileBonus() {
double result = 0;
double modifiedTMM = element.getTMM() + 0.5 * element.getJMPS() + 0.5 * element.getSUBS();
- if (modifiedTMM >= 2) {
+ if (modifiedTMM > 1) {
double dmgS = element.getStandardDamage().S.minimal ? 0.5 : element.getStandardDamage().S.damage;
double dmgM = element.getStandardDamage().M.minimal ? 0.5 : element.getStandardDamage().M.damage;
if (dmgM > 0) {
@@ -534,7 +534,11 @@ protected void processForceBonus() {
}
if (element.hasSUA(MHQ)) {
int mhqValue = (int) element.getSUA(MHQ);
- bonus += mhqValue;
+ if (mhqValue <= 4) {
+ bonus += mhqValue;
+ } else {
+ bonus += 4 + Math.ceil(0.2 * mhqValue);
+ }
modifierList.add("MHQ");
}
if (!modifierList.isEmpty()) {
diff --git a/megamek/src/megamek/common/alphaStrike/conversion/ASSpecialAbilityConverter.java b/megamek/src/megamek/common/alphaStrike/conversion/ASSpecialAbilityConverter.java
index 69518c57316..fcf2bba96f1 100644
--- a/megamek/src/megamek/common/alphaStrike/conversion/ASSpecialAbilityConverter.java
+++ b/megamek/src/megamek/common/alphaStrike/conversion/ASSpecialAbilityConverter.java
@@ -471,6 +471,10 @@ protected static boolean isExplosive(Mounted equipment) {
if ((equipment.getType() instanceof MiscType) && equipment.getType().hasFlag(F_BOMB_BAY)) {
return true;
}
+ // According to ASC p.123 Booby Traps count as explosive contrary to TO AUE p.109
+ if ((equipment.getType() instanceof MiscType) && equipment.getType().hasFlag(F_BOOBY_TRAP)) {
+ return true;
+ }
// Oneshot weapons internally have normal ammo allocated to them which must
// be disqualified as explosive; such ammo has no location
return equipment.getType().isExplosive(null) && (equipment.getExplosionDamage() > 0)
@@ -539,6 +543,18 @@ protected void finalizeSpecials() {
}
}
}
+
+ // Armor 0 elements cannot get BAR
+ if (element.getFullArmor() == 0) {
+ element.getSpecialAbilities().removeSUA(BAR);
+ }
+
+ // A unit with ENE doesn't need any type of CASE
+ if (element.hasSUA(ENE)) {
+ element.getSpecialAbilities().removeSUA(CASE);
+ element.getSpecialAbilities().removeSUA(CASEII);
+ element.getSpecialAbilities().removeSUA(CASEP);
+ }
}
/** Adds the sua(s) to the element and writes a report line for each, if it is not yet present. */
diff --git a/megamek/src/megamek/common/enums/BasementType.java b/megamek/src/megamek/common/enums/BasementType.java
index 8643dbf7390..e6888beaab3 100644
--- a/megamek/src/megamek/common/enums/BasementType.java
+++ b/megamek/src/megamek/common/enums/BasementType.java
@@ -19,7 +19,6 @@
package megamek.common.enums;
import megamek.MegaMek;
-import megamek.common.util.EncodeControl;
import java.util.Arrays;
import java.util.ResourceBundle;
@@ -44,7 +43,7 @@ public enum BasementType {
//region Constructors
BasementType(final String name, final int depth) {
final ResourceBundle resources = ResourceBundle.getBundle("megamek.common.messages",
- MegaMek.getMMOptions().getLocale(), new EncodeControl());
+ MegaMek.getMMOptions().getLocale());
this.name = resources.getString(name);
this.depth = depth;
}
diff --git a/megamek/src/megamek/common/enums/GamePhase.java b/megamek/src/megamek/common/enums/GamePhase.java
index c697be6142f..09ff7afc137 100644
--- a/megamek/src/megamek/common/enums/GamePhase.java
+++ b/megamek/src/megamek/common/enums/GamePhase.java
@@ -21,7 +21,6 @@
import megamek.MegaMek;
import megamek.common.*;
import megamek.common.options.OptionsConstants;
-import megamek.common.util.EncodeControl;
import java.util.Objects;
import java.util.ResourceBundle;
@@ -63,7 +62,7 @@ public enum GamePhase {
//region Constructors
GamePhase(final String name) {
final ResourceBundle resources = ResourceBundle.getBundle("megamek.common.messages",
- MegaMek.getMMOptions().getLocale(), new EncodeControl());
+ MegaMek.getMMOptions().getLocale());
this.name = resources.getString(name);
}
//endregion Constructors
diff --git a/megamek/src/megamek/common/enums/SkillLevel.java b/megamek/src/megamek/common/enums/SkillLevel.java
index 85952726ed4..7c5fb956dfe 100644
--- a/megamek/src/megamek/common/enums/SkillLevel.java
+++ b/megamek/src/megamek/common/enums/SkillLevel.java
@@ -19,7 +19,6 @@
package megamek.common.enums;
import megamek.MegaMek;
-import megamek.common.util.EncodeControl;
import org.apache.logging.log4j.LogManager;
import java.util.List;
@@ -47,7 +46,7 @@ public enum SkillLevel {
//region Constructors
SkillLevel(final String name, final String toolTipText) {
final ResourceBundle resources = ResourceBundle.getBundle("megamek.common.messages",
- MegaMek.getMMOptions().getLocale(), new EncodeControl());
+ MegaMek.getMMOptions().getLocale());
this.name = resources.getString(name);
this.toolTipText = resources.getString(toolTipText);
}
@@ -92,15 +91,38 @@ public boolean isLegendary() {
return this == LEGENDARY;
}
+ public boolean isUltraGreenOrGreater() {
+ return isUltraGreen() || isGreenOrGreater();
+ }
+
+ public boolean isGreenOrGreater() {
+ return isGreen() || isRegularOrGreater();
+ }
+
+ public boolean isRegularOrGreater() {
+ return isRegular() || isVeteranOrGreater();
+ }
+
public boolean isVeteranOrGreater() {
return isVeteran() || isEliteOrGreater();
}
public boolean isEliteOrGreater() {
- return isElite() || isHeroic() || isLegendary();
+ return isElite() || isHeroicOrGreater();
+ }
+
+ public boolean isHeroicOrGreater() {
+ return isHeroic() || isLegendary();
}
//endregion Boolean Comparisons
+ /**
+ * @return the skill level adjusted so that 0 is the level for Ultra-Green
+ */
+ public int getAdjustedValue() {
+ return ordinal() - 1;
+ }
+
/**
* This returns the default skill values by level. This should never return the value for NONE,
* as NONE means one does not have the skill.
diff --git a/megamek/src/megamek/common/enums/WeaponSortOrder.java b/megamek/src/megamek/common/enums/WeaponSortOrder.java
index 54ce25f01fb..aaa7331672e 100644
--- a/megamek/src/megamek/common/enums/WeaponSortOrder.java
+++ b/megamek/src/megamek/common/enums/WeaponSortOrder.java
@@ -20,7 +20,6 @@
import megamek.MegaMek;
import megamek.common.*;
-import megamek.common.util.EncodeControl;
import org.apache.logging.log4j.LogManager;
import java.util.Comparator;
@@ -44,7 +43,7 @@ public enum WeaponSortOrder {
//region Constructors
WeaponSortOrder(final String name) {
final ResourceBundle resources = ResourceBundle.getBundle("megamek.common.messages",
- MegaMek.getMMOptions().getLocale(), new EncodeControl());
+ MegaMek.getMMOptions().getLocale());
this.name = resources.getString(name);
}
//endregion Constructors
diff --git a/megamek/src/megamek/common/loaders/MtfFile.java b/megamek/src/megamek/common/loaders/MtfFile.java
index 57f15139ba7..3ab2b3cf764 100644
--- a/megamek/src/megamek/common/loaders/MtfFile.java
+++ b/megamek/src/megamek/common/loaders/MtfFile.java
@@ -741,14 +741,15 @@ private void parseCrits(Mech mech, int loc) throws EntityLoadingException {
m.setOmniPodMounted(isOmniPod);
hSharedEquip.put(etype, m);
} else if (((etype instanceof WeaponType) && ((WeaponType) etype).isSplitable()) || ((etype instanceof MiscType) && etype.hasFlag(MiscType.F_SPLITABLE))) {
- // do we already have this one in this or an outer
- // location?
+ // do we already have this one in this or an outer location?
Mounted m = null;
boolean bFound = false;
for (Mounted vSplitWeapon : vSplitWeapons) {
m = vSplitWeapon;
int nLoc = m.getLocation();
- if (((nLoc == loc) || (loc == Mech.getInnerLocation(nLoc))) && (m.getType() == etype)) {
+ if ((((nLoc == loc) || (loc == Mech.getInnerLocation(nLoc)))
+ || ((nLoc == Mech.LOC_CT) && (loc == Mech.LOC_HEAD)))
+ && (m.getType() == etype)) {
bFound = true;
break;
}
diff --git a/megamek/src/megamek/common/options/GameOptions.java b/megamek/src/megamek/common/options/GameOptions.java
index b8c4955f48d..ef789aef7e0 100755
--- a/megamek/src/megamek/common/options/GameOptions.java
+++ b/megamek/src/megamek/common/options/GameOptions.java
@@ -116,8 +116,8 @@ public synchronized void initialize() {
addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_GHOST_TARGET, false);
addOption(advancedRules, OptionsConstants.ADVANCED_GHOST_TARGET_MAX, 5);
addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_DIG_IN, false);
- addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_BA_WEIGHT, false);
- addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_TAKE_COVER, false);
+ addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_BA_WEIGHT, false);
+ addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_TAKE_COVER, false);
addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_ANGEL_ECM, false);
addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_BATTLE_WRECK, false);
addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_SKIN_OF_THE_TEETH_EJECTION, false);
@@ -222,7 +222,8 @@ public synchronized void initialize() {
addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_TAKING_DAMAGE, false);
addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_LEG_DAMAGE, false);
addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_WALK_BACKWARDS, false);
- addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_FAST_INFANTRY_MOVE, false);
+ addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_FAST_INFANTRY_MOVE, false);
+ addOption(advancedGroundMovement, OptionsConstants.ADVANCED_TACOPS_INF_PAVE_BONUS, false);
addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT, false);
addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT_NUMBER, 4);
addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLE_ACCELERATION, false);
@@ -470,18 +471,18 @@ public Vector getOptions() {
* @param indent the indent to write at
*/
public void writeToXML(final PrintWriter pw, int indent) {
- MMXMLUtility.writeSimpleXMLOpenIndentedLine(pw, indent++, "gameOptions");
+ MMXMLUtility.writeSimpleXMLOpenTag(pw, indent++, "gameOptions");
for (final Enumeration groups = getGroups(); groups.hasMoreElements(); ) {
final IOptionGroup group = groups.nextElement();
for (final Enumeration options = group.getOptions(); options.hasMoreElements(); ) {
final IOption option = options.nextElement();
- MMXMLUtility.writeSimpleXMLOpenIndentedLine(pw, indent++, "gameOption");
+ MMXMLUtility.writeSimpleXMLOpenTag(pw, indent++, "gameOption");
MMXMLUtility.writeSimpleXMLTag(pw, indent, "name", option.getName());
MMXMLUtility.writeSimpleXMLTag(pw, indent, "value", option.getValue().toString());
- MMXMLUtility.writeSimpleXMLCloseIndentedLine(pw, --indent, "gameOption");
+ MMXMLUtility.writeSimpleXMLCloseTag(pw, --indent, "gameOption");
}
}
- MMXMLUtility.writeSimpleXMLCloseIndentedLine(pw, --indent, "gameOptions");
+ MMXMLUtility.writeSimpleXMLCloseTag(pw, --indent, "gameOptions");
}
/**
diff --git a/megamek/src/megamek/common/options/Messages.java b/megamek/src/megamek/common/options/Messages.java
index bc79788ec61..5020e76a5ab 100644
--- a/megamek/src/megamek/common/options/Messages.java
+++ b/megamek/src/megamek/common/options/Messages.java
@@ -14,7 +14,6 @@
package megamek.common.options;
import megamek.MegaMek;
-import megamek.common.util.EncodeControl;
import java.text.MessageFormat;
import java.util.MissingResourceException;
@@ -23,7 +22,7 @@
class Messages {
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle("megamek.common.options.messages",
- MegaMek.getMMOptions().getLocale(), new EncodeControl());
+ MegaMek.getMMOptions().getLocale());
private Messages() {
}
diff --git a/megamek/src/megamek/common/options/OptionsConstants.java b/megamek/src/megamek/common/options/OptionsConstants.java
index 69ab3d01c1c..05de66207bd 100644
--- a/megamek/src/megamek/common/options/OptionsConstants.java
+++ b/megamek/src/megamek/common/options/OptionsConstants.java
@@ -337,7 +337,7 @@ public class OptionsConstants {
public static final String ADVANCED_TACOPS_GHOST_TARGET= "tacops_ghost_target";
public static final String ADVANCED_GHOST_TARGET_MAX= "ghost_target_max";
public static final String ADVANCED_TACOPS_DIG_IN= "tacops_dig_in";
- public static final String ADVANCED_TACOPS_BA_WEIGHT= "tacops_ba_weight";
+ public static final String ADVANCED_TACOPS_BA_WEIGHT= "tacops_ba_weight";
public static final String ADVANCED_TACOPS_TAKE_COVER= "tacops_take_cover";
public static final String ADVANCED_TACOPS_ANGEL_ECM= "tacops_angel_ecm";
public static final String ADVANCED_TACOPS_BATTLE_WRECK= "tacops_battle_wreck";
@@ -442,7 +442,8 @@ public class OptionsConstants {
public static final String ADVGRNDMOV_TACOPS_TAKING_DAMAGE= "tacops_taking_damage";
public static final String ADVGRNDMOV_TACOPS_LEG_DAMAGE= "tacops_leg_damage";
public static final String ADVGRNDMOV_TACOPS_WALK_BACKWARDS= "tacops_walk_backwards";
- public static final String ADVGRNDMOV_TACOPS_FAST_INFANTRY_MOVE= "tacops_fast_infantry_move";
+ public static final String ADVGRNDMOV_TACOPS_FAST_INFANTRY_MOVE= "tacops_fast_infantry_move";
+ public static final String ADVANCED_TACOPS_INF_PAVE_BONUS= "tacops_inf_pave_bonus";
public static final String ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT= "vehicle_lance_movement";
public static final String ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT_NUMBER= "vehicle_lance_movement_number";
public static final String ADVGRNDMOV_TURN_MODE = "vehicle_turn_mode";
diff --git a/megamek/src/megamek/common/preference/ClientPreferences.java b/megamek/src/megamek/common/preference/ClientPreferences.java
index b12d37649cd..41400afecdb 100644
--- a/megamek/src/megamek/common/preference/ClientPreferences.java
+++ b/megamek/src/megamek/common/preference/ClientPreferences.java
@@ -57,6 +57,8 @@ public class ClientPreferences extends PreferenceStoreProxy {
public static final String BOARD_HEIGHT = "BoardHeight";
public static final String MAP_WIDTH = "MapWidth";
public static final String MAP_HEIGHT = "MapHeight";
+ public static final String REPORT_KEYWORDS = "ReportKeywords";
+ private static final String REPORTKEYWORDSDEFAULTS = "Needs\nRolls\nTakes\nHit\nFalls\nSkill Roll\nPilot Skill\nPhase\nDestroyed\nDamage";
public static final String IP_ADDRESSES_IN_CHAT = "IPAddressesInChat";
//endregion Variable Declarations
@@ -86,6 +88,7 @@ public ClientPreferences(IPreferenceStore store) {
store.setDefault(MAP_HEIGHT, 1);
store.setDefault(DEBUG_OUTPUT_ON, false);
store.setDefault(MEMORY_DUMP_ON, false);
+ store.setDefault(REPORT_KEYWORDS, REPORTKEYWORDSDEFAULTS);
store.setDefault(IP_ADDRESSES_IN_CHAT, false);
setLocale(store.getString(LOCALE));
setMekHitLocLog();
@@ -283,6 +286,14 @@ public void setGUIName(String guiName) {
store.setValue(GUI_NAME, guiName);
}
+ public String getReportKeywords() {
+ return store.getString(REPORT_KEYWORDS);
+ }
+
+ public void setReportKeywords(String s) {
+ store.setValue(REPORT_KEYWORDS, s);
+ }
+
public boolean getShowIPAddressesInChat() {
return store.getBoolean(IP_ADDRESSES_IN_CHAT);
}
diff --git a/megamek/src/megamek/common/util/EncodeControl.java b/megamek/src/megamek/common/util/EncodeControl.java
deleted file mode 100644
index 9655ae3c3ef..00000000000
--- a/megamek/src/megamek/common/util/EncodeControl.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * MegaMek - Copyright (C) 2000-2004 Ben Mazur (bmazur@sev.org)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-package megamek.common.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URL;
-import java.net.URLConnection;
-import java.nio.charset.StandardCharsets;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.Locale;
-import java.util.PropertyResourceBundle;
-import java.util.ResourceBundle;
-import java.util.ResourceBundle.Control;
-
-/**
- * Borrowed code from http://stackoverflow.com/questions/4659929/how-to-use-utf-8-in-resource-properties-with-resourcebundle
- * The issue was the Resource Bundle was reading properties files as ISO-8859-1 encodings. Thus
- * special characters, like those used in Russian, were being read wrong. The class below allows for
- * a controller to read in any encoding specified.
- * The actual overridden class has been copied here with the encoding change from the borrowed coded added.
- *
- * @author Xenon
- */
-public class EncodeControl extends Control {
- @Override
- public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
- throws IllegalAccessException, InstantiationException, IOException {
- String bundleName = this.toBundleName(baseName, locale);
- Object bundle = null;
- if (format.equals("java.class")) {
- try {
- Class> resourceName = loader.loadClass(bundleName);
- if (!ResourceBundle.class.isAssignableFrom(resourceName)) {
- throw new ClassCastException(resourceName.getName() + " cannot be cast to ResourceBundle");
- }
-
- bundle = resourceName.newInstance();
- } catch (ClassNotFoundException var19) {
- throw (IOException) var19.getException();
- }
- } else {
- if (!format.equals("java.properties")) {
- throw new IllegalArgumentException("unknown format: " + format);
- }
-
- final String resourceName1 = this.toResourceName0(bundleName, "properties");
- if (resourceName1 == null) {
- return (ResourceBundle) bundle;
- }
-
- final ClassLoader classLoader = loader;
- final boolean reloadFlag = reload;
- InputStream stream = null;
-
- try {
- stream = AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
- InputStream is = null;
- if (reloadFlag) {
- URL url = classLoader.getResource(resourceName1);
- if (url != null) {
- URLConnection connection = url.openConnection();
- if (connection != null) {
- connection.setUseCaches(false);
- is = connection.getInputStream();
- }
- }
- } else {
- is = classLoader.getResourceAsStream(resourceName1);
- }
-
- return is;
- });
- } catch (PrivilegedActionException var18) {
- throw (IOException) var18.getException();
- }
-
- if (stream != null) {
- try (Reader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) {
- // Only this line is changed to make it to read properties files as UTF-8 or other encodings.
- bundle = new PropertyResourceBundle(reader);
- } finally {
- stream.close();
- }
- }
- }
-
- return (ResourceBundle) bundle;
- }
-
- // Also borrowed from overridden class.
- private String toResourceName0(String bundleName, String suffix) {
- return bundleName.contains("://") ? null : this.toResourceName(bundleName, suffix);
- }
-}
diff --git a/megamek/src/megamek/common/util/SerializationHelper.java b/megamek/src/megamek/common/util/SerializationHelper.java
index 4047b88d788..674a44bb9d9 100644
--- a/megamek/src/megamek/common/util/SerializationHelper.java
+++ b/megamek/src/megamek/common/util/SerializationHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 The MegaMek Team. All rights reserved.
+ * Copyright (c) 2020-2022 - The MegaMek Team. All Rights Reserved.
*
* This file is part of MegaMek.
*
@@ -10,13 +10,12 @@
*
* MegaMek is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with MegaMek. If not, see .
+ * along with MegaMek. If not, see .
*/
-
package megamek.common.util;
import com.thoughtworks.xstream.XStream;
@@ -32,15 +31,54 @@
* Class that off-loads serialization related code from Server.java
*/
public class SerializationHelper {
-
+
/**
- * Factory method that produces an XStream object suitable for loading MegaMek save games
+ * Factory method that produces an XStream object suitable for working with MegaMek save games
*/
- public static XStream getXStream() {
- XStream xstream = new XStream();
+ public static XStream getSaveGameXStream() {
+ final XStream xStream = new XStream();
- // This mirrors the settings is saveGame
- xstream.setMode(XStream.ID_REFERENCES);
+ // This will make save games much smaller by using a more efficient means of referencing
+ // objects in the XML graph
+ xStream.setMode(XStream.ID_REFERENCES);
+
+ // Setup Permissions
+ xStream.allowTypes(new Class[] {
+ megamek.client.bot.princess.BehaviorSettings.class,
+ megamek.common.Board.class,
+ megamek.common.Coords.class,
+ megamek.common.CompositeTechLevel.DateRange.class,
+ megamek.common.CriticalSlot.class,
+ megamek.common.Game.class,
+ megamek.common.Hex.class,
+ megamek.common.Mounted.class,
+ megamek.common.PilotingRollData.class,
+ megamek.common.Player.class,
+ megamek.common.Sensor.class,
+ megamek.common.TargetRollModifier.class,
+ megamek.common.Team.class,
+ megamek.common.Terrain.class,
+ megamek.common.Report.class,
+ megamek.server.SmokeCloud.class,
+ });
+ xStream.allowTypeHierarchy(megamek.common.Crew.class);
+ xStream.allowTypeHierarchy(megamek.common.GameTurn.class);
+ xStream.allowTypeHierarchy(megamek.common.ITechnology.class);
+ xStream.allowTypeHierarchy(megamek.common.Transporter.class);
+ xStream.allowTypeHierarchy(megamek.common.actions.EntityAction.class);
+ xStream.allowTypeHierarchy(megamek.common.icons.AbstractIcon.class);
+ xStream.allowTypeHierarchy(megamek.common.options.AbstractOptions.class);
+ xStream.allowTypeHierarchy(megamek.common.options.IOption.class);
+ xStream.allowTypeHierarchy(megamek.common.weapons.AttackHandler.class);
+ xStream.allowTypeHierarchy(megamek.server.victory.IVictoryConditions.class);
+ return xStream;
+ }
+
+ /**
+ * Factory method that produces an XStream object suitable for loading MegaMek save games
+ */
+ public static XStream getLoadSaveGameXStream() {
+ XStream xstream = getSaveGameXStream();
xstream.registerConverter(new Converter() {
@Override
@@ -77,7 +115,7 @@ public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingC
// Unused here
}
});
-
+
return xstream;
}
}
diff --git a/megamek/src/megamek/common/weapons/ACAPHandler.java b/megamek/src/megamek/common/weapons/ACAPHandler.java
index 99381a09c80..baa2e62e075 100644
--- a/megamek/src/megamek/common/weapons/ACAPHandler.java
+++ b/megamek/src/megamek/common/weapons/ACAPHandler.java
@@ -34,39 +34,23 @@
public class ACAPHandler extends ACWeaponHandler {
private static final long serialVersionUID = -4251291510045646817L;
- /**
- * @param t
- * @param w
- * @param g
- */
public ACAPHandler(ToHitData t, WeaponAttackAction w, Game g, GameManager m) {
super(t, w, g, m);
generalDamageType = HitData.DAMAGE_ARMOR_PIERCING;
}
- /*
- * (non-Javadoc)
- *
- * @see
- * megamek.common.weapons.WeaponHandler#handleEntityDamage(megamek.common
- * .Entity, java.util.Vector, megamek.common.Building, int, int, int, int)
- */
@Override
- protected void handleEntityDamage(Entity entityTarget,
- Vector vPhaseReport, Building bldg, int hits, int nCluster,
- int bldgAbsorbs) {
+ protected void handleEntityDamage(Entity entityTarget, Vector vPhaseReport,
+ Building bldg, int hits, int nCluster, int bldgAbsorbs) {
AmmoType atype = (AmmoType) weapon.getLinked().getType();
- HitData hit = entityTarget.rollHitLocation(toHit.getHitTable(),
- toHit.getSideTable(), waa.getAimedLocation(),
- waa.getAimingMode(), toHit.getCover());
+ HitData hit = entityTarget.rollHitLocation(toHit.getHitTable(), toHit.getSideTable(),
+ waa.getAimedLocation(), waa.getAimingMode(), toHit.getCover());
hit.setGeneralDamageType(generalDamageType);
hit.setAttackerId(getAttackerId());
- if (entityTarget.removePartialCoverHits(hit.getLocation(), toHit
- .getCover(), Compute.targetSideTable(ae, entityTarget, weapon
- .getCalledShot().getCall()))) {
+ if (entityTarget.removePartialCoverHits(hit.getLocation(), toHit.getCover(),
+ Compute.targetSideTable(ae, entityTarget, weapon.getCalledShot().getCall()))) {
// Weapon strikes Partial Cover.
- handlePartialCoverHit(entityTarget, vPhaseReport, hit, bldg, hits,
- nCluster, bldgAbsorbs);
+ handlePartialCoverHit(entityTarget, vPhaseReport, hit, bldg, hits, nCluster, bldgAbsorbs);
return;
}
@@ -98,8 +82,8 @@ protected void handleEntityDamage(Entity entityTarget,
Hex targetHex = game.getBoard().getHex(target.getPosition());
boolean targetStickingOutOfBuilding = unitStickingOutOfBuilding(targetHex, entityTarget);
- nDamage = absorbBuildingDamage(nDamage, entityTarget, bldgAbsorbs,
- vPhaseReport, bldg, targetStickingOutOfBuilding);
+ nDamage = absorbBuildingDamage(nDamage, entityTarget, bldgAbsorbs, vPhaseReport, bldg,
+ targetStickingOutOfBuilding);
nDamage = checkTerrain(nDamage, entityTarget, vPhaseReport);
@@ -133,12 +117,9 @@ protected void handleEntityDamage(Entity entityTarget,
critModifier += toHit.getMoS() / 3;
}
hit.makeArmorPiercing(atype, critModifier);
- vPhaseReport
- .addAll(gameManager.damageEntity(entityTarget, hit, nDamage,
- false, ae.getSwarmTargetId() == entityTarget
- .getId() ? DamageType.IGNORE_PASSENGER
- : damageType, false, false, throughFront,
- underWater));
+ vPhaseReport.addAll(gameManager.damageEntity(entityTarget, hit, nDamage, false,
+ ae.getSwarmTargetId() == entityTarget.getId() ? DamageType.IGNORE_PASSENGER : damageType,
+ false, false, throughFront, underWater));
}
}
}
diff --git a/megamek/src/megamek/common/weapons/AmmoWeaponHandler.java b/megamek/src/megamek/common/weapons/AmmoWeaponHandler.java
index d73cf9c3c14..782c7295095 100644
--- a/megamek/src/megamek/common/weapons/AmmoWeaponHandler.java
+++ b/megamek/src/megamek/common/weapons/AmmoWeaponHandler.java
@@ -26,6 +26,7 @@
import megamek.common.options.OptionsConstants;
import megamek.server.GameManager;
import megamek.server.Server;
+import org.apache.logging.log4j.LogManager;
/**
* @author Andrew Hunter
@@ -40,28 +41,18 @@ protected AmmoWeaponHandler() {
// deserialization only
}
- /**
- * @param t
- * @param w
- * @param g
- */
- public AmmoWeaponHandler(ToHitData t, WeaponAttackAction w, Game g,
- GameManager m) {
+ public AmmoWeaponHandler(ToHitData t, WeaponAttackAction w, Game g, GameManager m) {
super(t, w, g, m);
generalDamageType = HitData.DAMAGE_BALLISTIC;
}
- /*
- * (non-Javadoc)
- *
- * @see megamek.common.weapons.WeaponHandler#UseAmmo()
- */
@Override
protected void useAmmo() {
checkAmmo();
- if (ammo == null) {// Can't happen. w/o legal ammo, the weapon
- // *shouldn't* fire.
- System.out.println("Handler can't find any ammo! Oh no!");
+ if (ammo == null) {
+ // Can't happen. w/o legal ammo, the weapon *shouldn't* fire.
+ LogManager.getLogger().error("Handler can't find any ammo! Oh no!", new Exception());
+ return;
}
if (ammo.getUsableShotsLeft() <= 0) {
@@ -84,8 +75,7 @@ protected void checkAmmo() {
* For ammo weapons, this number can be less than the full number if the
* amount of ammo is not high enough
*
- * @return the number of weapons of this type firing (for squadron weapon
- * groups)
+ * @return the number of weapons of this type firing (for squadron weapon groups)
*/
@Override
protected int getNumberWeapons() {
@@ -161,8 +151,7 @@ protected void explodeRoundInBarrel(Vector vPhaseReport) {
int wloc = weapon.getLocation();
for (int i = 0; i < ae.getNumberOfCriticals(wloc); i++) {
CriticalSlot slot1 = ae.getCritical(wloc, i);
- if ((slot1 == null) ||
- (slot1.getType() == CriticalSlot.TYPE_SYSTEM)) {
+ if ((slot1 == null) || (slot1.getType() == CriticalSlot.TYPE_SYSTEM)) {
continue;
}
Mounted mounted = slot1.getMount();
diff --git a/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectFireHandler.java b/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectFireHandler.java
index c8092eb3394..bcca3a4e059 100644
--- a/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectFireHandler.java
+++ b/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectFireHandler.java
@@ -97,7 +97,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
}
String artyMsg;
ArtilleryAttackAction aaa = (ArtilleryAttackAction) waa;
- if (phase == GamePhase.TARGETING) {
+ if (phase.isTargeting()) {
if (!handledAmmoAndReport) {
addHeat();
// Report the firing itself
diff --git a/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectHomingHandler.java b/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectHomingHandler.java
index fb9826c2b81..f87adbf2a76 100644
--- a/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectHomingHandler.java
+++ b/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectHomingHandler.java
@@ -77,7 +77,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
return true;
}
ArtilleryAttackAction aaa = (ArtilleryAttackAction) waa;
- if (phase == GamePhase.TARGETING) {
+ if (phase.isTargeting()) {
if (!handledAmmoAndReport) {
addHeat();
// Report the firing itself
diff --git a/megamek/src/megamek/common/weapons/ArtilleryWeaponIndirectFireHandler.java b/megamek/src/megamek/common/weapons/ArtilleryWeaponIndirectFireHandler.java
index ab20cdd5f58..77c77560be6 100644
--- a/megamek/src/megamek/common/weapons/ArtilleryWeaponIndirectFireHandler.java
+++ b/megamek/src/megamek/common/weapons/ArtilleryWeaponIndirectFireHandler.java
@@ -49,25 +49,11 @@ public ArtilleryWeaponIndirectFireHandler(ToHitData t, WeaponAttackAction w, Gam
}
}
- /*
- * (non-Javadoc)
- *
- * @see megamek.common.weapons.AttackHandler#cares(int)
- */
@Override
public boolean cares(GamePhase phase) {
- if ((phase == GamePhase.OFFBOARD)
- || (phase == GamePhase.TARGETING)) {
- return true;
- }
- return false;
+ return phase.isOffboard() || phase.isTargeting();
}
- /*
- * (non-Javadoc)
- *
- * @see megamek.common.weapons.AttackHandler#handle(int, java.util.Vector)
- */
@Override
public boolean handle(GamePhase phase, Vector vPhaseReport) {
if (!cares(phase)) {
@@ -75,7 +61,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
}
String artyMsg;
ArtilleryAttackAction aaa = (ArtilleryAttackAction) waa;
- if (phase == GamePhase.TARGETING) {
+ if (phase.isTargeting()) {
if (!handledAmmoAndReport) {
addHeat();
// Report the firing itself
diff --git a/megamek/src/megamek/common/weapons/ArtilleryWeaponIndirectHomingHandler.java b/megamek/src/megamek/common/weapons/ArtilleryWeaponIndirectHomingHandler.java
index 23985cd96c8..216297c0505 100644
--- a/megamek/src/megamek/common/weapons/ArtilleryWeaponIndirectHomingHandler.java
+++ b/megamek/src/megamek/common/weapons/ArtilleryWeaponIndirectHomingHandler.java
@@ -61,7 +61,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
return true;
}
ArtilleryAttackAction aaa = (ArtilleryAttackAction) waa;
- if (phase == GamePhase.TARGETING) {
+ if (phase.isTargeting()) {
if (!handledAmmoAndReport) {
addHeat();
// Report the firing itself
diff --git a/megamek/src/megamek/common/weapons/BayWeaponHandler.java b/megamek/src/megamek/common/weapons/BayWeaponHandler.java
index e9905678333..794a316b294 100644
--- a/megamek/src/megamek/common/weapons/BayWeaponHandler.java
+++ b/megamek/src/megamek/common/weapons/BayWeaponHandler.java
@@ -34,12 +34,6 @@ protected BayWeaponHandler() {
// deserialization only
}
- /**
- * @param t
- * @param w
- * @param g
- * @param m
- */
public BayWeaponHandler(ToHitData t, WeaponAttackAction w, Game g, GameManager m) {
super(t, w, g, m);
}
@@ -241,8 +235,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
// Works out fire setting, AMS shots, and whether continuation is
// necessary.
- if (!handleSpecialMiss(entityTarget, bldgDamagedOnMiss, bldg,
- vPhaseReport)) {
+ if (!handleSpecialMiss(entityTarget, bldgDamagedOnMiss, bldg, vPhaseReport)) {
return false;
}
}
@@ -264,8 +257,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
// Targeting a building.
if (target.getTargetType() == Targetable.TYPE_BUILDING) {
// The building takes the full brunt of the attack
- handleBuildingDamage(vPhaseReport, bldg, nDamPerHit,
- target.getPosition());
+ handleBuildingDamage(vPhaseReport, bldg, nDamPerHit, target.getPosition());
return false;
}
@@ -319,19 +311,16 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
// absorbed damage shouldn't reduce incoming damage,
// since the incoming damage was reduced in
// Compute.directBlowInfantryDamage
- nDamage = -wtype.getDamage(nRange)
- * Math.min(nCluster, hits);
+ nDamage = -wtype.getDamage(nRange) * Math.min(nCluster, hits);
}
- bldgAbsorbs = (int) Math.round(nDamage
- * bldg.getInfDmgFromInside());
+ bldgAbsorbs = (int) Math.round(nDamage * bldg.getInfDmgFromInside());
} else {
// Used later to indicate a special report
bldgAbsorbs = Integer.MIN_VALUE;
}
}
- handleEntityDamage(entityTarget, vPhaseReport, bldg, hits,
- nCluster, bldgAbsorbs);
+ handleEntityDamage(entityTarget, vPhaseReport, bldg, hits, nCluster, bldgAbsorbs);
gameManager.creditKill(entityTarget, ae);
} // Handle the next weapon in the bay
Report.addNewline(vPhaseReport);
@@ -341,7 +330,6 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
/**
* Calculate the starting armor value of a flight of Capital Missiles
* Used for Aero Sanity. This is done in calcAttackValue() otherwise
- *
*/
protected int initializeCapMissileArmor() {
return 0;
@@ -469,7 +457,7 @@ public boolean handleAeroSanity(GamePhase phase, Vector vPhaseReport) {
vPhaseReport.addElement(r);
}
- //Don't add heat here, because that will be handled by individual weapons (even if heat by arc)
+ // Don't add heat here, because that will be handled by individual weapons (even if heat by arc)
// Any necessary PSRs, jam checks, etc.
// If this boolean is true, don't report
@@ -486,8 +474,8 @@ public boolean handleAeroSanity(GamePhase phase, Vector vPhaseReport) {
return false;
}
- //Large missiles
- //use this if AMS counterfire destroys all the missiles
+ // Large missiles
+ // use this if AMS counterfire destroys all the missiles
if (amsBayEngagedCap && (CapMissileArmor <= 0)) {
r = new Report(3356);
r.indent();
@@ -495,7 +483,7 @@ public boolean handleAeroSanity(GamePhase phase, Vector vPhaseReport) {
vPhaseReport.addElement(r);
return false;
}
- //use this if PD counterfire destroys all the Capital missiles
+ // use this if PD counterfire destroys all the Capital missiles
if (pdBayEngagedCap && (CapMissileArmor <= 0)) {
r = new Report(3355);
r.indent();
@@ -512,10 +500,10 @@ public boolean handleAeroSanity(GamePhase phase, Vector vPhaseReport) {
}
}
- //Report point defense effects
- //Set up a cluster hits table modifier
+ // Report point defense effects
+ // Set up a cluster hits table modifier
double counterAVMod = getCounterAV();
- //Report a failure due to overheating
+ // Report a failure due to overheating
if (pdOverheated
&& (!(amsBayEngaged
|| amsBayEngagedCap
@@ -528,16 +516,16 @@ public boolean handleAeroSanity(GamePhase phase, Vector vPhaseReport) {
r.indent();
vPhaseReport.addElement(r);
} else if (pdOverheated) {
- //Report a partial failure
+ // Report a partial failure
r = new Report (3361);
r.subject = subjectId;
r.indent();
vPhaseReport.addElement(r);
- //Halve the effectiveness of cluster hits modification
+ // Halve the effectiveness of cluster hits modification
counterAVMod /= 2.0;
}
- //Now report the effects, if any
- //Missiles using the cluster hits table
+ // Now report the effects, if any
+ // Missiles using the cluster hits table
if (amsBayEngaged || pdBayEngaged) {
r = new Report(3366);
r.indent();
@@ -573,7 +561,7 @@ public boolean handleAeroSanity(GamePhase phase, Vector vPhaseReport) {
}
bayWHandler.handle(phase, vPhaseReport);
if (vPhaseReport.size() > replaceReport) {
- //fix the reporting - is there a better way to do this
+ // fix the reporting - is there a better way to do this
Report currentReport = vPhaseReport.get(replaceReport);
while (null != currentReport) {
vPhaseReport.remove(replaceReport);
diff --git a/megamek/src/megamek/common/weapons/BombAttackHandler.java b/megamek/src/megamek/common/weapons/BombAttackHandler.java
index a28e44be45e..ac878030c84 100644
--- a/megamek/src/megamek/common/weapons/BombAttackHandler.java
+++ b/megamek/src/megamek/common/weapons/BombAttackHandler.java
@@ -207,7 +207,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
// Retrieve facing at current step in flight path
int facing = ae.getPassedThroughFacing().get(idx);
// Scatter, based on location and facing
- drop = Compute.scatterAltitudeBombs(coords, facing);
+ drop = Compute.scatterAltitudeBombs(coords, facing, moF);
} else {
drop = Compute.scatterDiveBombs(coords, moF);
}
diff --git a/megamek/src/megamek/common/weapons/CLIATMHandler.java b/megamek/src/megamek/common/weapons/CLIATMHandler.java
index 2d01953673d..ce2cf02bf56 100644
--- a/megamek/src/megamek/common/weapons/CLIATMHandler.java
+++ b/megamek/src/megamek/common/weapons/CLIATMHandler.java
@@ -31,22 +31,11 @@ public class CLIATMHandler extends ATMHandler {
private static final long serialVersionUID = 5476183194060709574L;
boolean isAngelECMAffected;
- /**
- * @param t
- * @param w
- * @param g
- * @param m
- */
public CLIATMHandler(ToHitData t, WeaponAttackAction w, Game g, GameManager m) {
super(t, w, g, m);
isAngelECMAffected = ComputeECM.isAffectedByAngelECM(ae, ae.getPosition(), target.getPosition());
}
- /*
- * (non-Javadoc)
- *
- * @see megamek.common.weapons.WeaponHandler#calcDamagePerHit()
- */
@Override
protected int calcDamagePerHit() {
double toReturn;
@@ -83,24 +72,16 @@ protected int calcDamagePerHit() {
return (int) toReturn;
}
- /*
- * (non-Javadoc)
- *
- * @see megamek.common.weapons.WeaponHandler#calcHits(java.util.Vector)
- */
@Override
protected int calcHits(Vector vPhaseReport) {
- // conventional infantry gets hit in one lump - gets calculated in the
- // sub functions
+ // conventional infantry gets hit in one lump - gets calculated in the sub functions
// don't need to check for BAs, because BA can't mount ATMs
- int hits;
AmmoType atype = (AmmoType) ammo.getType();
// TacOPs p.84 Cluster Hit Penalites will only effect ATM HE
// I'm doing my own hit calcs here. Special ammo gets its own method.
- // compute ammount of missiles hit - this is the same for all ATM ammo
- // types.
- hits = calcMissileHits(vPhaseReport);
+ // compute ammount of missiles hit - this is the same for all ATM ammo types.
+ int hits = calcMissileHits(vPhaseReport);
// If we use IIW or IMP we are done.
if ((atype.getMunitionType() == AmmoType.M_IATM_IIW)
@@ -125,15 +106,10 @@ protected int calcHits(Vector vPhaseReport) {
*/
@Override
protected int calcAttackValue() {
- // TODO: Should handle speical munitions AV
+ // TODO: Should handle specical munitions AV
return super.calcAttackValue();
}
- /*
- * (non-Javadoc)
- *
- * @see megamek.common.weapons.WeaponHandler#calcHits(java.util.Vector)
- */
protected int calcMissileHits(Vector vPhaseReport) {
AmmoType atype = (AmmoType) ammo.getType();
@@ -145,8 +121,7 @@ protected int calcMissileHits(Vector vPhaseReport) {
Report r = new Report(3325);
r.newlines = 0;
r.subject = subjectId;
- r.add(wtype.getRackSize()
- * ((BattleArmor) ae).getShootingStrength());
+ r.add(wtype.getRackSize() * ((BattleArmor) ae).getShootingStrength());
r.add(sSalvoType);
r.add(toHit.getTableDesc());
vPhaseReport.add(r);
@@ -182,10 +157,9 @@ protected int calcMissileHits(Vector vPhaseReport) {
// Only apply if not all shots hit. IATM IMP have HE ranges and thus
// suffer from spread too
- if (((atype.getMunitionType() == AmmoType.M_HIGH_EXPLOSIVE) || (atype
- .getMunitionType() == AmmoType.M_IATM_IMP))
- && tacopscluster
- && !allShotsHit()) {
+ if (((atype.getMunitionType() == AmmoType.M_HIGH_EXPLOSIVE)
+ || (atype.getMunitionType() == AmmoType.M_IATM_IMP))
+ && tacopscluster && !allShotsHit()) {
if (nRange <= 1) {
nMissilesModifier += 1;
} else if (nRange <= ranges[RangeType.RANGE_MEDIUM]) {
@@ -198,7 +172,7 @@ protected int calcMissileHits(Vector vPhaseReport) {
// //////
// This applies even with streaks.
if (game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_RANGE)
- && (nRange > wtype.getRanges(weapon)[RangeType.RANGE_LONG])) {
+ && (nRange > wtype.getRanges(weapon)[RangeType.RANGE_LONG])) {
nMissilesModifier -= 2;
}
if (game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_LOS_RANGE)
@@ -309,8 +283,7 @@ protected int calcMissileHits(Vector vPhaseReport) {
// I don't think i need to change anything here for iATMs. Seems just to
// handle Minefield clearance
@Override
- protected boolean specialResolution(Vector vPhaseReport,
- Entity entityTarget) {
+ protected boolean specialResolution(Vector vPhaseReport, Entity entityTarget) {
if (!bMissed
&& (target.getTargetType() == Targetable.TYPE_MINEFIELD_CLEAR)) {
Report r = new Report(3255);
@@ -319,13 +292,11 @@ protected boolean specialResolution(Vector vPhaseReport,
vPhaseReport.addElement(r);
Coords coords = target.getPosition();
- Enumeration minefields = game.getMinefields(coords)
- .elements();
+ Enumeration minefields = game.getMinefields(coords).elements();
ArrayList mfRemoved = new ArrayList<>();
while (minefields.hasMoreElements()) {
Minefield mf = minefields.nextElement();
- if (gameManager.clearMinefield(mf, ae,
- Minefield.CLEAR_NUMBER_WEAPON, vPhaseReport)) {
+ if (gameManager.clearMinefield(mf, ae, Minefield.CLEAR_NUMBER_WEAPON, vPhaseReport)) {
mfRemoved.add(mf);
}
}
@@ -339,11 +310,6 @@ protected boolean specialResolution(Vector vPhaseReport,
return false;
}
- /*
- * (non-Javadoc)
- *
- * @see megamek.common.weapons.WeaponHandler#allShotsHit()
- */
@Override
protected boolean allShotsHit() {
// If we IDF, we don't get the streak bonus
@@ -354,11 +320,6 @@ protected boolean allShotsHit() {
return super.allShotsHit() || !isAngelECMAffected;
}
- /*
- * (non-Javadoc)
- *
- * @see megamek.common.weapons.WeaponHandler#addHeat()
- */
@Override
protected void addHeat() {
// call super function if we are in IDF mode since we don't have streak
@@ -374,11 +335,6 @@ protected void addHeat() {
}
}
- /*
- * (non-Javadoc)
- *
- * @see megamek.common.weapons.WeaponHandler#UseAmmo()
- */
@Override
protected void useAmmo() {
// call super function if we are in IDF mode, since we don't have streak
@@ -405,11 +361,6 @@ protected void useAmmo() {
}
}
- /*
- * (non-Javadoc)
- *
- * @see megamek.common.weapons.WeaponHandler#reportMiss(java.util.Vector)
- */
@Override
protected void reportMiss(Vector vPhaseReport) {
// again, call super if we are in IDF mode.
diff --git a/megamek/src/megamek/common/weapons/CapitalMissileBearingsOnlyHandler.java b/megamek/src/megamek/common/weapons/CapitalMissileBearingsOnlyHandler.java
index 30e76dc2a5f..a2dd610482e 100644
--- a/megamek/src/megamek/common/weapons/CapitalMissileBearingsOnlyHandler.java
+++ b/megamek/src/megamek/common/weapons/CapitalMissileBearingsOnlyHandler.java
@@ -101,7 +101,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
return true;
}
ArtilleryAttackAction aaa = (ArtilleryAttackAction) waa;
- if (phase == GamePhase.TARGETING) {
+ if (phase.isTargeting()) {
if (!handledAmmoAndReport) {
addHeat();
// Report the firing itself
@@ -129,7 +129,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
}
Entity entityTarget = (aaa.getTargetType() == Targetable.TYPE_ENTITY) ? (Entity) aaa
.getTarget(game) : null;
- if (game.getPhase() == GamePhase.FIRING && entityTarget == null) {
+ if (game.getPhase().isFiring() && entityTarget == null) {
convertHexTargetToEntityTarget(vPhaseReport);
entityTarget = (aaa.getTargetType() == Targetable.TYPE_ENTITY) ? (Entity) aaa
.getTarget(game) : null;
diff --git a/megamek/src/megamek/common/weapons/FireExtinguisherHandler.java b/megamek/src/megamek/common/weapons/FireExtinguisherHandler.java
index 8f7b77dac0a..fcce425b09d 100644
--- a/megamek/src/megamek/common/weapons/FireExtinguisherHandler.java
+++ b/megamek/src/megamek/common/weapons/FireExtinguisherHandler.java
@@ -13,18 +13,11 @@
*/
package megamek.common.weapons;
-import java.util.Vector;
-
-import megamek.common.Entity;
-import megamek.common.Game;
-import megamek.common.Report;
-import megamek.common.Tank;
-import megamek.common.Targetable;
-import megamek.common.Terrains;
-import megamek.common.ToHitData;
+import megamek.common.*;
import megamek.common.actions.WeaponAttackAction;
import megamek.server.GameManager;
-import megamek.server.Server;
+
+import java.util.Vector;
/**
* @author Sebastian Brocks
@@ -33,22 +26,10 @@
public class FireExtinguisherHandler extends WeaponHandler {
private static final long serialVersionUID = -7047033962986081773L;
- /**
- * @param toHit
- * @param waa
- * @param g
- */
public FireExtinguisherHandler(ToHitData toHit, WeaponAttackAction waa, Game g, GameManager m) {
super(toHit, waa, g, m);
}
- /*
- * (non-Javadoc)
- *
- * @see
- * megamek.common.weapons.WeaponHandler#specialResolution(java.util.Vector,
- * megamek.common.Entity, boolean)
- */
@Override
protected boolean specialResolution(Vector vPhaseReport, Entity entityTarget) {
if (!bMissed) {
diff --git a/megamek/src/megamek/common/weapons/FlamerHandler.java b/megamek/src/megamek/common/weapons/FlamerHandler.java
index 5288a9f9b9d..f7f846179d0 100644
--- a/megamek/src/megamek/common/weapons/FlamerHandler.java
+++ b/megamek/src/megamek/common/weapons/FlamerHandler.java
@@ -17,7 +17,6 @@
import megamek.common.actions.WeaponAttackAction;
import megamek.common.options.OptionsConstants;
import megamek.server.GameManager;
-import megamek.server.Server;
import java.util.Vector;
@@ -28,11 +27,6 @@
public class FlamerHandler extends WeaponHandler {
private static final long serialVersionUID = -7348456582587703751L;
- /**
- * @param toHit
- * @param waa
- * @param g
- */
public FlamerHandler(ToHitData toHit, WeaponAttackAction waa, Game g, GameManager m) {
super(toHit, waa, g, m);
generalDamageType = HitData.DAMAGE_ENERGY;
diff --git a/megamek/src/megamek/common/weapons/MicroBombHandler.java b/megamek/src/megamek/common/weapons/MicroBombHandler.java
index aa1ba4d4519..9e5811c26c3 100644
--- a/megamek/src/megamek/common/weapons/MicroBombHandler.java
+++ b/megamek/src/megamek/common/weapons/MicroBombHandler.java
@@ -67,7 +67,9 @@ protected boolean specialResolution(Vector vPhaseReport, Entity entityTa
moF = -toHit.getMoS() - 2;
}
}
- coords = Compute.scatterDiveBombs(coords, moF);
+
+ // magic number - BA-launched micro bombs only scatter 1 hex per TW-2018 p 228
+ coords = Compute.scatter(coords, 1);
if (game.getBoard().contains(coords)) {
Report r = new Report(3195);
r.subject = subjectId;
diff --git a/megamek/src/megamek/common/weapons/MissileWeaponHandler.java b/megamek/src/megamek/common/weapons/MissileWeaponHandler.java
index 6351f7c1922..5f6d4b83b8d 100644
--- a/megamek/src/megamek/common/weapons/MissileWeaponHandler.java
+++ b/megamek/src/megamek/common/weapons/MissileWeaponHandler.java
@@ -33,14 +33,7 @@ public class MissileWeaponHandler extends AmmoWeaponHandler {
boolean advancedPD = false;
boolean multiAMS = false;
- /**
- * @param t
- * @param w
- * @param g
- * @param m
- */
- public MissileWeaponHandler(ToHitData t, WeaponAttackAction w, Game g,
- GameManager m) {
+ public MissileWeaponHandler(ToHitData t, WeaponAttackAction w, Game g, GameManager m) {
super(t, w, g, m);
generalDamageType = HitData.DAMAGE_MISSILE;
advancedAMS = g.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_AMS);
@@ -117,12 +110,10 @@ protected int calcHits(Vector vPhaseReport) {
} else {
nMissilesModifier += 2;
}
-
} else if (((mLinker != null)
&& (mLinker.getType() instanceof MiscType)
&& !mLinker.isDestroyed() && !mLinker.isMissing()
- && !mLinker.isBreached() && mLinker.getType().hasFlag(
- MiscType.F_ARTEMIS_PROTO))
+ && !mLinker.isBreached() && mLinker.getType().hasFlag(MiscType.F_ARTEMIS_PROTO))
&& (atype.getMunitionType() == AmmoType.M_ARTEMIS_CAPABLE)) {
if (bECMAffected) {
// ECM prevents bonus
@@ -142,8 +133,7 @@ protected int calcHits(Vector vPhaseReport) {
} else if (((mLinker != null)
&& (mLinker.getType() instanceof MiscType)
&& !mLinker.isDestroyed() && !mLinker.isMissing()
- && !mLinker.isBreached() && mLinker.getType().hasFlag(
- MiscType.F_ARTEMIS_V))
+ && !mLinker.isBreached() && mLinker.getType().hasFlag(MiscType.F_ARTEMIS_V))
&& (atype.getMunitionType() == AmmoType.M_ARTEMIS_V_CAPABLE)) {
if (bECMAffected) {
// ECM prevents bonus
@@ -163,8 +153,7 @@ protected int calcHits(Vector vPhaseReport) {
} else if (((mLinker != null)
&& (mLinker.getType() instanceof MiscType)
&& !mLinker.isDestroyed() && !mLinker.isMissing()
- && !mLinker.isBreached() && mLinker.getType().hasFlag(
- MiscType.F_APOLLO))
+ && !mLinker.isBreached() && mLinker.getType().hasFlag(MiscType.F_APOLLO))
&& (atype.getAmmoType() == AmmoType.T_MRM)) {
nMissilesModifier -= 1;
} else if (atype.getAmmoType() == AmmoType.T_ATM) {
@@ -184,15 +173,14 @@ protected int calcHits(Vector vPhaseReport) {
nMissilesModifier += 2;
}
} else if ((entityTarget != null)
- && (entityTarget.isNarcedBy(ae.getOwner().getTeam()) || entityTarget
- .isINarcedBy(ae.getOwner().getTeam()))) {
+ && (entityTarget.isNarcedBy(ae.getOwner().getTeam())
+ || entityTarget.isINarcedBy(ae.getOwner().getTeam()))) {
// only apply Narc bonus if we're not suffering ECM effect
// and we are using narc ammo, and we're not firing indirectly.
// narc capable missiles are only affected if the narc pod, which
// sits on the target, is ECM affected
boolean bTargetECMAffected = false;
- bTargetECMAffected = ComputeECM.isAffectedByECM(ae,
- target.getPosition(), target.getPosition());
+ bTargetECMAffected = ComputeECM.isAffectedByECM(ae, target.getPosition(), target.getPosition());
if (((atype.getAmmoType() == AmmoType.T_LRM)
|| (atype.getAmmoType() == AmmoType.T_LRM_IMP)
|| (atype.getAmmoType() == AmmoType.T_SRM)
@@ -224,24 +212,20 @@ protected int calcHits(Vector vPhaseReport) {
if (allShotsHit()) {
// We want buildings and large craft to be able to affect this number with AMS
// treat as a Streak launcher (cluster roll 11) to make this happen
- missilesHit = Compute.missilesHit(wtype.getRackSize(),
- nMissilesModifier, weapon.isHotLoaded(), true,
- isAdvancedAMS());
+ missilesHit = Compute.missilesHit(wtype.getRackSize(), nMissilesModifier,
+ weapon.isHotLoaded(), true, isAdvancedAMS());
} else {
if (ae instanceof BattleArmor) {
int shootingStrength = 1;
if ((weapon.getLocation() == BattleArmor.LOC_SQUAD)
- && !(weapon.isSquadSupportWeapon())) {
+ && !weapon.isSquadSupportWeapon()) {
shootingStrength = ((BattleArmor) ae).getShootingStrength();
}
- missilesHit = Compute.missilesHit(wtype.getRackSize()
- * shootingStrength,
- nMissilesModifier, weapon.isHotLoaded(), false,
- isAdvancedAMS());
+ missilesHit = Compute.missilesHit(wtype.getRackSize() * shootingStrength,
+ nMissilesModifier, weapon.isHotLoaded(), false, isAdvancedAMS());
} else {
- missilesHit = Compute.missilesHit(wtype.getRackSize(),
- nMissilesModifier, weapon.isHotLoaded(), false,
- isAdvancedAMS());
+ missilesHit = Compute.missilesHit(wtype.getRackSize(), nMissilesModifier,
+ weapon.isHotLoaded(), false, isAdvancedAMS());
}
}
@@ -314,8 +298,7 @@ protected int calcAttackValue() {
int bonus = 0;
if (((mLinker != null) && (mLinker.getType() instanceof MiscType)
&& !mLinker.isDestroyed() && !mLinker.isMissing()
- && !mLinker.isBreached() && mLinker.getType().hasFlag(
- MiscType.F_ARTEMIS))
+ && !mLinker.isBreached() && mLinker.getType().hasFlag(MiscType.F_ARTEMIS))
&& (atype.getMunitionType() == AmmoType.M_ARTEMIS_CAPABLE)) {
// MML3 gets no bonus from Artemis IV (how sad)
if (atype.getRackSize() > 3) {
@@ -325,10 +308,10 @@ protected int calcAttackValue() {
}
}
}
+
if (((mLinker != null) && (mLinker.getType() instanceof MiscType)
&& !mLinker.isDestroyed() && !mLinker.isMissing()
- && !mLinker.isBreached() && mLinker.getType().hasFlag(
- MiscType.F_ARTEMIS_PROTO))
+ && !mLinker.isBreached() && mLinker.getType().hasFlag(MiscType.F_ARTEMIS_PROTO))
&& (atype.getMunitionType() == AmmoType.M_ARTEMIS_CAPABLE)) {
// MML3 gets no bonus from Artemis IV (how sad)
if (atype.getRackSize() > 3) {
@@ -338,10 +321,10 @@ protected int calcAttackValue() {
}
}
}
+
if (((mLinker != null) && (mLinker.getType() instanceof MiscType)
&& !mLinker.isDestroyed() && !mLinker.isMissing()
- && !mLinker.isBreached() && mLinker.getType().hasFlag(
- MiscType.F_ARTEMIS_V))
+ && !mLinker.isBreached() && mLinker.getType().hasFlag(MiscType.F_ARTEMIS_V))
&& (atype.getMunitionType() == AmmoType.M_ARTEMIS_V_CAPABLE)) {
// MML3 WOULD get a bonus from Artemis V, if you were crazy enough
// to cross-tech it
@@ -426,6 +409,7 @@ protected boolean handleSpecialMiss(Entity entityTarget, boolean bldgDamagedOnMi
|| (toHit.getValue() == TargetRoll.AUTOMATIC_FAIL)) {
return false;
}
+
return true;
}
@@ -434,7 +418,7 @@ protected boolean handleSpecialMiss(Entity entityTarget, boolean bldgDamagedOnMi
protected double getAeroSanityAMSHitsMod() {
if (getParentBayHandler() != null) {
WeaponHandler bayHandler = getParentBayHandler();
- double counterAVMod = (bayHandler.getCounterAV() / bayHandler.weapon.getBayWeapons().size());
+ double counterAVMod = bayHandler.getCounterAV() / bayHandler.weapon.getBayWeapons().size();
// use this if point defenses engage the missiles
if (bayHandler.pdOverheated) {
// Halve the effectiveness
@@ -501,8 +485,7 @@ protected int getAMSHitsMod(Vector vPhaseReport) {
if (!(counter.getType() instanceof WeaponType)
|| !counter.isReady() || counter.isMissing()
// no AMS when a shield in the AMS location
- || (pdEnt.hasShield() && pdEnt.hasActiveShield(
- counter.getLocation(), false))
+ || (pdEnt.hasShield() && pdEnt.hasActiveShield(counter.getLocation(), false))
// shutdown means no AMS
|| pdEnt.isShutDown()) {
continue;
@@ -585,6 +568,7 @@ protected int getAMSHitsMod(Vector vPhaseReport) {
break;
default: // 4+
minApdsMod = -4;
+ break;
}
}
apdsMod = Math.min(minApdsMod + dist, 0);
@@ -618,8 +602,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
}
Entity entityTarget = (target.getTargetType() == Targetable.TYPE_ENTITY) ? (Entity) target
: null;
- final boolean targetInBuilding = Compute.isInBuilding(game,
- entityTarget);
+ final boolean targetInBuilding = Compute.isInBuilding(game, entityTarget);
final boolean bldgDamagedOnMiss = targetInBuilding
&& !(target instanceof Infantry)
&& ae.getPosition().distance(target.getPosition()) <= 1;
@@ -657,8 +640,8 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
boolean shotAtNemesisTarget = false;
if (bNemesisConfusable && !waa.isNemesisConfused()) {
// loop through nemesis targets
- for (Enumeration e = game.getNemesisTargets(ae,
- target.getPosition()); e.hasMoreElements();) {
+ for (Enumeration e = game.getNemesisTargets(ae, target.getPosition());
+ e.hasMoreElements(); ) {
Entity entity = e.nextElement();
// friendly unit with attached iNarc Nemesis pod standing in the way
r = new Report(3125);
@@ -812,8 +795,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
reportMiss(vPhaseReport);
// Works out fire setting, AMS shots, and whether continuation is necessary.
- if (!handleSpecialMiss(entityTarget, bldgDamagedOnMiss, bldg,
- vPhaseReport)) {
+ if (!handleSpecialMiss(entityTarget, bldgDamagedOnMiss, bldg, vPhaseReport)) {
return false;
}
}
@@ -841,12 +823,13 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
r.indent();
vPhaseReport.addElement(r);
} else if (pdOverheated) {
- //Report a partial failure
+ // Report a partial failure
r = new Report (3361);
r.subject = subjectId;
r.indent();
vPhaseReport.addElement(r);
}
+
if (!bMissed && amsEngaged && isTbolt() && !ae.isCapitalFighter()) {
// Thunderbolts are destroyed by AMS 50% of the time whether Aero Sanity is on or not
hits = calcHits(vPhaseReport);
@@ -855,6 +838,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
r.subject = subjectId;
vPhaseReport.addElement(r);
}
+
// This is for aero attacks as attack value. Does not apply if Aero Sanity is on
if (!game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_AERO_SANITY)) {
if (!bMissed && amsEngaged && !isTbolt() && !ae.isCapitalFighter()) {
@@ -874,7 +858,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
r.subject = subjectId;
vPhaseReport.addElement(r);
} else if (amsBayEngaged) {
- //use this if AMS counterfire destroys some of the missiles
+ // use this if AMS counterfire destroys some of the missiles
CounterAV = getCounterAV();
r = new Report(3354);
r.indent();
@@ -885,12 +869,12 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
// Report any Point Defense bay action against standard missiles.
} else if (pdBayEngaged && (originalAV <= 0)) {
- //use this if PD counterfire destroys all the missiles
+ // use this if PD counterfire destroys all the missiles
r = new Report(3355);
r.subject = subjectId;
vPhaseReport.addElement(r);
} else if (pdBayEngaged) {
- //use this if PD counterfire destroys some of the missiles
+ // use this if PD counterfire destroys some of the missiles
r = new Report(3353);
r.add(CounterAV);
r.subject = subjectId;
@@ -935,8 +919,7 @@ public boolean handle(GamePhase phase, Vector vPhaseReport) {
// Compute.directBlowInfantryDamage
nDamage = -wtype.getDamage(nRange) * Math.min(nCluster, hits);
}
- bldgAbsorbs = (int) Math.round(nDamage
- * bldg.getInfDmgFromInside());
+ bldgAbsorbs = (int) Math.round(nDamage * bldg.getInfDmgFromInside());
} else {
// Used later to indicate a special report
bldgAbsorbs = Integer.MIN_VALUE;
diff --git a/megamek/src/megamek/common/weapons/Weapon.java b/megamek/src/megamek/common/weapons/Weapon.java
index 64699269baa..e76dfe1ecda 100644
--- a/megamek/src/megamek/common/weapons/Weapon.java
+++ b/megamek/src/megamek/common/weapons/Weapon.java
@@ -13,13 +13,7 @@
*/
package megamek.common.weapons;
-import java.io.Serializable;
-
-import megamek.common.AmmoType;
-import megamek.common.Game;
-import megamek.common.TargetRoll;
-import megamek.common.ToHitData;
-import megamek.common.WeaponType;
+import megamek.common.*;
import megamek.common.actions.WeaponAttackAction;
import megamek.common.annotations.Nullable;
import megamek.common.options.GameOptions;
@@ -28,6 +22,8 @@
import megamek.common.weapons.bayweapons.SubCapLaserBayWeapon;
import megamek.server.GameManager;
+import java.io.Serializable;
+
/**
* A class representing a weapon.
* @author Andrew Hunter
diff --git a/megamek/src/megamek/common/weapons/WeaponHandler.java b/megamek/src/megamek/common/weapons/WeaponHandler.java
index 7e8e983bafd..7849434ecde 100644
--- a/megamek/src/megamek/common/weapons/WeaponHandler.java
+++ b/megamek/src/megamek/common/weapons/WeaponHandler.java
@@ -40,7 +40,6 @@
* @author Andrew Hunter
*/
public class WeaponHandler implements AttackHandler, Serializable {
-
private static final long serialVersionUID = 7137408139594693559L;
public ToHitData toHit;
protected HitData hit;
@@ -91,7 +90,7 @@ public class WeaponHandler implements AttackHandler, Serializable {
protected boolean isStrafing = false;
/**
- * Boolean flag that determiens if this shot was the first one by a
+ * Boolean flag that determines if this shot was the first one by a
* particular weapon in a strafing run. Used to ensure that heat is only
* added once.
*/
@@ -400,10 +399,7 @@ public Entity getAttacker() {
*/
@Override
public boolean cares(GamePhase phase) {
- if (phase == GamePhase.FIRING) {
- return true;
- }
- return false;
+ return phase.isFiring();
}
/**
@@ -428,21 +424,19 @@ private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
- private void readObject(ObjectInputStream in) throws IOException,
- ClassNotFoundException {
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
gameManager = (GameManager) Server.getServerInstance().getGameManager();
}
/**
- * @return a boolean value indicating wether or not this attack
+ * @return a boolean value indicating whether or not this attack
* needs further calculating, like a missed shot hitting a building,
* or an AMS only shooting down some missiles.
*/
- protected boolean handleSpecialMiss(Entity entityTarget,
- boolean bldgDamagedOnMiss, Building bldg,
- Vector vPhaseReport) {
+ protected boolean handleSpecialMiss(Entity entityTarget, boolean bldgDamagedOnMiss,
+ Building bldg, Vector vPhaseReport) {
// Shots that miss an entity can set fires.
// Buildings can't be accidentally ignited,
// and some weapons can't ignite fires.
@@ -1090,9 +1084,7 @@ public boolean handle(GamePhase phase, Vector returnedReports) {
int nDamage;
if ((target.getTargetType() == Targetable.TYPE_HEX_TAG)
|| (target.getTargetType() == Targetable.TYPE_BLDG_TAG)) {
-
- TagInfo info = new TagInfo(ae.getId(),
- target.getTargetType(), target, false);
+ TagInfo info = new TagInfo(ae.getId(), target.getTargetType(), target, false);
game.addTagInfo(info);
ae.setSpotting(true);
@@ -1116,12 +1108,10 @@ public boolean handle(GamePhase phase, Vector returnedReports) {
} else if (target.getTargetType() == Targetable.TYPE_BUILDING) {
// The building takes the full brunt of the attack.
nDamage = nDamPerHit * hits;
- handleBuildingDamage(vPhaseReport, bldg, nDamage,
- target.getPosition());
+ handleBuildingDamage(vPhaseReport, bldg, nDamage, target.getPosition());
hits = 0;
} else if (entityTarget != null) {
- handleEntityDamage(entityTarget, vPhaseReport, bldg,
- hits, nCluster, bldgAbsorbs);
+ handleEntityDamage(entityTarget, vPhaseReport, bldg, hits, nCluster, bldgAbsorbs);
gameManager.creditKill(entityTarget, ae);
hits -= nCluster;
firstHit = false;
@@ -1133,7 +1123,6 @@ public boolean handle(GamePhase phase, Vector returnedReports) {
}
} // Handle the next cluster.
} else { // We missed, but need to handle special miss cases
-
// When shooting at a non-infantry unit in a building and the
// shot misses, the building is damaged instead, TW pg 171
if (bldgDamagedOnMiss) {
@@ -1153,6 +1142,7 @@ public boolean handle(GamePhase phase, Vector returnedReports) {
hits = 0;
}
}
+
if (game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_UAC_TWOROLLS)
&& ((wtype.getAmmoType() == AmmoType.T_AC_ULTRA) || (wtype
.getAmmoType() == AmmoType.T_AC_ULTRA_THB))
@@ -1418,18 +1408,16 @@ protected void handlePartialCoverHit(Entity entityTarget,
} else if (damageableCoverType == LosEffects.DAMAGABLE_COVER_BUILDING) {
// Normal damage
int nDamage = nDamPerHit * Math.min(nCluster, hits);
- Vector buildingReport = gameManager.damageBuilding(
- coverBuilding, nDamage, " blocks the shot and takes ",
- coverLoc);
+ Vector buildingReport = gameManager.damageBuilding(coverBuilding, nDamage,
+ " blocks the shot and takes ", coverLoc);
for (Report report : buildingReport) {
report.subject = subjectId;
report.indent();
}
vPhaseReport.addAll(buildingReport);
// Damage any infantry in the building.
- Vector infantryReport = gameManager.damageInfantryIn(
- coverBuilding, nDamage, coverLoc,
- wtype.getInfantryDamageClass());
+ Vector infantryReport = gameManager.damageInfantryIn(coverBuilding, nDamage,
+ coverLoc, wtype.getInfantryDamageClass());
for (Report report : infantryReport) {
report.indent(2);
}
@@ -1545,13 +1533,11 @@ protected void handleEntityDamage(Entity entityTarget,
hit.makeGlancingBlow();
}
- vPhaseReport
- .addAll(gameManager.damageEntity(entityTarget, hit, nDamage,
- false, ae.getSwarmTargetId() == entityTarget
- .getId() ? DamageType.IGNORE_PASSENGER
- : damageType, false, false, throughFront,
- underWater, nukeS2S));
- if (damageType.equals(DamageType.ANTI_TSM) && (target instanceof Mech) && entityTarget.antiTSMVulnerable()) {
+ vPhaseReport.addAll(gameManager.damageEntity(entityTarget, hit, nDamage, false,
+ ae.getSwarmTargetId() == entityTarget.getId() ? DamageType.IGNORE_PASSENGER : damageType,
+ false, false, throughFront, underWater, nukeS2S));
+ if (damageType.equals(DamageType.ANTI_TSM) && (target instanceof Mech)
+ && entityTarget.antiTSMVulnerable()) {
vPhaseReport.addAll(gameManager.doGreenSmokeDamage(entityTarget));
}
// for salvo shots, report that the aimed location was hit after
@@ -1594,13 +1580,13 @@ protected boolean unitStickingOutOfBuilding(Hex targetHex, Entity entityTarget)
(entityTarget.getElevation() < targetHex.ceiling()) &&
(entityTarget.relHeight() >= targetHex.ceiling());
}
-
+
/**
* Worker function to (maybe) have a building absorb damage meant for the entity
*/
- protected int absorbBuildingDamage(int nDamage, Entity entityTarget, int bldgAbsorbs,
- Vector vPhaseReport, Building bldg, boolean targetStickingOutOfBuilding) {
-
+ protected int absorbBuildingDamage(int nDamage, Entity entityTarget, int bldgAbsorbs,
+ Vector vPhaseReport, Building bldg,
+ boolean targetStickingOutOfBuilding) {
// if the building will absorb some damage and the target is actually
// entirely inside the building:
if ((bldgAbsorbs > 0) && !targetStickingOutOfBuilding) {
@@ -1635,8 +1621,7 @@ protected int absorbBuildingDamage(int nDamage, Entity entityTarget, int bldgAbs
return nDamage;
}
- protected void handleIgnitionDamage(Vector vPhaseReport,
- Building bldg, int hits) {
+ protected void handleIgnitionDamage(Vector vPhaseReport, Building bldg, int hits) {
if (!bSalvo) {
// hits!
Report r = new Report(2270);
@@ -1652,13 +1637,12 @@ protected void handleIgnitionDamage(Vector vPhaseReport,
}
}
- protected void handleClearDamage(Vector vPhaseReport,
- Building bldg, int nDamage) {
+ protected void handleClearDamage(Vector vPhaseReport, Building bldg, int nDamage) {
handleClearDamage(vPhaseReport, bldg, nDamage, true);
}
- protected void handleClearDamage(Vector vPhaseReport,
- Building bldg, int nDamage, boolean hitReport) {
+ protected void handleClearDamage(Vector vPhaseReport, Building bldg, int nDamage,
+ boolean hitReport) {
if (!bSalvo && hitReport) {
// hits!
Report r = new Report(2270);
@@ -1679,14 +1663,11 @@ protected void handleClearDamage(Vector vPhaseReport,
// a 5 or less
// you do a normal ignition as though for intentional fires
if ((bldg != null)
- && gameManager.tryIgniteHex(target.getPosition(), subjectId, false,
- false,
- new TargetRoll(wtype.getFireTN(), wtype.getName()), 5,
- vPhaseReport)) {
+ && gameManager.tryIgniteHex(target.getPosition(), subjectId, false, false,
+ new TargetRoll(wtype.getFireTN(), wtype.getName()), 5, vPhaseReport)) {
return;
}
- Vector clearReports = gameManager.tryClearHex(target.getPosition(),
- nDamage, subjectId);
+ Vector clearReports = gameManager.tryClearHex(target.getPosition(), nDamage, subjectId);
if (!clearReports.isEmpty()) {
vPhaseReport.lastElement().newlines = 0;
}
diff --git a/megamek/src/megamek/common/weapons/artillery/ArtilleryWeapon.java b/megamek/src/megamek/common/weapons/artillery/ArtilleryWeapon.java
index cf5b7f6c59b..8e5fa43da85 100644
--- a/megamek/src/megamek/common/weapons/artillery/ArtilleryWeapon.java
+++ b/megamek/src/megamek/common/weapons/artillery/ArtilleryWeapon.java
@@ -17,13 +17,7 @@
import megamek.common.Mounted;
import megamek.common.ToHitData;
import megamek.common.actions.WeaponAttackAction;
-import megamek.common.enums.GamePhase;
-import megamek.common.weapons.AmmoWeapon;
-import megamek.common.weapons.ArtilleryWeaponDirectFireHandler;
-import megamek.common.weapons.ArtilleryWeaponDirectHomingHandler;
-import megamek.common.weapons.ArtilleryWeaponIndirectFireHandler;
-import megamek.common.weapons.ArtilleryWeaponIndirectHomingHandler;
-import megamek.common.weapons.AttackHandler;
+import megamek.common.weapons.*;
import megamek.server.GameManager;
/**
@@ -55,11 +49,11 @@ protected AttackHandler getCorrectHandler(ToHitData toHit,
.getEquipment(waa.getWeaponId()).getLinked();
if (ammo.isHomingAmmoInHomingMode()) {
- if (game.getPhase() == GamePhase.FIRING) {
+ if (game.getPhase().isFiring()) {
return new ArtilleryWeaponDirectHomingHandler(toHit, waa, game, manager);
}
return new ArtilleryWeaponIndirectHomingHandler(toHit, waa, game, manager);
- } else if (game.getPhase() == GamePhase.FIRING) {
+ } else if (game.getPhase().isFiring()) {
return new ArtilleryWeaponDirectFireHandler(toHit, waa, game, manager);
} else {
return new ArtilleryWeaponIndirectFireHandler(toHit, waa, game, manager);
diff --git a/megamek/src/megamek/common/weapons/autocannons/ACWeapon.java b/megamek/src/megamek/common/weapons/autocannons/ACWeapon.java
index 7fd1fa98aaa..484b0f5b69f 100644
--- a/megamek/src/megamek/common/weapons/autocannons/ACWeapon.java
+++ b/megamek/src/megamek/common/weapons/autocannons/ACWeapon.java
@@ -33,6 +33,7 @@
import megamek.common.weapons.RapidfireACWeaponHandler;
import megamek.common.weapons.Weapon;
import megamek.server.GameManager;
+import megamek.server.Server;
/**
* N.B. This class is overridden for AC/2, AC/5, AC/10, AC/10, NOT ultras/LB/RAC.
@@ -106,13 +107,13 @@ public int getDamage() {
if ((dmg != 5) && (dmg != 2)) {
return dmg;
}
- GameOptions options = getGameOptions();
- if (options == null) {
- return dmg;
- }
- if (options.getOption(OptionsConstants.ADVCOMBAT_INCREASED_AC_DMG).booleanValue()) {
+
+ if ((Server.getServerInstance() != null)
+ && Server.getServerInstance().getGame().getOptions()
+ .getOption(OptionsConstants.ADVCOMBAT_INCREASED_AC_DMG).booleanValue()) {
dmg++;
}
+
return dmg;
}
diff --git a/megamek/src/megamek/common/weapons/autocannons/CLImprovedAC2.java b/megamek/src/megamek/common/weapons/autocannons/CLImprovedAC2.java
index aba8bf806f4..48f92983f47 100644
--- a/megamek/src/megamek/common/weapons/autocannons/CLImprovedAC2.java
+++ b/megamek/src/megamek/common/weapons/autocannons/CLImprovedAC2.java
@@ -43,7 +43,9 @@ public CLImprovedAC2() {
criticals = 1;
bv = 37;
cost = 75000;
- shortAV = 20;
+ shortAV = 2;
+ medAV = 2;
+ longAV = 2;
maxRange = RANGE_LONG;
explosionDamage = damage;
ammoType = AmmoType.T_AC_IMP;
diff --git a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM1OS.java b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM1OS.java
index c69c35798a3..a93834fbba5 100644
--- a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM1OS.java
+++ b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM1OS.java
@@ -36,7 +36,7 @@ public CLAdvancedSRM1OS() {
extremeRange = 16;
bv = 3;
flags = flags.or(F_NO_FIRES).or(F_BA_WEAPON).or(F_ONESHOT).andNot(F_MECH_WEAPON).andNot(F_TANK_WEAPON).andNot(F_AERO_WEAPON).andNot(F_PROTO_WEAPON);
- tonnage = 0.04;
+ tonnage = 0.035;
criticals = 3;
cost = 7500;
rulesRefs = "261, TM";
diff --git a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM2OS.java b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM2OS.java
index e87d32b7412..9c9cb93cda0 100644
--- a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM2OS.java
+++ b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM2OS.java
@@ -36,7 +36,7 @@ public CLAdvancedSRM2OS() {
extremeRange = 16;
bv = 6;
flags = flags.or(F_NO_FIRES).or(F_BA_WEAPON).or(F_ONESHOT).andNot(F_MECH_WEAPON).andNot(F_TANK_WEAPON).andNot(F_AERO_WEAPON).andNot(F_PROTO_WEAPON);
- tonnage = .06;
+ tonnage = .07;
criticals = 3;
cost = 15000;
rulesRefs = "261, TM";
diff --git a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM3OS.java b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM3OS.java
index 9d68b7495d4..eb1178f7fb3 100644
--- a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM3OS.java
+++ b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM3OS.java
@@ -36,7 +36,7 @@ public CLAdvancedSRM3OS() {
extremeRange = 16;
bv = 9;
flags = flags.or(F_NO_FIRES).or(F_BA_WEAPON).or(F_ONESHOT).andNot(F_MECH_WEAPON).andNot(F_TANK_WEAPON).andNot(F_AERO_WEAPON).andNot(F_PROTO_WEAPON);
- tonnage = .80;
+ tonnage = .105;
criticals = 4;
cost = 22500;
rulesRefs = "261, TM";
diff --git a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM4OS.java b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM4OS.java
index 7ce48620702..c141e7af8fa 100644
--- a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM4OS.java
+++ b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM4OS.java
@@ -36,7 +36,7 @@ public CLAdvancedSRM4OS() {
extremeRange = 16;
bv = 12;
flags = flags.or(F_NO_FIRES).or(F_BA_WEAPON).or(F_ONESHOT).andNot(F_MECH_WEAPON).andNot(F_TANK_WEAPON).andNot(F_AERO_WEAPON).andNot(F_PROTO_WEAPON);
- tonnage = 0.100;
+ tonnage = 0.135;
criticals = 4;
cost = 30000;
rulesRefs = "261, TM";
diff --git a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM5OS.java b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM5OS.java
index ef629f321ff..bf01812a3e4 100644
--- a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM5OS.java
+++ b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM5OS.java
@@ -36,7 +36,7 @@ public CLAdvancedSRM5OS() {
extremeRange = 16;
bv = 15;
flags = flags.or(F_NO_FIRES).or(F_BA_WEAPON).or(F_ONESHOT).andNot(F_MECH_WEAPON).andNot(F_TANK_WEAPON).andNot(F_AERO_WEAPON).andNot(F_PROTO_WEAPON);
- tonnage = 0.120;
+ tonnage = 0.165;
criticals = 5;
cost = 37500;
rulesRefs = "261, TM";
diff --git a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM6OS.java b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM6OS.java
index bfc01a525bb..22c37f7cbbd 100644
--- a/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM6OS.java
+++ b/megamek/src/megamek/common/weapons/battlearmor/CLAdvancedSRM6OS.java
@@ -36,7 +36,7 @@ public CLAdvancedSRM6OS() {
extremeRange = 16;
bv = 18;
flags = flags.or(F_NO_FIRES).or(F_BA_WEAPON).or(F_ONESHOT).andNot(F_MECH_WEAPON).andNot(F_TANK_WEAPON).andNot(F_AERO_WEAPON).andNot(F_PROTO_WEAPON);
- tonnage = .140;
+ tonnage = .195;
criticals = 5;
cost = 45000;
rulesRefs = "261, TM";
diff --git a/megamek/src/megamek/common/weapons/battlearmor/CLBAAPGaussRifle.java b/megamek/src/megamek/common/weapons/battlearmor/CLBAAPGaussRifle.java
index 6d6ebb29ba6..618e0cbf8e1 100644
--- a/megamek/src/megamek/common/weapons/battlearmor/CLBAAPGaussRifle.java
+++ b/megamek/src/megamek/common/weapons/battlearmor/CLBAAPGaussRifle.java
@@ -35,7 +35,7 @@ public CLBAAPGaussRifle() {
longRange = 9;
extremeRange = 12;
tonnage = 0.2;
- criticals = 1;
+ criticals = 2;
bv = 21;
cost = 10000;
shortAV = 3;
diff --git a/megamek/src/megamek/common/weapons/battlearmor/CLBAMortarHeavy.java b/megamek/src/megamek/common/weapons/battlearmor/CLBAMortarHeavy.java
index a6c278d168e..094c303ad27 100644
--- a/megamek/src/megamek/common/weapons/battlearmor/CLBAMortarHeavy.java
+++ b/megamek/src/megamek/common/weapons/battlearmor/CLBAMortarHeavy.java
@@ -14,7 +14,9 @@
package megamek.common.weapons.battlearmor;
import megamek.common.AmmoType;
+import megamek.common.Mounted;
import megamek.common.WeaponType;
+import megamek.common.alphaStrike.AlphaStrikeElement;
import megamek.common.weapons.Weapon;
/**
@@ -61,4 +63,20 @@ public CLBAMortarHeavy() {
.setPrototypeFactions(F_FS, F_LC)
.setProductionFactions(F_LC);
}
-}
+
+ @Override
+ public double getBattleForceDamage(int range, Mounted linked) {
+ if (range <= AlphaStrikeElement.SHORT_RANGE) {
+ return 0.249;
+ } else if (range <= AlphaStrikeElement.MEDIUM_RANGE) {
+ return 0.3;
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public boolean isAlphaStrikeIndirectFire() {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/battlearmor/CLBAMortarLight.java b/megamek/src/megamek/common/weapons/battlearmor/CLBAMortarLight.java
index 22951b497c9..a49e82bb7e0 100644
--- a/megamek/src/megamek/common/weapons/battlearmor/CLBAMortarLight.java
+++ b/megamek/src/megamek/common/weapons/battlearmor/CLBAMortarLight.java
@@ -14,7 +14,9 @@
package megamek.common.weapons.battlearmor;
import megamek.common.AmmoType;
+import megamek.common.Mounted;
import megamek.common.WeaponType;
+import megamek.common.alphaStrike.AlphaStrikeElement;
import megamek.common.weapons.Weapon;
/**
@@ -62,4 +64,14 @@ public CLBAMortarLight() {
.setPrototypeFactions(F_FS, F_LC)
.setProductionFactions(F_LC);
}
-}
+
+ @Override
+ public double getBattleForceDamage(int range, Mounted linked) {
+ return (range <= AlphaStrikeElement.SHORT_RANGE) ? 0.276 : 0;
+ }
+
+ @Override
+ public boolean isAlphaStrikeIndirectFire() {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/battlearmor/ISBAMortarHeavy.java b/megamek/src/megamek/common/weapons/battlearmor/ISBAMortarHeavy.java
index 2ace8cc92ae..e01ba4ea0cf 100644
--- a/megamek/src/megamek/common/weapons/battlearmor/ISBAMortarHeavy.java
+++ b/megamek/src/megamek/common/weapons/battlearmor/ISBAMortarHeavy.java
@@ -14,8 +14,10 @@
package megamek.common.weapons.battlearmor;
import megamek.common.AmmoType;
+import megamek.common.Mounted;
import megamek.common.TechAdvancement;
import megamek.common.WeaponType;
+import megamek.common.alphaStrike.AlphaStrikeElement;
import megamek.common.weapons.Weapon;
/**
@@ -55,4 +57,19 @@ public ISBAMortarHeavy() {
techAdvancement.setAvailability(RATING_X, RATING_X, RATING_C, RATING_C);
}
-}
+ @Override
+ public double getBattleForceDamage(int range, Mounted linked) {
+ if (range <= AlphaStrikeElement.SHORT_RANGE) {
+ return 0.249;
+ } else if (range <= AlphaStrikeElement.MEDIUM_RANGE) {
+ return 0.3;
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public boolean isAlphaStrikeIndirectFire() {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/battlearmor/ISBAMortarLight.java b/megamek/src/megamek/common/weapons/battlearmor/ISBAMortarLight.java
index b855f62fccb..dafc4b07a84 100644
--- a/megamek/src/megamek/common/weapons/battlearmor/ISBAMortarLight.java
+++ b/megamek/src/megamek/common/weapons/battlearmor/ISBAMortarLight.java
@@ -14,8 +14,10 @@
package megamek.common.weapons.battlearmor;
import megamek.common.AmmoType;
+import megamek.common.Mounted;
import megamek.common.TechAdvancement;
import megamek.common.WeaponType;
+import megamek.common.alphaStrike.AlphaStrikeElement;
import megamek.common.weapons.Weapon;
/**
@@ -53,4 +55,14 @@ public ISBAMortarLight() {
techAdvancement.setTechRating(RATING_B);
techAdvancement.setAvailability(RATING_X, RATING_X, RATING_C, RATING_C);
}
-}
+
+ @Override
+ public double getBattleForceDamage(int range, Mounted linked) {
+ return (range <= AlphaStrikeElement.SHORT_RANGE) ? 0.276 : 0;
+ }
+
+ @Override
+ public boolean isAlphaStrikeIndirectFire() {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/bayweapons/ArtilleryBayWeapon.java b/megamek/src/megamek/common/weapons/bayweapons/ArtilleryBayWeapon.java
index 189c82f8e40..108f3505e89 100644
--- a/megamek/src/megamek/common/weapons/bayweapons/ArtilleryBayWeapon.java
+++ b/megamek/src/megamek/common/weapons/bayweapons/ArtilleryBayWeapon.java
@@ -15,7 +15,6 @@
import megamek.common.*;
import megamek.common.actions.WeaponAttackAction;
-import megamek.common.enums.GamePhase;
import megamek.common.weapons.*;
import megamek.server.GameManager;
@@ -70,11 +69,11 @@ protected AttackHandler getCorrectHandler(ToHitData toHit,
break;
}
if (useHoming) {
- if (game.getPhase() == GamePhase.FIRING) {
+ if (game.getPhase().isFiring()) {
return new ArtilleryBayWeaponDirectHomingHandler(toHit, waa, game, manager);
}
return new ArtilleryBayWeaponIndirectHomingHandler(toHit, waa, game, manager);
- } else if (game.getPhase() == GamePhase.FIRING) {
+ } else if (game.getPhase().isFiring()) {
return new ArtilleryBayWeaponDirectFireHandler(toHit, waa, game, manager);
} else {
return new ArtilleryBayWeaponIndirectFireHandler(toHit, waa, game, manager);
diff --git a/megamek/src/megamek/common/weapons/infantry/InfantryWeaponHandler.java b/megamek/src/megamek/common/weapons/infantry/InfantryWeaponHandler.java
index 00b9a4562a2..a51836a8cb0 100644
--- a/megamek/src/megamek/common/weapons/infantry/InfantryWeaponHandler.java
+++ b/megamek/src/megamek/common/weapons/infantry/InfantryWeaponHandler.java
@@ -206,4 +206,24 @@ public static double calculateBaseDamage(Entity ae, Mounted weapon, WeaponType w
return ((InfantryWeapon) wtype).getInfantryDamage();
}
}
+
+ @Override
+ protected void initHit(Entity entityTarget) {
+ if ((entityTarget instanceof BattleArmor) && ae.isConventionalInfantry()) {
+ // TacOps crits against BA do not happen for infantry weapon attacks
+ hit = ((BattleArmor) entityTarget).rollHitLocation(toHit.getSideTable(),
+ waa.getAimedLocation(), waa.getAimingMode(), true);
+ hit.setGeneralDamageType(generalDamageType);
+ hit.setCapital(wtype.isCapital());
+ hit.setBoxCars(roll == 12);
+ hit.setCapMisCritMod(getCapMisMod());
+ hit.setFirstHit(firstHit);
+ hit.setAttackerId(getAttackerId());
+ if (weapon.isWeaponGroup()) {
+ hit.setSingleAV(attackValue);
+ }
+ } else {
+ super.initHit(entityTarget);
+ }
+ }
}
diff --git a/megamek/src/megamek/common/weapons/lasers/CLERPulseLaserSmall.java b/megamek/src/megamek/common/weapons/lasers/CLERPulseLaserSmall.java
index 91371358419..b8c1981f44c 100644
--- a/megamek/src/megamek/common/weapons/lasers/CLERPulseLaserSmall.java
+++ b/megamek/src/megamek/common/weapons/lasers/CLERPulseLaserSmall.java
@@ -45,9 +45,8 @@ public CLERPulseLaserSmall() {
waterExtremeRange = 4;
tonnage = 1.5;
criticals = 1;
- shortAV = 7;
- medAV = 7;
- maxRange = RANGE_MED;
+ shortAV = 5;
+ maxRange = RANGE_SHORT;
bv = 36;
cost = 30000;
flags = flags.or(F_BURST_FIRE);
diff --git a/megamek/src/megamek/common/weapons/lasers/ISERLaserLarge.java b/megamek/src/megamek/common/weapons/lasers/ISERLaserLarge.java
index 633065fdc40..d91af48a8d1 100644
--- a/megamek/src/megamek/common/weapons/lasers/ISERLaserLarge.java
+++ b/megamek/src/megamek/common/weapons/lasers/ISERLaserLarge.java
@@ -15,6 +15,7 @@
import megamek.common.options.GameOptions;
import megamek.common.options.OptionsConstants;
+import megamek.server.Server;
/**
* @author Andrew Hunter
@@ -62,15 +63,16 @@ public ISERLaserLarge() {
@Override
public int getLongRange() {
- GameOptions options = getGameOptions();
- if (options == null) {
- return super.getLongRange();
- } else if (options.getOption(OptionsConstants.ADVCOMBAT_INCREASED_ISERLL_RANGE) == null) {
+ if (Server.getServerInstance() == null) {
return super.getLongRange();
}
- if (options.getOption(OptionsConstants.ADVCOMBAT_INCREASED_ISERLL_RANGE).booleanValue()) {
+ final GameOptions options = Server.getServerInstance().getGame().getOptions();
+ if (options.getOption(OptionsConstants.ADVCOMBAT_INCREASED_ISERLL_RANGE) == null) {
+ return super.getLongRange();
+ } else if (options.getOption(OptionsConstants.ADVCOMBAT_INCREASED_ISERLL_RANGE).booleanValue()) {
return 21;
+ } else {
+ return super.getLongRange();
}
- return super.getLongRange();
}
}
diff --git a/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserLarge.java b/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserLarge.java
index 1563ee3c767..81cd379910f 100644
--- a/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserLarge.java
+++ b/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserLarge.java
@@ -54,10 +54,10 @@ public ISReengineeredLaserLarge() {
.setUnofficial(false)
.setTechRating(RATING_E)
.setAvailability(RATING_X, RATING_X, RATING_X, RATING_D)
- .setISAdvancement(DATE_NONE,3120, 3130,DATE_NONE, DATE_NONE)
- .setISApproximate(false, true, false, false, false)
+ .setISAdvancement(3120, 3130,DATE_NONE,DATE_NONE, DATE_NONE)
+ .setISApproximate(true, false, false, false, false)
.setPrototypeFactions(F_FS)
.setProductionFactions(F_FS)
- .setStaticTechLevel(SimpleTechLevel.STANDARD);
+ .setStaticTechLevel(SimpleTechLevel.ADVANCED);
}
}
diff --git a/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserMedium.java b/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserMedium.java
index 980b492b945..de907cfae51 100644
--- a/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserMedium.java
+++ b/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserMedium.java
@@ -53,10 +53,10 @@ public ISReengineeredLaserMedium() {
.setUnofficial(false)
.setTechRating(RATING_E)
.setAvailability(RATING_X, RATING_X, RATING_X, RATING_D)
- .setISAdvancement(DATE_NONE,3120, 3130,DATE_NONE, DATE_NONE)
- .setISApproximate(false, true, false, false, false)
+ .setISAdvancement(3120, 3130,DATE_NONE,DATE_NONE, DATE_NONE)
+ .setISApproximate(true, false, false, false, false)
.setPrototypeFactions(F_FS)
.setProductionFactions(F_FS)
- .setStaticTechLevel(SimpleTechLevel.STANDARD);
+ .setStaticTechLevel(SimpleTechLevel.ADVANCED);
}
}
diff --git a/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserSmall.java b/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserSmall.java
index 48a0b037010..4b7cb542fe7 100644
--- a/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserSmall.java
+++ b/megamek/src/megamek/common/weapons/lasers/ISReengineeredLaserSmall.java
@@ -52,11 +52,11 @@ public ISReengineeredLaserSmall() {
.setUnofficial(false)
.setTechRating(RATING_E)
.setAvailability(RATING_X, RATING_X, RATING_X, RATING_D)
- .setISAdvancement(DATE_NONE,3120, 3130,DATE_NONE, DATE_NONE)
- .setISApproximate(false, true, false, false, false)
+ .setISAdvancement(3120, 3130,DATE_NONE,DATE_NONE, DATE_NONE)
+ .setISApproximate(true, false, false, false, false)
.setPrototypeFactions(F_FS)
.setProductionFactions(F_FS)
- .setStaticTechLevel(SimpleTechLevel.STANDARD);
+ .setStaticTechLevel(SimpleTechLevel.ADVANCED);
}
@Override
diff --git a/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserLarge.java b/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserLarge.java
index 9accbfa903e..07eca70a913 100644
--- a/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserLarge.java
+++ b/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserLarge.java
@@ -54,10 +54,11 @@ public ISVariableSpeedPulseLaserLarge() {
medAV = 7;
maxRange = RANGE_MED;
rulesRefs = "321, TO";
+ //Nov 22 - CGL requested we move to Standard for Simple Tech Level
techAdvancement.setTechBase(TECH_BASE_IS).setTechRating(RATING_E)
.setAvailability(RATING_X, RATING_X, RATING_E, RATING_D)
.setISAdvancement(3070, 3072, 3080).setPrototypeFactions(F_FW,F_WB)
- .setProductionFactions(F_FW,F_WB).setStaticTechLevel(SimpleTechLevel.ADVANCED);
+ .setProductionFactions(F_FW,F_WB).setStaticTechLevel(SimpleTechLevel.STANDARD);
}
@Override
diff --git a/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserMedium.java b/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserMedium.java
index b41068d4354..1577ce0f29b 100644
--- a/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserMedium.java
+++ b/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserMedium.java
@@ -52,10 +52,11 @@ public ISVariableSpeedPulseLaserMedium() {
shortAV = 7;
maxRange = RANGE_SHORT;
rulesRefs = "321, TO";
+ //Nov 22 - CGL requested we move to Standard for Simple Tech Level
techAdvancement.setTechBase(TECH_BASE_IS).setTechRating(RATING_E)
.setAvailability(RATING_X, RATING_X, RATING_E, RATING_D)
.setISAdvancement(3070, 3072, 3080).setPrototypeFactions(F_FW, F_WB)
- .setProductionFactions(F_FW, F_WB).setStaticTechLevel(SimpleTechLevel.ADVANCED);
+ .setProductionFactions(F_FW, F_WB).setStaticTechLevel(SimpleTechLevel.STANDARD);
}
@Override
diff --git a/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserSmall.java b/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserSmall.java
index 68537e95515..c22f7c43933 100644
--- a/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserSmall.java
+++ b/megamek/src/megamek/common/weapons/lasers/ISVariableSpeedPulseLaserSmall.java
@@ -53,10 +53,11 @@ public ISVariableSpeedPulseLaserSmall() {
shortAV = 4;
maxRange = RANGE_SHORT;
rulesRefs = "321, TO";
+ //Nov 22 - CGL requested we move to Standard for Simple Tech Level
techAdvancement.setTechBase(TECH_BASE_IS).setTechRating(RATING_E)
.setAvailability(RATING_X, RATING_X, RATING_E, RATING_D)
.setISAdvancement(3070, 3072, 3080).setPrototypeFactions(F_FW, F_WB)
- .setProductionFactions(F_FW, F_WB).setStaticTechLevel(SimpleTechLevel.ADVANCED);
+ .setProductionFactions(F_FW, F_WB).setStaticTechLevel(SimpleTechLevel.STANDARD);
}
@Override
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderBolt10.java b/megamek/src/megamek/common/weapons/missiles/ISThunderBolt10.java
index e3edb462dbe..fd1ebf4b6e9 100644
--- a/megamek/src/megamek/common/weapons/missiles/ISThunderBolt10.java
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderBolt10.java
@@ -19,24 +19,12 @@
*/
package megamek.common.weapons.missiles;
-import megamek.common.AmmoType;
-import megamek.common.alphaStrike.AlphaStrikeElement;
-import megamek.common.Mounted;
-import megamek.common.SimpleTechLevel;
-
/**
* @author Sebastian Brocks
*/
-public class ISThunderBolt10 extends ThunderBoltWeapon {
-
- /**
- *
- */
+public class ISThunderBolt10 extends Thunderbolt10Weapon {
private static final long serialVersionUID = 6781882739979127656L;
- /**
- *
- */
public ISThunderBolt10() {
super();
name = "Thunderbolt 10";
@@ -45,43 +33,8 @@ public ISThunderBolt10() {
addLookupName("ISThunderbolt10");
addLookupName("IS Thunderbolt 10");
addLookupName("ISTBolt10");
- ammoType = AmmoType.T_TBOLT_10;
- heat = 5;
- minimumRange = 5;
- shortRange = 6;
- mediumRange = 12;
- longRange = 18;
- extremeRange = 24;
- shortAV = 10;
- medAV = 10;
- maxRange = RANGE_MED;
- tonnage = 7.0;
- criticals = 2;
+ tonnage = 7;
bv = 127;
cost = 175000;
- flags = flags.or(F_LARGEMISSILE);
- this.missileArmor = 10;
- rulesRefs = "347, TO";
- techAdvancement.setTechBase(TECH_BASE_IS)
- .setIntroLevel(false)
- .setUnofficial(false)
- .setTechRating(RATING_E)
- .setAvailability(RATING_X, RATING_X, RATING_F, RATING_E)
- .setISAdvancement(3052, 3072, 3081, DATE_NONE, DATE_NONE)
- .setISApproximate(false, false, false, false, false)
- .setPrototypeFactions(F_FS)
- .setProductionFactions(F_FS, F_LC)
- .setStaticTechLevel(SimpleTechLevel.STANDARD);
- }
-
- @Override
- public double getBattleForceDamage(int range, Mounted fcs) {
- if (range == AlphaStrikeElement.SHORT_RANGE) {
- return 0.58;
- } else if (range <= AlphaStrikeElement.LONG_RANGE) {
- return 1;
- } else {
- return 0;
- }
}
-}
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderBolt15.java b/megamek/src/megamek/common/weapons/missiles/ISThunderBolt15.java
index 450ca8a711b..8af422f3125 100644
--- a/megamek/src/megamek/common/weapons/missiles/ISThunderBolt15.java
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderBolt15.java
@@ -19,15 +19,10 @@
*/
package megamek.common.weapons.missiles;
-import megamek.common.AmmoType;
-import megamek.common.alphaStrike.AlphaStrikeElement;
-import megamek.common.Mounted;
-import megamek.common.SimpleTechLevel;
-
/**
* @author Sebastian Brocks
*/
-public class ISThunderBolt15 extends ThunderBoltWeapon {
+public class ISThunderBolt15 extends Thunderbolt15Weapon {
private static final long serialVersionUID = -5466726857144417393L;
public ISThunderBolt15() {
@@ -38,45 +33,8 @@ public ISThunderBolt15() {
addLookupName("ISThunderbolt15");
addLookupName("IS Thunderbolt 15");
addLookupName("ISTBolt15");
- ammoType = AmmoType.T_TBOLT_15;
- heat = 7;
- minimumRange = 5;
- shortRange = 6;
- mediumRange = 12;
- longRange = 18;
- extremeRange = 24;
- shortAV = 15;
- medAV = 15;
- maxRange = RANGE_MED;
tonnage = 11.0;
- criticals = 3;
bv = 229;
cost = 325000;
- flags = flags.or(F_LARGEMISSILE);
- this.missileArmor = 15;
- rulesRefs = "347, TO";
- techAdvancement.setTechBase(TECH_BASE_IS)
- .setIntroLevel(false)
- .setUnofficial(false)
- .setTechRating(RATING_E)
- .setAvailability(RATING_X, RATING_X, RATING_F, RATING_E)
- .setISAdvancement(3052, 3072, 3081, DATE_NONE, DATE_NONE)
- .setISApproximate(false, false, false, false, false)
- .setPrototypeFactions(F_FS)
- .setProductionFactions(F_FS, F_LC)
- .setStaticTechLevel(SimpleTechLevel.STANDARD);
- }
-
- @Override
- public double getBattleForceDamage(int range, Mounted fcs) {
- if (range == AlphaStrikeElement.SHORT_RANGE) {
- return 0.87;
- } else if (range == AlphaStrikeElement.MEDIUM_RANGE) {
- return 1.5;
- } else if (range == AlphaStrikeElement.LONG_RANGE) {
- return 1.5;
- } else {
- return 0;
- }
}
-}
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderBolt20.java b/megamek/src/megamek/common/weapons/missiles/ISThunderBolt20.java
index 813822ff0df..19f5069db6c 100644
--- a/megamek/src/megamek/common/weapons/missiles/ISThunderBolt20.java
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderBolt20.java
@@ -19,15 +19,10 @@
*/
package megamek.common.weapons.missiles;
-import megamek.common.AmmoType;
-import megamek.common.SimpleTechLevel;
-import megamek.common.alphaStrike.AlphaStrikeElement;
-import megamek.common.Mounted;
-
/**
* @author Sebastian Brocks
*/
-public class ISThunderBolt20 extends ThunderBoltWeapon {
+public class ISThunderBolt20 extends Thunderbolt20Weapon {
private static final long serialVersionUID = -6976091682813292840L;
public ISThunderBolt20() {
@@ -38,45 +33,8 @@ public ISThunderBolt20() {
addLookupName("ISThunderbolt20");
addLookupName("ISTBolt20");
addLookupName("IS Thunderbolt 20");
- ammoType = AmmoType.T_TBOLT_20;
- heat = 8;
- minimumRange = 5;
- shortRange = 6;
- mediumRange = 12;
- longRange = 18;
- extremeRange = 24;
- shortAV = 20;
- medAV = 20;
- maxRange = RANGE_MED;
- tonnage = 15.0;
- criticals = 5;
+ tonnage = 15;
bv = 305;
cost = 450000;
- flags = flags.or(F_LARGEMISSILE);
- this.missileArmor = 20;
- rulesRefs = "347, TO";
- techAdvancement.setTechBase(TECH_BASE_IS)
- .setIntroLevel(false)
- .setUnofficial(false)
- .setTechRating(RATING_E)
- .setAvailability(RATING_X, RATING_X, RATING_F, RATING_E)
- .setISAdvancement(3052, 3072, 3081, DATE_NONE, DATE_NONE)
- .setISApproximate(false, false, false, false, false)
- .setPrototypeFactions(F_FS)
- .setProductionFactions(F_FS, F_LC)
- .setStaticTechLevel(SimpleTechLevel.STANDARD);
- }
-
- @Override
- public double getBattleForceDamage(int range, Mounted fcs) {
- if (range == AlphaStrikeElement.SHORT_RANGE) {
- return 1.16;
- } else if (range == AlphaStrikeElement.MEDIUM_RANGE) {
- return 2;
- } else if (range == AlphaStrikeElement.LONG_RANGE) {
- return 2;
- } else {
- return 0;
- }
}
-}
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderBolt5.java b/megamek/src/megamek/common/weapons/missiles/ISThunderBolt5.java
index 56a66026eb6..6062a662ffd 100644
--- a/megamek/src/megamek/common/weapons/missiles/ISThunderBolt5.java
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderBolt5.java
@@ -19,15 +19,10 @@
*/
package megamek.common.weapons.missiles;
-import megamek.common.AmmoType;
-import megamek.common.alphaStrike.AlphaStrikeElement;
-import megamek.common.Mounted;
-import megamek.common.SimpleTechLevel;
-
/**
* @author Sebastian Brocks
*/
-public class ISThunderBolt5 extends ThunderBoltWeapon {
+public class ISThunderBolt5 extends Thunderbolt5Weapon {
private static final long serialVersionUID = 5295837076559643763L;
public ISThunderBolt5() {
@@ -37,47 +32,8 @@ public ISThunderBolt5() {
addLookupName("IS Thunderbolt-5");
addLookupName("ISThunderbolt5");
addLookupName("IS Thunderbolt 5");
- sortingName = "Thunderbolt 05";
- ammoType = AmmoType.T_TBOLT_5;
- heat = 3;
- minimumRange = 5;
- shortRange = 6;
- mediumRange = 12;
- longRange = 18;
- extremeRange = 24;
- shortAV = 5;
- medAV = 5;
- maxRange = RANGE_MED;
tonnage = 3.0;
- criticals = 1;
bv = 64;
cost = 50000;
- flags = flags.or(F_LARGEMISSILE);
- this.missileArmor = 5;
- rulesRefs = "347, TO";
- // Tech Progression tweaked to combine IntOps with TRO Prototypes/3145 NTNU RS
- techAdvancement.setTechBase(TECH_BASE_IS)
- .setIntroLevel(false)
- .setUnofficial(false)
- .setTechRating(RATING_E)
- .setAvailability(RATING_X, RATING_X, RATING_F, RATING_E)
- .setISAdvancement(3052, 3072, 3081, DATE_NONE, DATE_NONE)
- .setISApproximate(false, false, false, false, false)
- .setPrototypeFactions(F_FS)
- .setProductionFactions(F_FS, F_LC)
- .setStaticTechLevel(SimpleTechLevel.STANDARD);
- }
-
- @Override
- public double getBattleForceDamage(int range, Mounted fcs) {
- if (range == AlphaStrikeElement.SHORT_RANGE) {
- return 0.29;
- } else if (range == AlphaStrikeElement.MEDIUM_RANGE) {
- return 0.5;
- } else if (range == AlphaStrikeElement.LONG_RANGE) {
- return 0.5;
- } else {
- return 0;
- }
}
-}
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderbolt10IOS.java b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt10IOS.java
new file mode 100644
index 00000000000..afe390060c9
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt10IOS.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+/**
+ * The Improved One-Shot Thunderbolt 10
+ * @author Simon (Juliez)
+ */
+public class ISThunderbolt10IOS extends Thunderbolt10Weapon {
+
+ public ISThunderbolt10IOS() {
+ super();
+ name = "Thunderbolt 10 (I-OS)";
+ setInternalName(name);
+ addLookupName("IS IOS Thunderbolt-10");
+ addLookupName("ISThunderbolt10 (IOS)");
+ addLookupName("IS Thunderbolt 10 (IOS)");
+ addLookupName("ISTBolt10IOS");
+ tonnage = 6.5;
+ bv = 25;
+ cost = 140000;
+ flags = flags.or(F_ONESHOT);
+ techAdvancement.setTechRating(RATING_B)
+ .setISAdvancement(3056, 3081, 3085, DATE_NONE, DATE_NONE)
+ .setPrototypeFactions(F_DC)
+ .setProductionFactions(F_DC)
+ .setISApproximate(false, true, false, false, false);
+ }
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderbolt10OS.java b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt10OS.java
new file mode 100644
index 00000000000..3ec44443ea3
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt10OS.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+/**
+ * The One-Shot Thunderbolt 10
+ * @author Simon (Juliez)
+ */
+public class ISThunderbolt10OS extends Thunderbolt10Weapon {
+
+ public ISThunderbolt10OS() {
+ super();
+ name = "Thunderbolt 10 (OS)";
+ setInternalName(name);
+ addLookupName("IS OS Thunderbolt-10");
+ addLookupName("ISThunderbolt10 (OS)");
+ addLookupName("IS Thunderbolt 10 (OS)");
+ addLookupName("ISTBolt10OS");
+ tonnage = 7.5;
+ bv = 25;
+ cost = 87500;
+ flags = flags.or(F_ONESHOT);
+ }
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderbolt15IOS.java b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt15IOS.java
new file mode 100644
index 00000000000..3659c128b5a
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt15IOS.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+/**
+ * The Improved One-Shot Thunderbolt 15
+ * @author Simon (Juliez)
+ */
+public class ISThunderbolt15IOS extends Thunderbolt15Weapon {
+
+ public ISThunderbolt15IOS() {
+ super();
+ name = "Thunderbolt 15 (I-OS)";
+ setInternalName(name);
+ addLookupName("IS IOS Thunderbolt-15");
+ addLookupName("ISThunderbolt15 (IOS)");
+ addLookupName("IS Thunderbolt 15 (IOS)");
+ addLookupName("ISTBolt15IOS");
+ tonnage = 10.5;
+ bv = 46;
+ cost = 260000;
+ flags = flags.or(F_ONESHOT);
+ techAdvancement.setTechRating(RATING_B)
+ .setISAdvancement(3056, 3081, 3085, DATE_NONE, DATE_NONE)
+ .setPrototypeFactions(F_DC)
+ .setProductionFactions(F_DC)
+ .setISApproximate(false, true, false, false, false);
+ }
+}
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderbolt15OS.java b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt15OS.java
new file mode 100644
index 00000000000..39e40731999
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt15OS.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+/**
+ * The One-Shot Thunderbolt 15
+ * @author Simon (Juliez)
+ */
+public class ISThunderbolt15OS extends Thunderbolt15Weapon {
+
+ public ISThunderbolt15OS() {
+ super();
+ name = "Thunderbolt 15 (OS)";
+ setInternalName(name);
+ addLookupName("IS OS Thunderbolt-15");
+ addLookupName("ISThunderbolt15 (OS)");
+ addLookupName("IS Thunderbolt 15 (OS)");
+ addLookupName("ISTBolt15OS");
+ tonnage = 11.5;
+ bv = 46;
+ cost = 162500;
+ flags = flags.or(F_ONESHOT);
+ }
+}
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderbolt20IOS.java b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt20IOS.java
new file mode 100644
index 00000000000..bf6a702e0c5
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt20IOS.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+/**
+ * The Improved One-Shot Thunderbolt 20
+ * @author Simon (Juliez)
+ */
+public class ISThunderbolt20IOS extends Thunderbolt20Weapon {
+
+ public ISThunderbolt20IOS() {
+ super();
+ name = "Thunderbolt 20 (I-OS)";
+ setInternalName(name);
+ addLookupName("IS IOS Thunderbolt-20");
+ addLookupName("ISThunderbolt20 (IOS)");
+ addLookupName("ISTBolt20IOS");
+ addLookupName("IS Thunderbolt 20 (IOS)");
+ tonnage = 14.5;
+ bv = 61;
+ cost = 360000;
+ flags = flags.or(F_ONESHOT);
+ techAdvancement.setTechRating(RATING_B)
+ .setISAdvancement(3056, 3081, 3085, DATE_NONE, DATE_NONE)
+ .setPrototypeFactions(F_DC)
+ .setProductionFactions(F_DC)
+ .setISApproximate(false, true, false, false, false);
+ }
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderbolt20OS.java b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt20OS.java
new file mode 100644
index 00000000000..87d113e202e
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt20OS.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+/**
+ * The One-Shot Thunderbolt 20
+ * @author Simon (Juliez)
+ */
+public class ISThunderbolt20OS extends Thunderbolt20Weapon {
+
+ public ISThunderbolt20OS() {
+ super();
+ name = "Thunderbolt 20 (OS)";
+ setInternalName(name);
+ addLookupName("IS OS Thunderbolt-20");
+ addLookupName("ISThunderbolt20 (OS)");
+ addLookupName("ISTBolt20OS");
+ addLookupName("IS Thunderbolt 20 (OS)");
+ tonnage = 15.5;
+ bv = 61;
+ cost = 225000;
+ flags = flags.or(F_ONESHOT);
+ }
+}
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderbolt5IOS.java b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt5IOS.java
new file mode 100644
index 00000000000..936ae03a8b3
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt5IOS.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+/**
+ * The Improved One-Shot Thunderbolt 5
+ * @author Simon (Juliez)
+ */
+public class ISThunderbolt5IOS extends Thunderbolt5Weapon {
+
+ public ISThunderbolt5IOS() {
+ super();
+ name = "Thunderbolt 5 (I-OS)";
+ setInternalName(name);
+ addLookupName("IS IOS Thunderbolt-5");
+ addLookupName("ISThunderbolt5 (IOS)");
+ addLookupName("IS Thunderbolt 5 (IOS)");
+ tonnage = 2.5;
+ bv = 13;
+ cost = 40000;
+ flags = flags.or(F_ONESHOT);
+ techAdvancement.setTechRating(RATING_B)
+ .setISAdvancement(3056, 3081, 3085, DATE_NONE, DATE_NONE)
+ .setPrototypeFactions(F_DC)
+ .setProductionFactions(F_DC)
+ .setISApproximate(false, true, false, false, false);
+ }
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/missiles/ISThunderbolt5OS.java b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt5OS.java
new file mode 100644
index 00000000000..f16f09e454b
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/ISThunderbolt5OS.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+/**
+ * The One-Shot Thunderbolt 5
+ * @author Simon (Juliez)
+ */
+public class ISThunderbolt5OS extends Thunderbolt5Weapon {
+
+ public ISThunderbolt5OS() {
+ super();
+ name = "Thunderbolt 5 (OS)";
+ setInternalName(name);
+ addLookupName("IS OS Thunderbolt-5");
+ addLookupName("ISThunderbolt5 (OS)");
+ addLookupName("IS Thunderbolt 5 (OS)");
+ tonnage = 3.5;
+ bv = 13;
+ cost = 25000;
+ flags = flags.or(F_ONESHOT);
+ }
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/missiles/ThunderBoltWeapon.java b/megamek/src/megamek/common/weapons/missiles/ThunderBoltWeapon.java
index a739092c2d2..a2b128390fd 100644
--- a/megamek/src/megamek/common/weapons/missiles/ThunderBoltWeapon.java
+++ b/megamek/src/megamek/common/weapons/missiles/ThunderBoltWeapon.java
@@ -1,20 +1,26 @@
-/**
- * MegaMek - Copyright (C) 2005 Ben Mazur (bmazur@sev.org)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+/*
+ * Copyright (c) 2005 - Ben Mazur (bmazur@sev.org)
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
*/
package megamek.common.weapons.missiles;
-import megamek.common.alphaStrike.AlphaStrikeElement;
import megamek.common.Game;
+import megamek.common.SimpleTechLevel;
import megamek.common.ToHitData;
import megamek.common.actions.WeaponAttackAction;
import megamek.common.options.GameOptions;
@@ -27,46 +33,38 @@
* @author Sebastian Brocks
*/
public abstract class ThunderBoltWeapon extends MissileWeapon {
-
- /**
- *
- */
private static final long serialVersionUID = 3496376576886743383L;
- /**
- *
- */
public ThunderBoltWeapon() {
super();
- this.rackSize = 1;
+ rackSize = 1;
+ minimumRange = 5;
+ shortRange = 6;
+ mediumRange = 12;
+ longRange = 18;
+ extremeRange = 24;
+ maxRange = RANGE_MED;
+ flags = flags.or(F_LARGEMISSILE);
atClass = CLASS_THUNDERBOLT;
+ rulesRefs = "159, TO:AUE";
+ techAdvancement.setTechBase(TECH_BASE_IS)
+ .setIntroLevel(false)
+ .setUnofficial(false)
+ .setTechRating(RATING_E)
+ .setAvailability(RATING_X, RATING_X, RATING_F, RATING_E)
+ .setISAdvancement(3052, 3072, 3081, DATE_NONE, DATE_NONE)
+ .setISApproximate(false, false, false, false, false)
+ .setPrototypeFactions(F_FS)
+ .setProductionFactions(F_FS, F_LC)
+ .setStaticTechLevel(SimpleTechLevel.STANDARD);
}
- /*
- * (non-Javadoc)
- *
- * @see
- * megamek.common.weapons.Weapon#getCorrectHandler(megamek.common.ToHitData,
- * megamek.common.actions.WeaponAttackAction, megamek.common.Game)
- */
@Override
protected AttackHandler getCorrectHandler(ToHitData toHit,
WeaponAttackAction waa, Game game, GameManager manager) {
return new ThunderBoltWeaponHandler(toHit, waa, game, manager);
}
- @Override
- public double getBattleForceDamage(int range) {
- double damage = 0;
- if (range <= getLongRange()) {
- damage = getRackSize();
- if ((range == AlphaStrikeElement.SHORT_RANGE) && (getMinimumRange() > 0)) {
- damage = adjustBattleForceDamageForMinRange(damage);
- }
- }
- return damage / 10.0;
- }
-
@Override
public boolean hasIndirectFire() {
return true;
@@ -85,4 +83,4 @@ public void adaptToGameOptions(GameOptions gOp) {
removeMode("Indirect");
}
}
-}
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/missiles/Thunderbolt10Weapon.java b/megamek/src/megamek/common/weapons/missiles/Thunderbolt10Weapon.java
new file mode 100644
index 00000000000..9a31cc122c6
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/Thunderbolt10Weapon.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+import megamek.common.AmmoType;
+import megamek.common.Mounted;
+import megamek.common.SimpleTechLevel;
+import megamek.common.alphaStrike.AlphaStrikeElement;
+
+public abstract class Thunderbolt10Weapon extends ThunderBoltWeapon {
+
+ public Thunderbolt10Weapon() {
+ super();
+ ammoType = AmmoType.T_TBOLT_10;
+ heat = 5;
+ shortAV = 10;
+ medAV = 10;
+ criticals = 2;
+ missileArmor = 10;
+ }
+
+ @Override
+ public double getBattleForceDamage(int range, Mounted fcs) {
+ if (range == AlphaStrikeElement.SHORT_RANGE) {
+ return 0.58;
+ } else if (range <= AlphaStrikeElement.LONG_RANGE) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public String getSortingName() {
+ String oneShotTag = hasFlag(F_ONESHOT) ? "OS" : "";
+ if (name.contains("I-OS")) {
+ oneShotTag = "XIOS";
+ }
+ return "Thunderbolt-" + oneShotTag + "10";
+ }
+}
diff --git a/megamek/src/megamek/common/weapons/missiles/Thunderbolt15Weapon.java b/megamek/src/megamek/common/weapons/missiles/Thunderbolt15Weapon.java
new file mode 100644
index 00000000000..febe189d173
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/Thunderbolt15Weapon.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+import megamek.common.AmmoType;
+import megamek.common.Mounted;
+import megamek.common.SimpleTechLevel;
+import megamek.common.alphaStrike.AlphaStrikeElement;
+
+public abstract class Thunderbolt15Weapon extends ThunderBoltWeapon {
+
+ public Thunderbolt15Weapon() {
+ super();
+ ammoType = AmmoType.T_TBOLT_15;
+ heat = 7;
+ shortAV = 15;
+ medAV = 15;
+ criticals = 3;
+ missileArmor = 15;
+ }
+
+ @Override
+ public double getBattleForceDamage(int range, Mounted fcs) {
+ if (range == AlphaStrikeElement.SHORT_RANGE) {
+ return 0.87;
+ } else if (range == AlphaStrikeElement.MEDIUM_RANGE) {
+ return 1.5;
+ } else if (range == AlphaStrikeElement.LONG_RANGE) {
+ return 1.5;
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public String getSortingName() {
+ String oneShotTag = hasFlag(F_ONESHOT) ? "OS" : "";
+ if (name.contains("I-OS")) {
+ oneShotTag = "XIOS";
+ }
+ return "Thunderbolt-" + oneShotTag + "15";
+ }
+}
diff --git a/megamek/src/megamek/common/weapons/missiles/Thunderbolt20Weapon.java b/megamek/src/megamek/common/weapons/missiles/Thunderbolt20Weapon.java
new file mode 100644
index 00000000000..fda21331783
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/Thunderbolt20Weapon.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+import megamek.common.AmmoType;
+import megamek.common.Mounted;
+import megamek.common.SimpleTechLevel;
+import megamek.common.alphaStrike.AlphaStrikeElement;
+
+public abstract class Thunderbolt20Weapon extends ThunderBoltWeapon {
+
+ public Thunderbolt20Weapon() {
+ super();
+ ammoType = AmmoType.T_TBOLT_20;
+ heat = 8;
+ shortAV = 20;
+ medAV = 20;
+ criticals = 5;
+ missileArmor = 20;
+ }
+
+ @Override
+ public double getBattleForceDamage(int range, Mounted fcs) {
+ if (range == AlphaStrikeElement.SHORT_RANGE) {
+ return 1.16;
+ } else if (range == AlphaStrikeElement.MEDIUM_RANGE) {
+ return 2;
+ } else if (range == AlphaStrikeElement.LONG_RANGE) {
+ return 2;
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public String getSortingName() {
+ String oneShotTag = hasFlag(F_ONESHOT) ? "OS" : "";
+ if (name.contains("I-OS")) {
+ oneShotTag = "XIOS";
+ }
+ return "Thunderbolt-" + oneShotTag + "20";
+ }
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/missiles/Thunderbolt5Weapon.java b/megamek/src/megamek/common/weapons/missiles/Thunderbolt5Weapon.java
new file mode 100644
index 00000000000..615124e8c13
--- /dev/null
+++ b/megamek/src/megamek/common/weapons/missiles/Thunderbolt5Weapon.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MegaMek. If not, see .
+ */
+package megamek.common.weapons.missiles;
+
+import megamek.common.AmmoType;
+import megamek.common.Mounted;
+import megamek.common.SimpleTechLevel;
+import megamek.common.alphaStrike.AlphaStrikeElement;
+
+public abstract class Thunderbolt5Weapon extends ThunderBoltWeapon {
+
+ public Thunderbolt5Weapon() {
+ super();
+ ammoType = AmmoType.T_TBOLT_5;
+ heat = 3;
+ shortAV = 5;
+ medAV = 5;
+ criticals = 1;
+ missileArmor = 5;
+ }
+
+ @Override
+ public double getBattleForceDamage(int range, Mounted fcs) {
+ if (range == AlphaStrikeElement.SHORT_RANGE) {
+ return 0.29;
+ } else if (range == AlphaStrikeElement.MEDIUM_RANGE) {
+ return 0.5;
+ } else if (range == AlphaStrikeElement.LONG_RANGE) {
+ return 0.5;
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public String getSortingName() {
+ String oneShotTag = hasFlag(F_ONESHOT) ? "OS" : "";
+ if (name.contains("I-OS")) {
+ oneShotTag = "XIOS";
+ }
+ return "Thunderbolt-" + oneShotTag + "05";
+ }
+}
\ No newline at end of file
diff --git a/megamek/src/megamek/common/weapons/prototypes/ISERLaserLargePrototype.java b/megamek/src/megamek/common/weapons/prototypes/ISERLaserLargePrototype.java
index b53093f3d6b..2281969787b 100644
--- a/megamek/src/megamek/common/weapons/prototypes/ISERLaserLargePrototype.java
+++ b/megamek/src/megamek/common/weapons/prototypes/ISERLaserLargePrototype.java
@@ -23,6 +23,7 @@
import megamek.common.weapons.PrototypeLaserHandler;
import megamek.common.weapons.lasers.LaserWeapon;
import megamek.server.GameManager;
+import megamek.server.Server;
/**
* @author Andrew Hunter
@@ -86,16 +87,17 @@ protected AttackHandler getCorrectHandler(ToHitData toHit, WeaponAttackAction wa
@Override
public int getLongRange() {
- GameOptions options = getGameOptions();
- if (options == null) {
- return super.getLongRange();
- } else if (options.getOption(OptionsConstants.ADVCOMBAT_INCREASED_ISERLL_RANGE) == null) {
+ if (Server.getServerInstance() == null) {
return super.getLongRange();
}
- if (options.getOption(OptionsConstants.ADVCOMBAT_INCREASED_ISERLL_RANGE).booleanValue()) {
+ final GameOptions options = Server.getServerInstance().getGame().getOptions();
+ if (options.getOption(OptionsConstants.ADVCOMBAT_INCREASED_ISERLL_RANGE) == null) {
+ return super.getLongRange();
+ } else if (options.getOption(OptionsConstants.ADVCOMBAT_INCREASED_ISERLL_RANGE).booleanValue()) {
return 21;
+ } else {
+ return super.getLongRange();
}
- return super.getLongRange();
}
@Override
diff --git a/megamek/src/megamek/server/GameManager.java b/megamek/src/megamek/server/GameManager.java
index 9c16307d636..fb991e2999c 100644
--- a/megamek/src/megamek/server/GameManager.java
+++ b/megamek/src/megamek/server/GameManager.java
@@ -39,6 +39,7 @@
import megamek.common.preference.PreferenceManager;
import megamek.common.util.BoardUtilities;
import megamek.common.util.EmailService;
+import megamek.common.util.SerializationHelper;
import megamek.common.util.StringUtil;
import megamek.common.util.fileUtils.MegaMekFile;
import megamek.common.verifier.*;
@@ -443,12 +444,6 @@ public void saveGame(String sFile, boolean sendChat) {
if (sFile.endsWith(".gz")) {
sFile = sFile.replace(".gz", "");
}
- XStream xstream = new XStream();
-
- // This will make save games much smaller
- // by using a more efficient means of referencing
- // objects in the XML graph
- xstream.setMode(XStream.ID_REFERENCES);
String sFinalFile = sFile;
if (!sFinalFile.endsWith(MMConstants.SAVE_FILE_EXT)) {
@@ -464,8 +459,7 @@ public void saveGame(String sFile, boolean sendChat) {
try (OutputStream os = new FileOutputStream(sFinalFile + ".gz");
OutputStream gzo = new GZIPOutputStream(os);
Writer writer = new OutputStreamWriter(gzo, StandardCharsets.UTF_8)) {
-
- xstream.toXML(getGame(), writer);
+ SerializationHelper.getSaveGameXStream().toXML(getGame(), writer);
} catch (Exception e) {
LogManager.getLogger().error("Unable to save file: " + sFinalFile, e);
}
@@ -673,14 +667,12 @@ public void sendCurrentInfo(int connId) {
// LOUNGE triggers a Game.reset() on the client, which wipes out
// the PlanetaryCondition, so resend
- if (game.getPhase() == GamePhase.LOUNGE) {
+ if (game.getPhase().isLounge()) {
send(connId, createPlanetaryConditionsPacket());
}
- if ((game.getPhase() == GamePhase.FIRING)
- || (game.getPhase() == GamePhase.TARGETING)
- || (game.getPhase() == GamePhase.OFFBOARD)
- || (game.getPhase() == GamePhase.PHYSICAL)) {
+ if (game.getPhase().isFiring() || game.getPhase().isTargeting()
+ || game.getPhase().isOffboard() || game.getPhase().isPhysical()) {
// can't go above, need board to have been sent
send(connId, createAttackPacket(getGame().getActionsVector(), 0));
send(connId, createAttackPacket(getGame().getChargesVector(), 1));
@@ -688,11 +680,10 @@ public void sendCurrentInfo(int connId) {
send(connId, createAttackPacket(getGame().getTeleMissileAttacksVector(), 1));
}
- if (game.getPhase().hasTurns() && game.hasMoreTurns()) {
+ if (getGame().getPhase().hasTurns() && getGame().hasMoreTurns()) {
send(connId, createTurnVectorPacket());
send(connId, createTurnIndexPacket(connId));
- } else if ((game.getPhase() != GamePhase.LOUNGE)
- && (game.getPhase() != GamePhase.STARTING_SCENARIO)) {
+ } else if (!getGame().getPhase().isLounge() && !getGame().getPhase().isStartingScenario()) {
endCurrentPhase();
}
@@ -1086,7 +1077,7 @@ private void resetEntityPhase(GamePhase phase) {
// reset done to false
- if (phase == GamePhase.DEPLOYMENT) {
+ if (phase.isDeployment()) {
entity.setDone(!entity.shouldDeploy(game.getRoundCount()));
} else {
entity.setDone(false);
@@ -1386,8 +1377,8 @@ private void checkReady() {
}
// need at least one entity in the game for the lounge phase to end
- if (!game.getPhase().hasTurns() && ((game.getPhase() != GamePhase.LOUNGE)
- || (game.getNoOfEntities() > 0))) {
+ if (!getGame().getPhase().hasTurns()
+ && (!getGame().getPhase().isLounge() || (getGame().getNoOfEntities() > 0))) {
endCurrentPhase();
}
}
@@ -1431,22 +1422,15 @@ private void endCurrentTurn(Entity entityUsed) {
final int playerId = null == entityUsed ? Player.PLAYER_NONE : entityUsed.getOwnerId();
boolean infMoved = entityUsed instanceof Infantry;
boolean infMoveMulti = gameOpts.booleanOption(OptionsConstants.INIT_INF_MOVE_MULTI)
- && ((currPhase == GamePhase.MOVEMENT)
- || (currPhase == GamePhase.DEPLOYMENT)
- || (currPhase == GamePhase.INITIATIVE));
+ && (currPhase.isMovement() || currPhase.isDeployment() || currPhase.isInitiative());
boolean protosMoved = entityUsed instanceof Protomech;
boolean protosMoveMulti = gameOpts.booleanOption(OptionsConstants.INIT_PROTOS_MOVE_MULTI);
boolean tanksMoved = entityUsed instanceof Tank;
- boolean tanksMoveMulti = gameOpts.booleanOption(
- OptionsConstants.ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT)
- && ((currPhase == GamePhase.MOVEMENT)
- || (currPhase == GamePhase.DEPLOYMENT)
- || (currPhase == GamePhase.INITIATIVE));
+ boolean tanksMoveMulti = gameOpts.booleanOption(OptionsConstants.ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT)
+ && (currPhase.isMovement() || currPhase.isDeployment() || currPhase.isInitiative());
boolean meksMoved = entityUsed instanceof Mech;
boolean meksMoveMulti = gameOpts.booleanOption(OptionsConstants.ADVGRNDMOV_MEK_LANCE_MOVEMENT)
- && ((currPhase == GamePhase.MOVEMENT)
- || (currPhase == GamePhase.DEPLOYMENT)
- || (currPhase == GamePhase.INITIATIVE));
+ && (currPhase.isMovement() || currPhase.isDeployment() || currPhase.isInitiative());
// If infantry or protos move multi see if any
// other unit types can move in the current turn.
@@ -2057,8 +2041,7 @@ public void checkEntityExchange() {
a.setSI(currentSI);
}
}
- // Give the unit a spotlight, if it has the spotlight quirk
- if (entity instanceof Mech || entity instanceof Tank) {
+ if (entity.getsAutoExternalSearchlight()) {
entity.setExternalSearchlight(true);
}
entityUpdate(entity.getId());
@@ -2499,8 +2482,8 @@ private void receiveForwardIni(int connectionId) {
* allow the other players to skip that player.
*/
private void changeToNextTurn(int prevPlayerId) {
- boolean minefieldPhase = game.getPhase() == GamePhase.DEPLOY_MINEFIELDS;
- boolean artyPhase = game.getPhase() == GamePhase.SET_ARTILLERY_AUTOHIT_HEXES;
+ boolean minefieldPhase = game.getPhase().isDeployMinefields();
+ boolean artyPhase = game.getPhase().isSetArtilleryAutohitHexes();
GameTurn nextTurn = null;
Entity nextEntity = null;
@@ -2721,7 +2704,7 @@ private Vector initGameTurnsWithStranded(TurnVectors team_order) {
// Stranded units only during movement phases, rebuild the turns vector
// TODO maybe move this to Premovemnt?
- if (game.getPhase() == GamePhase.MOVEMENT) {
+ if (game.getPhase().isMovement()) {
// See if there are any loaded units stranded on immobile transports.
Iterator strandedUnits = game.getSelectedEntities(
entity -> game.isEntityStranded(entity));
@@ -2816,40 +2799,31 @@ private void determineTurnOrder(GamePhase phase) {
}
// and/or deploy even according to game options.
boolean infMoveEven = (game.getOptions().booleanOption(OptionsConstants.INIT_INF_MOVE_EVEN)
- && ((game.getPhase() == GamePhase.INITIATIVE)
- || (game.getPhase() == GamePhase.MOVEMENT)))
+ && (game.getPhase().isInitiative() || game.getPhase().isMovement()))
|| (game.getOptions().booleanOption(OptionsConstants.INIT_INF_DEPLOY_EVEN)
- && (game.getPhase() == GamePhase.DEPLOYMENT));
- boolean infMoveMulti = game.getOptions()
- .booleanOption(OptionsConstants.INIT_INF_MOVE_MULTI)
- && ((game.getPhase() == GamePhase.INITIATIVE)
- || ((game.getPhase() == GamePhase.MOVEMENT)
- || (game.getPhase() == GamePhase.DEPLOYMENT)));
- boolean protosMoveEven = (game.getOptions().booleanOption(
- OptionsConstants.INIT_PROTOS_MOVE_EVEN)
- && ((game.getPhase() == GamePhase.INITIATIVE)
- || ((game.getPhase() == GamePhase.MOVEMENT)
- || (game.getPhase() == GamePhase.DEPLOYMENT))))
+ && game.getPhase().isDeployment());
+ boolean infMoveMulti = game.getOptions().booleanOption(OptionsConstants.INIT_INF_MOVE_MULTI)
+ && (game.getPhase().isInitiative() || game.getPhase().isMovement()
+ || game.getPhase().isDeployment());
+ boolean protosMoveEven = (game.getOptions().booleanOption(OptionsConstants.INIT_PROTOS_MOVE_EVEN)
+ && (game.getPhase().isInitiative() || game.getPhase().isMovement()
+ || game.getPhase().isDeployment()))
|| (game.getOptions().booleanOption(OptionsConstants.INIT_PROTOS_MOVE_EVEN)
- && (game.getPhase() == GamePhase.DEPLOYMENT));
- boolean protosMoveMulti = game.getOptions().booleanOption(
- OptionsConstants.INIT_PROTOS_MOVE_MULTI);
+ && game.getPhase().isDeployment());
+ boolean protosMoveMulti = game.getOptions().booleanOption(OptionsConstants.INIT_PROTOS_MOVE_MULTI);
boolean protosMoveByPoint = !protosMoveMulti;
- boolean tankMoveByLance = game.getOptions().booleanOption(
- OptionsConstants.ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT)
- && ((game.getPhase() == GamePhase.INITIATIVE)
- || ((game.getPhase() == GamePhase.MOVEMENT)
- || (game.getPhase() == GamePhase.DEPLOYMENT)));
- boolean mekMoveByLance = game.getOptions().booleanOption(
- OptionsConstants.ADVGRNDMOV_MEK_LANCE_MOVEMENT)
- && ((game.getPhase() == GamePhase.INITIATIVE)
- || ((game.getPhase() == GamePhase.MOVEMENT)
- || (game.getPhase() == GamePhase.DEPLOYMENT)));
+ boolean tankMoveByLance = game.getOptions().booleanOption(OptionsConstants.ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT)
+ && (game.getPhase().isInitiative() || game.getPhase().isMovement()
+ || game.getPhase().isDeployment());
+ boolean mekMoveByLance = game.getOptions().booleanOption(OptionsConstants.ADVGRNDMOV_MEK_LANCE_MOVEMENT)
+ && (game.getPhase().isInitiative() || game.getPhase().isMovement()
+ || game.getPhase().isDeployment());
int evenMask = 0;
if (infMoveEven) {
evenMask += GameTurn.CLASS_INFANTRY;
}
+
if (protosMoveEven) {
evenMask += GameTurn.CLASS_PROTOMECH;
}
@@ -2911,28 +2885,22 @@ public boolean accept(Entity entity) {
if (entity.isSelectableThisTurn()) {
final Player player = entity.getOwner();
if ((entity instanceof SpaceStation)
- && ((game.getPhase() == GamePhase.MOVEMENT)
- || (game.getPhase() == GamePhase.DEPLOYMENT))) {
+ && (game.getPhase().isMovement() || game.getPhase().isDeployment())) {
player.incrementSpaceStationTurns();
} else if ((entity instanceof Warship)
- && ((game.getPhase() == GamePhase.MOVEMENT)
- || (game.getPhase() == GamePhase.DEPLOYMENT))) {
+ && (game.getPhase().isMovement() || game.getPhase().isDeployment())) {
player.incrementWarshipTurns();
} else if ((entity instanceof Jumpship)
- && ((game.getPhase() == GamePhase.MOVEMENT)
- || (game.getPhase() == GamePhase.DEPLOYMENT))) {
+ && (game.getPhase().isMovement() || game.getPhase().isDeployment())) {
player.incrementJumpshipTurns();
} else if ((entity instanceof Dropship) && entity.isAirborne()
- && ((game.getPhase() == GamePhase.MOVEMENT)
- || (game.getPhase() == GamePhase.DEPLOYMENT))) {
+ && (game.getPhase().isMovement() || game.getPhase().isDeployment())) {
player.incrementDropshipTurns();
} else if ((entity instanceof SmallCraft) && entity.isAirborne()
- && ((game.getPhase() == GamePhase.MOVEMENT)
- || (game.getPhase() == GamePhase.DEPLOYMENT))) {
+ && (game.getPhase().isMovement() || game.getPhase().isDeployment())) {
player.incrementSmallCraftTurns();
} else if (entity.isAirborne()
- && ((game.getPhase() == GamePhase.MOVEMENT)
- || (game.getPhase() == GamePhase.DEPLOYMENT))) {
+ && (game.getPhase().isMovement() || game.getPhase().isDeployment())) {
player.incrementAeroTurns();
} else if ((entity instanceof Infantry)) {
if (infMoveEven) {
@@ -3124,7 +3092,7 @@ private void writeInitiativeReport(boolean abbreviatedReport) {
if (!abbreviatedReport) {
r = new Report(1210);
r.type = Report.PUBLIC;
- if ((game.getLastPhase() == GamePhase.DEPLOYMENT) || game.isDeploymentComplete()
+ if (game.getLastPhase().isDeployment() || game.isDeploymentComplete()
|| !game.shouldDeployThisRound()) {
r.messageId = 1000;
r.add(game.getRoundCount());
@@ -3219,7 +3187,7 @@ private void writeInitiativeReport(boolean abbreviatedReport) {
r = new Report(1021, Report.PUBLIC);
if ((game.getOptions().booleanOption(OptionsConstants.INIT_INF_DEPLOY_EVEN)
|| game.getOptions().booleanOption(OptionsConstants.INIT_PROTOS_MOVE_EVEN))
- && !(game.getLastPhase() == GamePhase.END_REPORT)) {
+ && !game.getLastPhase().isEndReport()) {
r.choose(true);
} else {
r.choose(false);
@@ -3405,8 +3373,7 @@ private void loadUnit(Entity loader, Entity unit, int bayNumber) {
&& en.getUnitNumber() == unit.getUnitNumber());
}
- if ((game.getPhase() != GamePhase.LOUNGE) && !unit.isDone()
- && (remainingProtos == 0)) {
+ if (!getGame().getPhase().isLounge() && !unit.isDone() && (remainingProtos == 0)) {
// Remove the *last* friendly turn (removing the *first* penalizes
// the opponent too much, and re-calculating moves is too hard).
game.removeTurnFor(unit);
@@ -3425,11 +3392,7 @@ private void loadUnit(Entity loader, Entity unit, int bayNumber) {
// Load the unit. Do not check for elevation during deployment
boolean checkElevation = !getGame().getPhase().isLounge()
&& !getGame().getPhase().isDeployment();
- if (bayNumber == -1) {
- loader.load(unit, checkElevation);
- } else {
- loader.load(unit, checkElevation, bayNumber);
- }
+ loader.load(unit, checkElevation, bayNumber);
// The loaded unit is being carried by the loader.
unit.setTransportId(loader.getId());
@@ -3440,9 +3403,9 @@ private void loadUnit(Entity loader, Entity unit, int bayNumber) {
// set deployment round of the loadee to equal that of the loader
unit.setDeployRound(loader.getDeployRound());
- //Update the loading unit's passenger count, if it's a large craft
- if (loader instanceof SmallCraft || loader instanceof Jumpship) {
- //Don't add DropShip crew to a JumpShip or station's passenger list
+ // Update the loading unit's passenger count, if it's a large craft
+ if ((loader instanceof SmallCraft) || (loader instanceof Jumpship)) {
+ // Don't add DropShip crew to a JumpShip or station's passenger list
if (!unit.isLargeCraft()) {
loader.setNPassenger(loader.getNPassenger() + unit.getCrew().getSize());
}
@@ -3461,7 +3424,7 @@ private void loadUnit(Entity loader, Entity unit, int bayNumber) {
* @param unit - the Entity being towed.
*/
private void towUnit(Entity loader, Entity unit) {
- if ((game.getPhase() != GamePhase.LOUNGE) && !unit.isDone()) {
+ if (!getGame().getPhase().isLounge() && !unit.isDone()) {
// Remove the *last* friendly turn (removing the *first* penalizes
// the opponent too much, and re-calculating moves is too hard).
game.removeTurnFor(unit);
@@ -4143,7 +4106,7 @@ private void receiveMovement(Packet packet, int connId) {
md.setEntity(entity);
// is this the right phase?
- if (game.getPhase() != GamePhase.MOVEMENT) {
+ if (!getGame().getPhase().isMovement()) {
LogManager.getLogger().error("Server got movement packet in wrong phase");
return;
}
@@ -4153,6 +4116,7 @@ private void receiveMovement(Packet packet, int connId) {
if (getGame().getPhase().isSimultaneous(getGame())) {
turn = game.getTurnForPlayer(connId);
}
+
if ((turn == null) || !turn.isValid(connId, entity, game)) {
String msg = "error: server got invalid movement packet from " + "connection " + connId;
if (entity != null) {
@@ -4918,6 +4882,7 @@ else if ((target instanceof Infantry) && (bldg != null)) {
// note that this must sequentially occur before the next 'entering liquid magma' check
// otherwise, magma crust won't have a chance to break
ServerHelper.checkAndApplyMagmaCrust(nextHex, nextElevation, entity, curPos, false, vPhaseReport, this);
+ ServerHelper.checkEnteringMagma(nextHex, nextElevation, entity, this);
// is the next hex a swamp?
PilotingRollData rollTarget = entity.checkBogDown(step, moveType, nextHex, curPos, nextPos,
@@ -5920,6 +5885,7 @@ private void processMovement(Entity entity, MovePath md, Map doEntityDisplacement(Entity entity, Coords src,
// Make sure there aren't any specific entity turns for entity
int turnsRemoved = game.removeSpecificEntityTurnsFor(entity);
// May need to remove a turn for this Entity
- if ((game.getPhase() == GamePhase.MOVEMENT)
- && !entity.isDone() && (turnsRemoved == 0)) {
+ if (game.getPhase().isMovement() && !entity.isDone() && (turnsRemoved == 0)) {
game.removeTurnFor(entity);
send(createTurnVectorPacket());
} else if (turnsRemoved > 0) {
@@ -12043,6 +12026,7 @@ private Vector doEntityDisplacement(Entity entity, Coords src,
}
ServerHelper.checkAndApplyMagmaCrust(destHex, entity.getElevation(), entity, dest, false, vPhaseReport, this);
+ ServerHelper.checkEnteringMagma(destHex, entity.getElevation(), entity, this);
Entity violation = Compute.stackingViolation(game, entity.getId(), dest);
if (violation == null) {
@@ -12624,7 +12608,7 @@ private void receiveDeployMinefields(Packet packet, int connId) {
Vector minefields = (Vector) packet.getObject(0);
// is this the right phase?
- if (game.getPhase() != GamePhase.DEPLOY_MINEFIELDS) {
+ if (!getGame().getPhase().isDeployMinefields()) {
LogManager.getLogger().error("Server got deploy minefields packet in wrong phase");
return;
}
@@ -12698,9 +12682,8 @@ private void receivePrephase(Packet packet, int connId) {
Entity entity = game.getEntity(packet.getIntValue(0));
// is this the right phase?
- if ((game.getPhase() != GamePhase.PREFIRING)
- && (game.getPhase() != GamePhase.PREMOVEMENT)) {
- LogManager.getLogger().error("Server got Prephase packet in wrong phase "+game.getPhase());
+ if (!getGame().getPhase().isPrefiring() && !getGame().getPhase().isPremovement()) {
+ LogManager.getLogger().error("Server got Prephase packet in wrong phase " + game.getPhase());
return;
}
@@ -12738,10 +12721,8 @@ private void receiveAttack(Packet packet, int connId) {
Vector vector = (Vector) packet.getObject(1);
// is this the right phase?
- if ((game.getPhase() != GamePhase.FIRING)
- && (game.getPhase() != GamePhase.PHYSICAL)
- && (game.getPhase() != GamePhase.TARGETING)
- && (game.getPhase() != GamePhase.OFFBOARD)) {
+ if (!getGame().getPhase().isFiring() && !getGame().getPhase().isPhysical()
+ && !getGame().getPhase().isTargeting() && !getGame().getPhase().isOffboard()) {
LogManager.getLogger().error("Server got attack packet in wrong phase");
return;
}
@@ -13063,7 +13044,7 @@ public void assignAMS() {
// For Bearings-only Capital Missiles, don't assign during the offboard phase
if (wh instanceof CapitalMissileBearingsOnlyHandler) {
ArtilleryAttackAction aaa = (ArtilleryAttackAction) waa;
- if (aaa.getTurnsTilHit() > 0 || game.getPhase() != GamePhase.FIRING) {
+ if ((aaa.getTurnsTilHit() > 0) || !getGame().getPhase().isFiring()) {
continue;
}
}
@@ -18292,33 +18273,6 @@ private void resolveHeat() {
} else {
LogManager.getLogger().error("Radical heat sinks mounted on non-mech, non-aero Entity!");
}
- int rhsRoll = Compute.d6(2);
- int targetNumber;
- switch (entity.getConsecutiveRHSUses()) {
- case 0:
- targetNumber = 2;
- break;
- case 1:
- targetNumber = 3;
- break;
- case 2:
- targetNumber = 5;
- break;
- case 3:
- targetNumber = 7;
- break;
- case 4:
- targetNumber = 10;
- break;
- case 5:
- targetNumber = 11;
- break;
- case 6:
- default:
- targetNumber = TargetRoll.AUTOMATIC_FAIL;
- break;
- }
- entity.setConsecutiveRHSUses(entity.getConsecutiveRHSUses() + 1);
// RHS activation report
r = new Report(5540);
@@ -18328,7 +18282,11 @@ private void resolveHeat() {
r.add(radicalHSBonus);
rhsReports.add(r);
+ int rhsRoll = Compute.d6(2);
+ entity.setConsecutiveRHSUses(entity.getConsecutiveRHSUses() + 1);
+ int targetNumber = ServerHelper.radicalHeatSinkSuccessTarget(entity.getConsecutiveRHSUses());
boolean rhsFailure = rhsRoll < targetNumber;
+
r = new Report(5541);
r.indent(2);
r.subject = entity.getId();
@@ -18467,32 +18425,7 @@ private void resolveHeat() {
// If a Mek is in extreme Temperatures, add or subtract one
// heat per 10 degrees (or fraction of 10 degrees) above or
// below 50 or -30 degrees Celsius
- if (game.getPlanetaryConditions().getTemperatureDifference(50, -30) != 0
- && !((Mech) entity).hasLaserHeatSinks()) {
- if (game.getPlanetaryConditions().getTemperature() > 50) {
- int heatToAdd = game.getPlanetaryConditions()
- .getTemperatureDifference(50, -30);
- if (((Mech) entity).hasIntactHeatDissipatingArmor()) {
- heatToAdd /= 2;
- }
- entity.heatFromExternal += heatToAdd;
- r = new Report(5020);
- r.subject = entity.getId();
- r.add(heatToAdd);
- addReport(r);
- if (((Mech) entity).hasIntactHeatDissipatingArmor()) {
- r = new Report(5550);
- addReport(r);
- }
- } else {
- entity.heatFromExternal -= game.getPlanetaryConditions()
- .getTemperatureDifference(50, -30);
- r = new Report(5025);
- r.subject = entity.getId();
- r.add(game.getPlanetaryConditions().getTemperatureDifference(50, -30));
- addReport(r);
- }
- }
+ ServerHelper.adjustHeatExtremeTemp(game, entity, vPhaseReport);
// Add +5 Heat if the hex you're in is on fire
// and was on fire for the full round.
@@ -29047,7 +28980,7 @@ public boolean accept(Entity entity) {
|| entity.hasQuirk(OptionsConstants.QUIRK_POS_SEARCHLIGHT));
entityIds.add(entity.getId());
- if (game.getPhase() != GamePhase.LOUNGE) {
+ if (!getGame().getPhase().isLounge()) {
entity.getOwner().changeInitialEntityCount(1);
entity.getOwner().changeInitialBV(entity.calculateBattleValue());
}
@@ -29210,7 +29143,7 @@ private void receiveEntityUpdate(Packet c, int connIndex) {
game.setEntity(entity.getId(), entity);
entityUpdate(entity.getId());
// In the chat lounge, notify players of customizing of unit
- if (game.getPhase() == GamePhase.LOUNGE) {
+ if (game.getPhase().isLounge()) {
sendServerChat(ServerLobbyHelper.entityUpdateMessage(entity, game));
}
}
@@ -29223,7 +29156,7 @@ private void receiveEntityUpdate(Packet c, int connIndex) {
* remain unchanged but still be sent back to overwrite incorrect client changes.
*/
private void receiveEntitiesUpdate(Packet c, int connIndex) {
- if (game.getPhase() != GamePhase.LOUNGE) {
+ if (!getGame().getPhase().isLounge()) {
LogManager.getLogger().error("Multi entity updates should not be used outside the lobby phase!");
}
Set newEntities = new HashSet<>();
@@ -29309,7 +29242,7 @@ private void receiveEntityLoad(Packet c, int connIndex) {
*/
private void receiveCustomInit(Packet c, int connIndex) {
// In the chat lounge, notify players of customizing of unit
- if (game.getPhase() == GamePhase.LOUNGE) {
+ if (game.getPhase().isLounge()) {
Player p = (Player) c.getObject(0);
sendServerChat("" + p.getName() + " has customized initiative.");
}
@@ -29639,7 +29572,7 @@ public boolean accept(Entity entity) {
} // End update-unit-number
} // End added-ProtoMech
- if (game.getPhase() != GamePhase.DEPLOYMENT) {
+ if (!getGame().getPhase().isDeployment()) {
// if a unit is removed during deployment just keep going
// without adjusting the turn vector.
game.removeTurnFor(entity);
@@ -29657,7 +29590,7 @@ public boolean accept(Entity entity) {
send(createRemoveEntityPacket(ids, affectedForces, IEntityRemovalConditions.REMOVE_NEVER_JOINED));
// Prevents deployment hanging. Only do this during deployment.
- if (game.getPhase() == GamePhase.DEPLOYMENT) {
+ if (game.getPhase().isDeployment()) {
for (Integer entityId : ids) {
final Entity entity = game.getEntity(entityId);
game.removeEntity(entityId, IEntityRemovalConditions.REMOVE_NEVER_JOINED);
@@ -29679,7 +29612,7 @@ private void receivePlayerDone(Packet pkt, int connIndex) {
private void receiveInitiativeRerollRequest(Packet pkt, int connIndex) {
Player player = game.getPlayer(connIndex);
- if (GamePhase.INITIATIVE_REPORT != game.getPhase()) {
+ if (!game.getPhase().isInitiativeReport()) {
StringBuilder message = new StringBuilder();
if (null == player) {
message.append("Player #").append(connIndex);
@@ -33006,7 +32939,7 @@ private void resolveSinkVees() {
* let all Entities make their "break-free-of-swamp-stickyness" PSR
*/
private void doTryUnstuck() {
- if (game.getPhase() != GamePhase.MOVEMENT) {
+ if (!getGame().getPhase().isMovement()) {
return;
}
diff --git a/megamek/src/megamek/server/Messages.java b/megamek/src/megamek/server/Messages.java
index 86530e05411..6953f53554c 100644
--- a/megamek/src/megamek/server/Messages.java
+++ b/megamek/src/megamek/server/Messages.java
@@ -1,7 +1,6 @@
package megamek.server;
import megamek.MegaMek;
-import megamek.common.util.EncodeControl;
import org.apache.logging.log4j.LogManager;
import java.util.MissingResourceException;
@@ -9,7 +8,7 @@
public class Messages {
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle("megamek.server.messages",
- MegaMek.getMMOptions().getLocale(), new EncodeControl());
+ MegaMek.getMMOptions().getLocale());
private Messages() {
diff --git a/megamek/src/megamek/server/Server.java b/megamek/src/megamek/server/Server.java
index 129fcf864f3..0944ceaf7a4 100644
--- a/megamek/src/megamek/server/Server.java
+++ b/megamek/src/megamek/server/Server.java
@@ -20,6 +20,7 @@
import megamek.MegaMek;
import megamek.Version;
import megamek.client.ui.swing.util.PlayerColour;
+import megamek.codeUtilities.StringUtility;
import megamek.common.*;
import megamek.common.annotations.Nullable;
import megamek.common.commandline.AbstractCommandLineParser.ParseException;
@@ -271,7 +272,7 @@ public static String validatePlayerName(String playerName) throws ParseException
* @return valid password or null if no password or password is blank string
*/
public static @Nullable String validatePassword(@Nullable String password) {
- return ((password == null) || password.isBlank()) ? null : password.trim();
+ return StringUtility.isNullOrBlank(password) ? null : password.trim();
}
/**
@@ -281,7 +282,7 @@ public static String validatePlayerName(String playerName) throws ParseException
* @return true if the user-supplied data matches the server password or no password is set.
*/
public boolean passwordMatches(Object password) {
- return (this.password == null) || this.password.isBlank() || this.password.equals(password);
+ return StringUtility.isNullOrBlank(this.password) || this.password.equals(password);
}
/**
@@ -300,21 +301,15 @@ public static int validatePort(int port) throws ParseException {
}
}
- public Server(String password, int port, IGameManager gameManager) throws IOException {
+ public Server(@Nullable String password, int port, IGameManager gameManager) throws IOException {
this(password, port, gameManager, false, "", null, false);
}
- public Server(String password, int port, IGameManager gameManager,
- boolean registerWithServerBrowser, String metaServerUrl) throws IOException {
+ public Server(@Nullable String password, int port, IGameManager gameManager,
+ boolean registerWithServerBrowser, @Nullable String metaServerUrl) throws IOException {
this(password, port, gameManager, registerWithServerBrowser, metaServerUrl, null, false);
}
- public Server(String password, int port, IGameManager gameManager,
- boolean registerWithServerBrowser, String metaServerUrl, EmailService mailer)
- throws IOException {
- this(password, port, gameManager, registerWithServerBrowser, metaServerUrl, mailer, false);
- }
-
/**
* Construct a new GameHost and begin listening for incoming clients.
*
@@ -330,10 +325,9 @@ public Server(String password, int port, IGameManager gameManager,
public Server(@Nullable String password, int port, IGameManager gameManager,
boolean registerWithServerBrowser, @Nullable String metaServerUrl,
@Nullable EmailService mailer, boolean dedicated) throws IOException {
- this.metaServerUrl = (metaServerUrl != null) && (!metaServerUrl.isBlank()) ? metaServerUrl : null;
- this.password = (password != null) && (!password.isBlank()) ? password : null;
+ this.metaServerUrl = StringUtility.isNullOrBlank(metaServerUrl) ? null : metaServerUrl;
+ this.password = StringUtility.isNullOrBlank(password) ? null : password;
this.gameManager = gameManager;
-
this.mailer = mailer;
this.dedicated = dedicated;
@@ -376,7 +370,7 @@ public Server(@Nullable String password, int port, IGameManager gameManager,
packetPumpThread.start();
if (registerWithServerBrowser) {
- if ((metaServerUrl != null) && (!metaServerUrl.isBlank())) {
+ if (!StringUtility.isNullOrBlank(metaServerUrl)) {
final TimerTask register = new TimerTask() {
@Override
public void run() {
@@ -873,7 +867,7 @@ public boolean loadGame(File f, boolean sendInfo) {
Game newGame;
try (InputStream is = new FileInputStream(f); InputStream gzi = new GZIPInputStream(is)) {
- XStream xstream = SerializationHelper.getXStream();
+ XStream xstream = SerializationHelper.getLoadSaveGameXStream();
newGame = (Game) xstream.fromXML(gzi);
} catch (Exception e) {
LogManager.getLogger().error("Unable to load file: " + f, e);
@@ -1317,9 +1311,9 @@ public int getPort() {
}
/**
- * @return the current server instance
+ * @return the current server instance. This may be null if a server has not been started
*/
- public static Server getServerInstance() {
+ public static @Nullable Server getServerInstance() {
return serverInstance;
}
diff --git a/megamek/src/megamek/server/ServerHelper.java b/megamek/src/megamek/server/ServerHelper.java
index 7e992098aca..896b7a2555b 100644
--- a/megamek/src/megamek/server/ServerHelper.java
+++ b/megamek/src/megamek/server/ServerHelper.java
@@ -96,6 +96,9 @@ public static void resolveAeroHeat(Game game, Entity entity, Vector vPha
vPhaseReport.add(r);
}
+ // Add or subtract heat due to extreme temperatures TO:AR p60
+ adjustHeatExtremeTemp(game, entity, vPhaseReport);
+
// Combat computers help manage heat
if (entity.hasQuirk(OptionsConstants.QUIRK_POS_COMBAT_COMPUTER)) {
int reduce = Math.min(entity.heatBuildup, 4);
@@ -398,7 +401,45 @@ else if ((entity.heat >= 14) && !entity.isShutDown()) {
vPhaseReport.addAll(s.destroyEntity(entity, "pilot death", true));
}
}
-
+
+ public static void adjustHeatExtremeTemp(Game game, Entity entity, Vector vPhaseReport) {
+ Report r;
+ int tempDiff = game.getPlanetaryConditions().getTemperatureDifference(50, -30);
+ boolean heatArmor = false;
+ boolean laserHS = false;
+
+ if (entity instanceof Mech) {
+ laserHS = ((Mech) entity).hasLaserHeatSinks();
+ heatArmor = ((Mech) entity).hasIntactHeatDissipatingArmor();
+ }
+
+ if (game.getBoard().inSpace() || (tempDiff == 0) || laserHS) {
+ return;
+ } else {
+ if (game.getPlanetaryConditions().getTemperature() > 50) {
+ int heatToAdd = tempDiff;
+ if (heatArmor) {
+ heatToAdd /= 2;
+ }
+ entity.heatFromExternal += heatToAdd;
+ r = new Report(5020);
+ r.subject = entity.getId();
+ r.add(heatToAdd);
+ vPhaseReport.add(r);
+ if (heatArmor) {
+ r = new Report(5550);
+ vPhaseReport.add(r);
+ }
+ } else {
+ entity.heatFromExternal -= tempDiff;
+ r = new Report(5025);
+ r.subject = entity.getId();
+ r.add(tempDiff);
+ vPhaseReport.add(r);
+ }
+ }
+ }
+
/**
* Helper function that causes an entity to sink to the bottom of the water
* hex it's currently in.
@@ -445,12 +486,24 @@ public static void checkAndApplyMagmaCrust(Hex hex, int elevation, Entity entity
hex.addTerrain(new Terrain(Terrains.MAGMA, 2));
gameManager.sendChangedHex(curPos);
for (Entity en : entity.getGame().getEntitiesVector(curPos)) {
- gameManager.doMagmaDamage(en, false);
+ if (en != entity) {
+ gameManager.doMagmaDamage(en, false);
+ }
}
}
}
}
+ /**
+ * Check for movement into magma hex and apply damage.
+ */
+ public static void checkEnteringMagma(Hex hex, int elevation, Entity entity, GameManager gameManager) {
+
+ if ((hex.terrainLevel(Terrains.MAGMA) == 2) && (elevation == 0) && (entity.getMovementMode() != EntityMovementMode.HOVER)) {
+ gameManager.doMagmaDamage(entity, false);
+ }
+ }
+
/**
* Loops through all active entities in the game and performs mine detection
*/
@@ -644,4 +697,28 @@ public static void clearBloodStalkers(Game game, int stalkeeID, GameManager game
}
}
}
+
+ /**
+ * Returns the target number to avoid Radical Heat Sink Failure for the given number of rounds
+ * of consecutive use, IO p.89. The first round of use means consecutiveRounds = 1; this is
+ * the minimum as 0 rounds of use would not trigger a roll.
+ * @param consecutiveRounds The rounds the RHS has been used
+ * @return The roll target number to avoid failure
+ */
+ public static int radicalHeatSinkSuccessTarget(int consecutiveRounds) {
+ switch (consecutiveRounds) {
+ case 1:
+ return 3;
+ case 2:
+ return 5;
+ case 3:
+ return 7;
+ case 4:
+ return 10;
+ case 5:
+ return 11;
+ default:
+ return TargetRoll.AUTOMATIC_FAIL;
+ }
+ }
}
diff --git a/megamek/src/megamek/test/ASWeaponDamageList.java b/megamek/src/megamek/test/ASWeaponDamageList.java
index 0d9fac3ccc4..f0d6d1dab41 100644
--- a/megamek/src/megamek/test/ASWeaponDamageList.java
+++ b/megamek/src/megamek/test/ASWeaponDamageList.java
@@ -38,6 +38,7 @@ public static void main(String[] args) {
&&!(etype instanceof BayWeapon)) {
wpLine = new ArrayList<>();
wpLine.add(etype.getName());
+ wpLine.add(etype.getInternalName());
wpLine.add(etype.isClan()? "-Clan-" : "-IS-");
double mult = etype.hasFlag(WeaponType.F_ONESHOT) ? 0.1 : 1;
double s = mult * ((WeaponType)etype).getBattleForceDamage(AlphaStrikeElement.SHORT_RANGE, null);
diff --git a/megamek/src/megamek/utilities/xml/MMXMLUtility.java b/megamek/src/megamek/utilities/xml/MMXMLUtility.java
index a24c4a74180..dd80efd308d 100644
--- a/megamek/src/megamek/utilities/xml/MMXMLUtility.java
+++ b/megamek/src/megamek/utilities/xml/MMXMLUtility.java
@@ -380,47 +380,6 @@ public static void writeSimpleXMLCloseTag(final PrintWriter pw, final int indent
}
//endregion Close Tag
- //region Deprecated Tag Writers
- @Deprecated
- public static void writeSimpleXMLOpenIndentedLine(final PrintWriter pw, final int indent,
- final String name) {
- writeSimpleXMLOpenTag(pw, indent, name, null, null, null, null);
- }
-
- @Deprecated
- public static void writeSimpleXmlTag(PrintWriter pw1, int indent, String name, UUID val) {
- if (val != null) {
- writeSimpleXmlTag(pw1, indent, name, val.toString());
- }
- }
-
- @Deprecated
- public static void writeSimpleXmlTag(PrintWriter pw1, int indent, String name, String val) {
- pw1.println(indentStr(indent) + '<' + name + '>' + escape(val) + "" + name + '>');
- }
-
- @Deprecated
- public static void writeSimpleXmlTag(PrintWriter pw1, int indent, String name, int val) {
- pw1.println(indentStr(indent) + '<' + name + '>' + val + "" + name + '>');
- }
-
- @Deprecated
- public static void writeSimpleXmlTag(PrintWriter pw1, int indent, String name, boolean val) {
- pw1.println(indentStr(indent) + '<' + name + '>' + val + "" + name + '>');
- }
-
- @Deprecated
- public static void writeSimpleXmlTag(PrintWriter pw1, int indent, String name, double val) {
- pw1.println(indentStr(indent) + '<' + name + '>' + val + "" + name + '>');
- }
-
- @Deprecated
- public static void writeSimpleXMLCloseIndentedLine(final PrintWriter pw, final int indent,
- final String name) {
- writeSimpleXMLCloseTag(pw, indent, name);
- }
- //endregion Deprecated Tag Writers
-
/**
* @param level the level to indent up to
* @return a string containing level tab indents
diff --git a/megamek/unittests/megamek/common/BoardDimensionsTests.java b/megamek/unittests/megamek/common/BoardDimensionsTests.java
index 630c46a1a05..7ac9188d8c5 100644
--- a/megamek/unittests/megamek/common/BoardDimensionsTests.java
+++ b/megamek/unittests/megamek/common/BoardDimensionsTests.java
@@ -19,6 +19,7 @@
*/
package megamek.common;
+import megamek.codeUtilities.MathUtility;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -48,15 +49,6 @@ public final void testInstantiation() {
assertEquals(8000, b.numHexes());
}
- @Test
- public final void testCopyConstructor() {
- BoardDimensions b = new BoardDimensions(20, 10);
- BoardDimensions c = new BoardDimensions(b);
-
- assertEquals(20, c.width());
- assertEquals(10, c.height());
- }
-
@Test
public final void testEqualsObject() {
BoardDimensions b = new BoardDimensions(10, 10);
@@ -78,17 +70,10 @@ public final void testNotEqualsObject() {
assertNotEquals(b, new BoardDimensions(5, 10));
}
- @Test
- public final void testClone() {
- BoardDimensions b = new BoardDimensions(10, 10);
- assertNotSame(b.clone(), b);
- assertEquals(b.clone(), b);
- }
-
@Test
public final void testToString() {
- assertEquals("10x10", new BoardDimensions(10, 10).toString());
- assertEquals("80x50", new BoardDimensions(80, 50).toString());
+ assertEquals("10 x 10", new BoardDimensions(10, 10).toString());
+ assertEquals("80 x 50", new BoardDimensions(80, 50).toString());
}
@Test
@@ -98,14 +83,23 @@ public final void testCompareTo() {
assertEquals(0, new BoardDimensions(Integer.MAX_VALUE,
Integer.MAX_VALUE).compareTo(new BoardDimensions(
Integer.MAX_VALUE, Integer.MAX_VALUE)));
- assertEquals(-1,
- new BoardDimensions(10, 10).compareTo(new BoardDimensions(
- Integer.MAX_VALUE, Integer.MAX_VALUE)));
- assertEquals(1, new BoardDimensions(Integer.MAX_VALUE,
- Integer.MAX_VALUE).compareTo(new BoardDimensions(10, 10)));
- assertEquals(-1,
- new BoardDimensions(10, 20).compareTo(new BoardDimensions(20, 10)));
- assertEquals(1,
- new BoardDimensions(20, 10).compareTo(new BoardDimensions(10, 20)));
+
+ int result = MathUtility.clamp(new BoardDimensions(10, 10).compareTo(new BoardDimensions(
+ Integer.MAX_VALUE, Integer.MAX_VALUE)), -1, 1);
+ assertEquals(-1, result);
+
+ result = MathUtility.clamp(new BoardDimensions(Integer.MAX_VALUE,
+ Integer.MAX_VALUE).compareTo(new BoardDimensions(10, 10)), -1, 1);
+ assertEquals(1, result);
+
+ result = MathUtility.clamp(
+ new BoardDimensions(10, 20).compareTo(new BoardDimensions(20, 10)),
+ -1, 1);
+ assertEquals(-1, result);
+
+ result = MathUtility.clamp(
+ new BoardDimensions(20, 10).compareTo(new BoardDimensions(10, 20)),
+ -1, 1);
+ assertEquals(1, result);
}
}
|