Skip to content

Commit

Permalink
Merge pull request #4865 from Sleet01/fix_4861_hang_when_two_variable…
Browse files Browse the repository at this point in the history
…_rate_weapons_together_consume_more_ammo_than_remains

Fix for RAC and UAC ammo bingo state hanging game
  • Loading branch information
HammerGS authored Nov 12, 2023
2 parents 68bcc5f + 6986af6 commit 7de99f3
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 53 deletions.
69 changes: 31 additions & 38 deletions megamek/src/megamek/common/weapons/RACHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ public RACHandler(ToHitData t, WeaponAttackAction w, Game g, GameManager m) {

/*
* (non-Javadoc)
*
*
* @see megamek.common.weapons.UltraWeaponHandler#doChecks(java.util.Vector)
*/
@Override
protected boolean doChecks(Vector<Report> vPhaseReport) {
if (doAmmoFeedProblemCheck(vPhaseReport)) {
return true;
}

if (ae instanceof Infantry) {
return false;
}
Expand Down Expand Up @@ -91,57 +91,50 @@ protected boolean doChecks(Vector<Report> vPhaseReport) {

/*
* (non-Javadoc)
*
*
* @see megamek.common.weapons.WeaponHandler#useAmmo()
*/
@Override
protected void useAmmo() {
int actualShots;
setDone();
checkAmmo();
if (weapon.curMode().equals(Weapon.MODE_RAC_SIX_SHOT)) {
howManyShots = 6;
} else if (weapon.curMode().equals(Weapon.MODE_RAC_FIVE_SHOT)) {
howManyShots = 5;
} else if (weapon.curMode().equals(Weapon.MODE_RAC_FOUR_SHOT)) {
howManyShots = 4;
} else if (weapon.curMode().equals(Weapon.MODE_RAC_THREE_SHOT)) {
howManyShots = 3;
} else if (weapon.curMode().equals(Weapon.MODE_RAC_TWO_SHOT)) {
howManyShots = 2;
} else if (weapon.curMode().equals(Weapon.MODE_AC_SINGLE)) {
howManyShots = 1;

switch (weapon.curMode().toString()) {
case Weapon.MODE_RAC_SIX_SHOT: howManyShots = 6;
break;
case Weapon.MODE_RAC_FIVE_SHOT: howManyShots = 5;
break;
case Weapon.MODE_RAC_FOUR_SHOT: howManyShots = 4;
break;
case Weapon.MODE_RAC_THREE_SHOT: howManyShots = 3;
break;
case Weapon.MODE_RAC_TWO_SHOT: howManyShots = 2;
break;
case Weapon.MODE_AC_SINGLE: howManyShots = 1;
break;
}

// Reduce number of allowed shots to number of remaining rounds of ammo if applicable
int total = ae.getTotalAmmoOfType(ammo.getType());
if (total >= 6) {
actualShots = 6;
} else if (total >= 5) {
actualShots = 5;
} else if (total >= 3) {
actualShots = 3;
} else if (total >= 2) {
actualShots = 2;
if (total < 0 ) {
throw new RuntimeException("Invalid total ammo value < 0!");
} else if (total < 6) {
actualShots = total;
} else {
actualShots = 1;
actualShots = 6;
}
if (actualShots < howManyShots) {
howManyShots = actualShots;
}

int shotsNeedFiring = howManyShots;
if (ammo.getUsableShotsLeft() == 0) {
ae.loadWeapon(weapon);
ammo = weapon.getLinked();
// there will be some ammo somewhere, otherwise shot will not have
// been fired.
}

while (shotsNeedFiring > ammo.getUsableShotsLeft()) {
shotsNeedFiring -= ammo.getBaseShotsLeft();
ammo.setShotsLeft(0);
ae.loadWeapon(weapon);
ammo = weapon.getLinked();
}
ammo.setShotsLeft(ammo.getBaseShotsLeft() - shotsNeedFiring);
// Try to reload if the linked bin is empty but another exists
attemptToReloadWeapon();

// Reduce linked ammo bin; if it runs out, switch to another.
reduceShotsLeft(shotsNeedFiring);
}

@Override
Expand All @@ -153,5 +146,5 @@ protected boolean usesClusterTable() {
protected int calcnClusterAero(Entity entityTarget) {
return 5;
}

}
39 changes: 24 additions & 15 deletions megamek/src/megamek/common/weapons/UltraWeaponHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,40 +56,49 @@ public UltraWeaponHandler(ToHitData t, WeaponAttackAction w, Game g, GameManager

/*
* (non-Javadoc)
*
*
* @see megamek.common.weapons.WeaponHandler#addHeatUseAmmo()
*/
@Override
protected void useAmmo() {
setDone();
checkAmmo();
howManyShots = (weapon.curMode().equals(Weapon.MODE_AC_SINGLE) ? 1 : 2);
int total = ae.getTotalAmmoOfType(ammo.getType());
if ((total > 1) && !weapon.curMode().equals(Weapon.MODE_AC_SINGLE)) {
howManyShots = 2;
} else {
if (total > 1 ) {
// No need to change howManyShots
} else if (total == 1) {
howManyShots = 1;
} else {
howManyShots = 0;
}

// Handle bins that are empty or will be emptied by this attack
attemptToReloadWeapon();
reduceShotsLeft(howManyShots);
}

protected void attemptToReloadWeapon() {
// We _may_ be able to reload from another ammo source, but in case
// a previous attack burned through all the ammo, this attack may be SOL.
if (ammo.getUsableShotsLeft() == 0) {
ae.loadWeapon(weapon);
ammo = weapon.getLinked();
// there will be some ammo somewhere, otherwise shot will not have been fired.
}
}

if (ammo.getUsableShotsLeft() == 1) {
protected void reduceShotsLeft(int shotsNeedFiring) {
while (shotsNeedFiring > ammo.getUsableShotsLeft()) {
shotsNeedFiring -= ammo.getBaseShotsLeft();
ammo.setShotsLeft(0);
ae.loadWeapon(weapon);
ammo = weapon.getLinked();
// that fired one, do we need to fire another?
ammo.setShotsLeft(ammo.getBaseShotsLeft() - ((howManyShots == 2) ? 1 : 0));
} else {
ammo.setShotsLeft(ammo.getBaseShotsLeft() - howManyShots);
attemptToReloadWeapon();
}
ammo.setShotsLeft(ammo.getBaseShotsLeft() - shotsNeedFiring);
}

/*
* (non-Javadoc)
*
*
* @see megamek.common.weapons.WeaponHandler#calcHits(java.util.Vector)
*/
@Override
Expand Down Expand Up @@ -138,7 +147,7 @@ protected int calcHits(Vector<Report> vPhaseReport) {

/*
* (non-Javadoc)
*
*
* @see megamek.common.weapons.WeaponHandler#doChecks(java.util.Vector)
*/
@Override
Expand All @@ -165,7 +174,7 @@ protected boolean doChecks(Vector<Report> vPhaseReport) {

/*
* (non-Javadoc)
*
*
* @see megamek.common.weapons.WeaponHandler#calcDamagePerHit()
*/
@Override
Expand Down

0 comments on commit 7de99f3

Please sign in to comment.