Skip to content

Commit

Permalink
feat: AC-AutoResolve feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Scoppio committed Dec 13, 2024
1 parent d778437 commit fda468b
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 3 deletions.
1 change: 1 addition & 0 deletions megamek/i18n/megamek/client/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,7 @@ CommonSettingsDialog.locale.Russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439
CommonSettingsDialog.locale.Spanish=Español
CommonSettingsDialog.locale=Language/Sprache/\u042f\u0437\u044b\u043a:
CommonSettingsDialog.logFileName=Game log filename:
CommonSettingsDialog.autoResolveLogFileName=Auto resolve game log filename:
CommonSettingsDialog.userDir=User Files Directory:
CommonSettingsDialog.userDir.tooltip=<html>Use this directory for resources you want to share between different installs or versions of MegaMek, MegaMekLab and MekHQ. Fonts, units, camos, portraits and fluff images will also be loaded from this directory.<BR>Note: Inside the user directory, use the directory structure of MM/MML/MHQ for camos, portraits and fluff images, i.e. data/images/camo, data/images/portraits and data/images/fluff/. <BR>Fonts and units can be placed anywhere in the user directory.
CommonSettingsDialog.userDir.chooser.title=Choose User Data Folder
Expand Down
20 changes: 20 additions & 0 deletions megamek/src/megamek/client/ui/swing/CommonSettingsDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ private <T> void moveElement(DefaultListModel<T> srcModel, int srcIndex, int trg
private JTextField mmlPath;
private final JCheckBox keepGameLog = new JCheckBox(Messages.getString("CommonSettingsDialog.keepGameLog"));
private JTextField gameLogFilename;
private JTextField autoResolveGameLogFilename;
private final JCheckBox stampFilenames = new JCheckBox(Messages.getString("CommonSettingsDialog.stampFilenames"));
private JTextField stampFormat;
private final JCheckBox defaultAutoejectDisabled = new JCheckBox(
Expand Down Expand Up @@ -315,6 +316,7 @@ private <T> void moveElement(DefaultListModel<T> srcModel, int srcIndex, int trg

private JLabel stampFormatLabel;
private JLabel gameLogFilenameLabel;
private JLabel autoResolveGameLogFilenameLabel;

private final JCheckBox gameSummaryBV = new JCheckBox(
Messages.getString("CommonSettingsDialog.gameSummaryBV.name"));
Expand Down Expand Up @@ -1839,6 +1841,17 @@ public Component getListCellRendererComponent(JList<?> list, Object value, int i
row.add(gameLogFilename);
comps.add(row);

addLineSpacer(comps);

autoResolveGameLogFilenameLabel = new JLabel(Messages.getString("CommonSettingsDialog.autoResolveLogFileName"));
autoResolveGameLogFilename = new JTextField(15);
autoResolveGameLogFilename.setMaximumSize(new Dimension(250, 40));
row = new ArrayList<>();
row.add(Box.createRigidArea(DEPENDENT_INSET));
row.add(autoResolveGameLogFilenameLabel);
row.add(autoResolveGameLogFilename);
comps.add(row);

addSpacer(comps, 5);
comps.add(checkboxEntry(stampFilenames, null));

Expand Down Expand Up @@ -1949,6 +1962,8 @@ public void setVisible(boolean visible) {
keepGameLog.setSelected(CLIENT_PREFERENCES.keepGameLog());
gameLogFilename.setEnabled(keepGameLog.isSelected());
gameLogFilename.setText(CLIENT_PREFERENCES.getGameLogFilename());
autoResolveGameLogFilename.setEnabled(keepGameLog.isSelected());
autoResolveGameLogFilename.setText(CLIENT_PREFERENCES.getAutoResolveGameLogFilename());
userDir.setText(CLIENT_PREFERENCES.getUserDir());
mmlPath.setText(CLIENT_PREFERENCES.getMmlPath());
stampFilenames.setSelected(CLIENT_PREFERENCES.stampFilenames());
Expand Down Expand Up @@ -2057,6 +2072,8 @@ public void setVisible(boolean visible) {
stampFormatLabel.setEnabled(stampFilenames.isSelected());
gameLogFilenameLabel.setEnabled(keepGameLog.isSelected());

autoResolveGameLogFilenameLabel.setEnabled(keepGameLog.isSelected());

getFocus.setSelected(GUIP.getFocus());

savedFovHighlight = GUIP.getFovHighlight();
Expand Down Expand Up @@ -2427,6 +2444,7 @@ protected void okAction() {

CLIENT_PREFERENCES.setKeepGameLog(keepGameLog.isSelected());
CLIENT_PREFERENCES.setGameLogFilename(gameLogFilename.getText());
CLIENT_PREFERENCES.setAutoResolveGameLogFilename(autoResolveGameLogFilename.getText());
CLIENT_PREFERENCES.setUserDir(userDir.getText());
CLIENT_PREFERENCES.setMmlPath(mmlPath.getText());
CLIENT_PREFERENCES.setStampFilenames(stampFilenames.isSelected());
Expand Down Expand Up @@ -2786,6 +2804,8 @@ public void itemStateChanged(ItemEvent event) {
gameLogFilename.setEnabled(keepGameLog.isSelected());
stampFormatLabel.setEnabled(stampFilenames.isSelected());
gameLogFilenameLabel.setEnabled(keepGameLog.isSelected());
autoResolveGameLogFilenameLabel.setEnabled(keepGameLog.isSelected());
autoResolveGameLogFilename.setEnabled(keepGameLog.isSelected());
// gameLogMaxSize.setEnabled(keepGameLog.isSelected());
} else if (source.equals(stampFilenames)) {
stampFormat.setEnabled(stampFilenames.isSelected());
Expand Down
7 changes: 7 additions & 0 deletions megamek/src/megamek/common/IGame.java
Original file line number Diff line number Diff line change
Expand Up @@ -509,4 +509,11 @@ default Board getBoard() {

Optional<Integer> idForPlayername(String playerName);

default Map<Integer, Integer> getTeamByPlayer() {
Map<Integer, Integer> teamByPlayer = new HashMap<>();
for (var player : getPlayersList()) {
teamByPlayer.put(player.getId(), player.getTeam());
}
return teamByPlayer;
}
}
4 changes: 4 additions & 0 deletions megamek/src/megamek/common/preference/ClientPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,10 @@ public void setGameLogFilename(String name) {
store.setValue(GAMELOG_FILENAME, name);
}

public void setAutoResolveGameLogFilename(String name) {
store.setValue(AUTO_RESOLVE_GAMELOG_FILENAME, name);
}

public void setPrintEntityChange(boolean print) {
store.setValue(PRINT_ENTITY_CHANGE, print);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ public SBFFormationReportEntry(SBFFormation formation, SBFGame game) {

@Override
protected String reportText() {
return "<span style='color:" + playerColorHex + ";'>" + formationName + "</span>";
return "<span style='color:" + playerColorHex + "; font-weight: bold;'>" + formationName + "</span>";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@

import megamek.common.annotations.Nullable;

import java.io.Serial;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;

public abstract class AbstractWeightedMap<K extends Number, T> extends TreeMap<K, T> {
//region Variable Declarations
@Serial
private static final long serialVersionUID = 6745329554873562471L;
//endregion Variable Declarations

/**
* @param weight the weight to put the item at
* @param value the value of the item
* @return the return value of {@link TreeMap#put}, or null if the value is not added to the map
* @return the return value of {@link TreeMap#put(Object, Object)}, or null if the value is not added to the map
*/
public abstract @Nullable T add(final K weight, final T value);

Expand All @@ -38,6 +41,13 @@ public abstract class AbstractWeightedMap<K extends Number, T> extends TreeMap<K
*/
public abstract @Nullable T randomItem();

/**
* @return an optional random item from the weighted map, or Optional empty if it is empty
*/
public Optional<T> randomOptionalItem() {
return isEmpty() ? Optional.empty() : Optional.ofNullable(randomItem());
}

/**
* @param key the key of the item to get (used for simplification and unit testing reasons)
* @return the item from the weighted map, or null if it does not exist
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

import megamek.common.annotations.Nullable;

import java.io.Serial;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom;

/**
Expand All @@ -30,6 +33,7 @@
*/
public class WeightedDoubleMap<T> extends AbstractWeightedMap<Double, T> {
//region Variable Declarations
@Serial
private static final long serialVersionUID = -2040584639476035520L;
//endregion Variable Declarations

Expand All @@ -40,6 +44,96 @@ public class WeightedDoubleMap<T> extends AbstractWeightedMap<Double, T> {

@Override
public @Nullable T randomItem() {
return isEmpty() ? null : randomItem(ThreadLocalRandom.current().nextDouble(0.0d, lastKey()));
return isEmpty() ? null : randomItem(getRandomKey());
}

private double getRandomKey() {
return ThreadLocalRandom.current().nextDouble(0.0d, lastKey());
}

/**
* @return an optional random item from the weighted map, or Optional empty if it is empty
*/
public Optional<T> randomOptionalItem(T[] except) {
double randomKey = getRandomKey();
double cumulativeWeight = 0.0;
var isException = false;
var i = 0;
for (var entry : entrySet()) {
isException = false;
for (i = 0; i < except.length; i++) {
if (entry.getValue().equals(except[i])) {
isException = true;
break;
}
}
if (isException) {
continue;
}
cumulativeWeight += entry.getKey();
if (randomKey <= cumulativeWeight) {
return Optional.of(entry.getValue());
}
}

return Optional.empty();
}

public WeightedDoubleMap() {}

WeightedDoubleMap(Object... input) {
if ((input.length & 1) != 0) { // implicit null check of input
throw new InternalError("length is odd");
}
for (int i = 0; i < input.length; i += 2) {
@SuppressWarnings("unchecked")
T t = Objects.requireNonNull((T) input[i]);
double weight = (double) input[i+1];
var alreadyPresent = this.entrySet().stream().anyMatch(entry -> entry.getValue().equals(t));
if (alreadyPresent) {
throw new IllegalArgumentException("duplicate value: " + t);
}
this.put(weight, t);
}
}

public static <T> WeightedDoubleMap<T> of(T t1, double w1) {
return new WeightedDoubleMap<>(t1, w1);
}

public static <T> WeightedDoubleMap<T> of(T t1, double w1, T t2, double w2) {
return new WeightedDoubleMap<>(t1, w1, t2, w2);
}

public static <T> WeightedDoubleMap<T> of(T t1, double w1, T t2, double w2, T t3, double w3) {
return new WeightedDoubleMap<>(t1, w1, t2, w2, t3, w3);
}

public static <T> WeightedDoubleMap<T> of(T t1, double w1, T t2, double w2, T t3, double w3, T t4, double w4) {
return new WeightedDoubleMap<>(t1, w1, t2, w2, t3, w3, t4, w4);
}

public static <T> WeightedDoubleMap<T> of(T t1, double w1, T t2, double w2, T t3, double w3, T t4, double w4, T t5, double w5) {
return new WeightedDoubleMap<>(t1, w1, t2, w2, t3, w3, t4, w4, t5, w5);
}

public static <T> WeightedDoubleMap<T> of(T t1, double w1, T t2, double w2, T t3, double w3, T t4, double w4, T t5, double w5, T t6, double w6) {
return new WeightedDoubleMap<>(t1, w1, t2, w2, t3, w3, t4, w4, t5, w5, t6, w6);
}

public static <T> WeightedDoubleMap<T> of(T t1, double w1, T t2, double w2, T t3, double w3, T t4, double w4, T t5, double w5, T t6, double w6, T t7, double w7) {
return new WeightedDoubleMap<>(t1, w1, t2, w2, t3, w3, t4, w4, t5, w5, t6, w6, t7, w7);
}

public static <T> WeightedDoubleMap<T> of(T t1, double w1, T t2, double w2, T t3, double w3, T t4, double w4, T t5, double w5, T t6, double w6, T t7, double w7, T t8, double w8) {
return new WeightedDoubleMap<>(t1, w1, t2, w2, t3, w3, t4, w4, t5, w5, t6, w6, t7, w7, t8, w8);
}

public static <T> WeightedDoubleMap<T> of(T t1, double w1, T t2, double w2, T t3, double w3, T t4, double w4, T t5, double w5, T t6, double w6, T t7, double w7, T t8, double w8, T t9, double w9) {
return new WeightedDoubleMap<>(t1, w1, t2, w2, t3, w3, t4, w4, t5, w5, t6, w6, t7, w7, t8, w8, t9, w9);
}

public static <T> WeightedDoubleMap<T> of(T t1, double w1, T t2, double w2, T t3, double w3, T t4, double w4, T t5, double w5, T t6, double w6, T t7, double w7, T t8, double w8, T t9, double w9, T t10, double w10) {
return new WeightedDoubleMap<>(t1, w1, t2, w2, t3, w3, t4, w4, t5, w5, t6, w6, t7, w7, t8, w8, t9, w9, t10, w10);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@
package megamek.common.util.weightedMaps;

import megamek.common.Compute;
import megamek.common.alphaStrike.ASRange;
import megamek.common.annotations.Nullable;

import java.io.Serial;
import java.util.Objects;

/**
* Constructs a table of values each with an int weight that makes them more or less likely to be
* selected at random
Expand All @@ -29,6 +33,7 @@
*/
public class WeightedIntMap<T> extends AbstractWeightedMap<Integer, T> {
//region Variable Declarations
@Serial
private static final long serialVersionUID = -568712793616821291L;
//endregion Variable Declarations

Expand All @@ -41,4 +46,5 @@ public class WeightedIntMap<T> extends AbstractWeightedMap<Integer, T> {
public @Nullable T randomItem() {
return isEmpty() ? null : randomItem(Compute.randomInt(lastKey()) + 1);
}

}

0 comments on commit fda468b

Please sign in to comment.