Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show all locations for spreadable equipment in summary view #2912

Merged
merged 4 commits into from
Jun 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions megamek/src/megamek/common/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -3167,6 +3167,24 @@ public int getLocationFromAbbr(String abbr) {
return Entity.LOC_NONE;
}

/**
* Joins the abbreviations for the locations into a String with / as the separator.
* If the number of locations exceeds the provided limit, the result is
* abbreviated. By default the abbreviation is simply an asterisk, but Mechs have
* specific abbreviations locations that include all torso or leg positions.
*
* @param locations A list of location indices
* @param limit The maximum number of locations to show in full
* @return A string formatted for display that shows the locations
*/
public String joinLocationAbbr(List<Integer> locations, int limit) {
if (locations.size() > limit) {
return "*";
} else {
return locations.stream().map(l -> getLocationAbbr(l)).collect(Collectors.joining("/"));
}
}

/**
* Rolls the to-hit number
*/
Expand Down
13 changes: 13 additions & 0 deletions megamek/src/megamek/common/Mech.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.math.BigInteger;
import java.text.NumberFormat;
import java.util.*;
import java.util.stream.Collectors;

import megamek.MegaMek;
import megamek.common.loaders.MtfFile;
Expand Down Expand Up @@ -2098,6 +2099,18 @@ public boolean isSecondaryArcWeapon(int weaponId) {
return true;
}

@Override
public String joinLocationAbbr(List<Integer> locations, int limit) {
// If all locations are torso, strip the T from all but the last location.
// e.g. R/L/CT
if ((locations.size() > limit) && locations.stream().allMatch(this::locationIsTorso)) {
return locations.stream().map(l -> getLocationAbbr(l).replace("T", ""))
.collect(Collectors.joining("/")) + "T";
} else {
return super.joinLocationAbbr(locations, limit);
}
}

/*
* (non-Javadoc)
*
Expand Down
12 changes: 3 additions & 9 deletions megamek/src/megamek/common/MechView.java
Original file line number Diff line number Diff line change
Expand Up @@ -777,8 +777,7 @@ private List<ViewElement> getWeapons(boolean showDetail) {
wpnTable.setJustification(TableElement.JUSTIFIED_LEFT, TableElement.JUSTIFIED_CENTER,
TableElement.JUSTIFIED_CENTER, TableElement.JUSTIFIED_LEFT);
for (Mounted mounted : entity.getWeaponList()) {
String[] row = new String[] { mounted.getDesc(),
entity.getLocationAbbr(mounted.getLocation()), "", "" };
String[] row = { mounted.getDesc(), entity.joinLocationAbbr(mounted.allLocations(), 3), "", "" };
WeaponType wtype = (WeaponType) mounted.getType();

if (entity.isClan()
Expand All @@ -796,11 +795,6 @@ private List<ViewElement> getWeapons(boolean showDetail) {
* //$NON-NLS-1$ }
*/

if (mounted.isSplit()) {
row[1] += "/" + entity.getLocationAbbr(mounted // $NON-NLS-1$
.getSecondLocation());
}

int heat = wtype.getHeat();
int bWeapDamaged = 0;
if (wtype instanceof BayWeapon) {
Expand Down Expand Up @@ -912,7 +906,7 @@ private ViewElement getAmmo() {
if (mounted.getLocation() == Entity.LOC_NONE) {
continue;
}

String[] row = { mounted.getName(), entity.getLocationAbbr(mounted.getLocation()),
String.valueOf(mounted.getBaseShotsLeft()), "" };
if (entity.isOmni()) {
Expand Down Expand Up @@ -997,7 +991,7 @@ private List<ViewElement> getMisc() {
}
nEquip++;

String[] row = { mounted.getDesc(), entity.getLocationAbbr(mounted.getLocation()), "" };
String[] row = { mounted.getDesc(), entity.joinLocationAbbr(mounted.allLocations(), 3), "" };
if (entity.isClan()
&& (mounted.getType().getTechBase() == ITechnology.TECH_BASE_IS)) {
row[0] += Messages.getString("MechView.IS"); //$NON-NLS-1$
Expand Down
37 changes: 33 additions & 4 deletions megamek/src/megamek/common/Mounted.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@
package megamek.common;

import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import java.util.*;

import megamek.MegaMek;
import megamek.common.actions.WeaponAttackAction;
Expand Down Expand Up @@ -1066,6 +1063,38 @@ public void setSecondLocation(int location, boolean rearMounted) {
this.rearMounted = rearMounted;
}

/**
* Fetches all locations that contain this equipment. This is primarily for
* spreadable equipment, can be placed in locations other than the primary or secondary,
* but will also work for non-spreadable equipment.
*
* @return A list of indices for all locations that contain this equipment.
* @see #getLocation()
* @see #getSecondLocation()
*/
public List<Integer> allLocations() {
List<Integer> locations = new ArrayList<>();
if (getType().isSpreadable()) {
for (int loc = 0; loc < getEntity().locations(); loc++) {
for (int slot = 0; slot < getEntity().getNumberOfCriticals(loc); slot++) {
final CriticalSlot crit = getEntity().getCritical(loc, slot);
if ((crit != null) && ((crit.getMount() == this) || (crit.getMount2() == this))) {
locations.add(loc);
break;
}
}
}
} else {
if (getLocation() >= 0) {
locations.add(getLocation());
}
if (getSecondLocation() >= 0) {
locations.add(getSecondLocation());
}
}
return locations;
}

public Mounted getLinked() {
return linked;
}
Expand Down
11 changes: 11 additions & 0 deletions megamek/src/megamek/common/QuadMech.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package megamek.common;

import java.io.PrintWriter;
import java.util.List;

import megamek.common.options.OptionsConstants;
import megamek.common.preference.PreferenceManager;
Expand Down Expand Up @@ -423,6 +424,16 @@ protected double getLegActuatorCost() {
return (weight * 150 * 4) + (weight * 80 * 4) + (weight * 120 * 4);
}

@Override
public String joinLocationAbbr(List<Integer> locations, int limit) {
// If we need to abbreviate something that occupies all leg locations, simply return "Legs"
if ((locations.size() > limit) && (locations.size() == 4) && locations.stream().allMatch(this::locationIsLeg)) {
return "Legs";
} else {
return super.joinLocationAbbr(locations, limit);
}
}

@Override
public HitData rollHitLocation(int table, int side, int aimedLocation, int aimingMode, int cover) {
int roll = -1;
Expand Down
11 changes: 11 additions & 0 deletions megamek/src/megamek/common/TripodMech.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package megamek.common;

import java.io.PrintWriter;
import java.util.List;

import megamek.common.options.OptionsConstants;
import megamek.common.preference.PreferenceManager;
Expand Down Expand Up @@ -979,6 +980,16 @@ public int locations() {
return 9;
}

@Override
public String joinLocationAbbr(List<Integer> locations, int limit) {
// If we need to abbreviate something that occupies all leg locations, simply return "Legs"
if ((locations.size() > limit) && (locations.size() == 3) && locations.stream().allMatch(this::locationIsLeg)) {
return "Legs";
} else {
return super.joinLocationAbbr(locations, limit);
}
}

/*
* (non-Javadoc)
*
Expand Down