Add extra checks to weapon cycling loops.

Ensure that the loops to find the next weapon always terminate -
even if there are somehow no weapons equipped. Also, only ever do
weapon cycling when in the GS_LEVEL gamestate. This fixes #503 -
thanks to Fabian and raithe on Doomworld.
This commit is contained in:
Simon Howard 2015-01-19 21:50:28 -05:00
parent 10eb5ee80c
commit 6d63753497
4 changed files with 27 additions and 20 deletions

View file

@ -281,7 +281,7 @@ static boolean WeaponSelectable(weapontype_t weapon)
static int G_NextWeapon(int direction)
{
weapontype_t weapon;
int i;
int start_i, i;
// Find index in the table.
@ -302,13 +302,13 @@ static int G_NextWeapon(int direction)
}
}
// Switch weapon.
// Switch weapon. Don't loop forever.
start_i = i;
do
{
i += direction;
i = (i + arrlen(weapon_order_table)) % arrlen(weapon_order_table);
} while (!WeaponSelectable(weapon_order_table[i].weapon));
} while (i != start_i && !WeaponSelectable(weapon_order_table[i].weapon));
return weapon_order_table[i].weapon_num;
}
@ -445,12 +445,11 @@ void G_BuildTiccmd (ticcmd_t* cmd, int maketic)
// next_weapon variable is set to change weapons when
// we generate a ticcmd. Choose a new weapon.
if (next_weapon != 0)
if (gamestate == GS_LEVEL && next_weapon != 0)
{
i = G_NextWeapon(next_weapon);
cmd->buttons |= BT_CHANGE;
cmd->buttons |= i << BT_WEAPONSHIFT;
next_weapon = 0;
}
else
{
@ -469,6 +468,8 @@ void G_BuildTiccmd (ticcmd_t* cmd, int maketic)
}
}
next_weapon = 0;
// mouse
if (mousebuttons[mousebforward])
{

View file

@ -228,7 +228,7 @@ static boolean WeaponSelectable(weapontype_t weapon)
static int G_NextWeapon(int direction)
{
weapontype_t weapon;
int i;
int start_i, i;
// Find index in the table.
@ -249,13 +249,13 @@ static int G_NextWeapon(int direction)
}
}
// Switch weapon.
// Switch weapon. Don't loop forever.
start_i = i;
do
{
i += direction;
i = (i + arrlen(weapon_order_table)) % arrlen(weapon_order_table);
} while (!WeaponSelectable(weapon_order_table[i].weapon));
} while (i != start_i && !WeaponSelectable(weapon_order_table[i].weapon));
return weapon_order_table[i].weapon_num;
}
@ -466,7 +466,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
// we generate a ticcmd. Choose a new weapon.
// (Can't weapon cycle when the player is a chicken)
if (players[consoleplayer].chickenTics == 0 && next_weapon != 0)
if (gamestate == GS_LEVEL
&& players[consoleplayer].chickenTics == 0 && next_weapon != 0)
{
i = G_NextWeapon(next_weapon);
cmd->buttons |= BT_CHANGE;

View file

@ -451,9 +451,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
// Weapon cycling. Switch to previous or next weapon.
// (Disabled when player is a pig).
if (players[consoleplayer].morphTics == 0 && next_weapon != 0)
if (gamestate == GS_LEVEL
&& players[consoleplayer].morphTics == 0 && next_weapon != 0)
{
int start_i;
if (players[consoleplayer].pendingweapon == WP_NOCHANGE)
{
i = players[consoleplayer].readyweapon;
@ -463,9 +465,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
i = players[consoleplayer].pendingweapon;
}
// Don't loop forever.
start_i = i;
do {
i = (i + next_weapon) % NUMWEAPONS;
} while (!players[consoleplayer].weaponowned[i]);
i = (i + next_weapon + NUMWEAPONS) % NUMWEAPONS;
} while (i != start_i && !players[consoleplayer].weaponowned[i]);
cmd->buttons |= BT_CHANGE;
cmd->buttons |= i << BT_WEAPONSHIFT;

View file

@ -289,7 +289,7 @@ static boolean WeaponSelectable(weapontype_t weapon)
static int G_NextWeapon(int direction)
{
weapontype_t weapon;
int i;
int start_i, i;
// Find index in the table.
@ -311,12 +311,12 @@ static int G_NextWeapon(int direction)
}
// Switch weapon.
start_i = i;
do
{
i += direction;
i = (i + arrlen(weapon_order_table)) % arrlen(weapon_order_table);
} while (!WeaponSelectable(weapon_order_table[i].weapon));
} while (i != start_i && !WeaponSelectable(weapon_order_table[i].weapon));
return weapon_order_table[i].weapon_num;
}
@ -511,12 +511,11 @@ void G_BuildTiccmd (ticcmd_t* cmd, int maketic)
// next_weapon variable is set to change weapons when
// we generate a ticcmd. Choose a new weapon.
if (next_weapon != 0)
if (gamestate == GS_LEVEL && next_weapon != 0)
{
i = G_NextWeapon(next_weapon);
cmd->buttons |= BT_CHANGE;
cmd->buttons |= i << BT_WEAPONSHIFT;
next_weapon = 0;
}
else
{
@ -535,6 +534,8 @@ void G_BuildTiccmd (ticcmd_t* cmd, int maketic)
}
}
next_weapon = 0;
// mouse
if (mousebuttons[mousebforward])
{