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

Match critical slot sort order to specification #1471

Merged
merged 2 commits into from
Apr 3, 2024
Merged
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
48 changes: 46 additions & 2 deletions megameklab/src/megameklab/util/MekUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import megamek.common.weapons.c3.ISC3MBS;
import megamek.common.weapons.infantry.InfantryWeapon;
import megamek.common.weapons.other.*;
import megamek.common.weapons.ppc.CLPlasmaCannon;
import megamek.common.weapons.tag.CLLightTAG;
import megamek.common.weapons.tag.CLTAG;
import megamek.common.weapons.tag.ISTAG;
Expand Down Expand Up @@ -967,10 +968,49 @@ public static void sortCrits(Mech mek) {
public static void sortCritSlots(Mech mek, int location) {
List<CriticalSlot> presentGear = extricateCritSlots(mek, location);
presentGear.sort(new MekCritSlotSorter(mek));
floatAmmo(presentGear);
presentGear = reOrderLinkedEquipment(presentGear);
refillCritSlots(mek, location, presentGear);
}

/**
* If the last weapon in the location uses ammo, floats compatible ammo above other ammo
* Requires the slots to have already been sorted beforehand
*/
private static void floatAmmo(List<CriticalSlot> slots) {
WeaponType lastWeapon = null;
for (CriticalSlot slot : slots) {
if (slot.getMount().getType() instanceof WeaponType) {
lastWeapon = (WeaponType) slot.getMount().getType();
}
}
if (lastWeapon == null) {
return;
}

List<CriticalSlot> compatibleAmmo = new ArrayList<>();
int insertPosition = -1;
for (int i = 0; i < slots.size(); ++i) {
if (slots.get(i).getMount().getType() instanceof AmmoType) {
if (insertPosition < 0) {
insertPosition = i;
}

AmmoType ammoType = (AmmoType) slots.get(i).getMount().getType();
if (lastWeapon.rackSize == ammoType.getRackSize() && lastWeapon.getAmmoType() == lastWeapon.getAmmoType()) {
compatibleAmmo.add(slots.get(i));
}
}
}

if (insertPosition < 0) {
return;
}

slots.removeAll(compatibleAmmo);
slots.addAll(insertPosition, compatibleAmmo);
}

/**
* Removes all crit slots from the given location except for system crit slots
* (e.g. engine) and returns them as a list.
Expand Down Expand Up @@ -1343,6 +1383,7 @@ public int compare(CriticalSlot critA, CriticalSlot critB) {
}
}


/**
* A Mounted sorter using the official sort order (mostly)
*/
Expand All @@ -1362,10 +1403,13 @@ public int compare(Mounted mountedA, Mounted mountedB) {
// compare average damage; using Aero damage here
double dmgA = 0;
double dmgB = 0;
if (mountedA.getType() instanceof WeaponType) {
// Weapons that deal heat but not damage should sort last after weapons that deal damage
// The only weapon I could find with positive aerospace damage but only heat damage against mechs
// is the plasma cannon. If others exist, this could be made to be a more comprehensive check.
if (mountedA.getType() instanceof WeaponType && !(mountedA.getType() instanceof CLPlasmaCannon)) {
dmgA = ((WeaponType) mountedA.getType()).getShortAV();
}
if (mountedB.getType() instanceof WeaponType) {
if (mountedB.getType() instanceof WeaponType && !(mountedB.getType() instanceof CLPlasmaCannon)) {
dmgB = ((WeaponType) mountedB.getType()).getShortAV();
}
if (dmgA != dmgB) {
Expand Down
Loading