ref: 6d6375349747e1870f9c74bc950bfd25b6bb2b51
parent: 10eb5ee80c7854d4ec5cce996af0c250347c0231
author: Simon Howard <[email protected]>
date: Mon Jan 19 16:50:28 EST 2015
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.
--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@ -281,7 +281,7 @@
static int G_NextWeapon(int direction)
{
weapontype_t weapon;
- int i;
+ int start_i, i;
// Find index in the table.
@@ -302,13 +302,13 @@
}
}
- // 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 @@
// 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
{
@@ -468,6 +467,8 @@
}
}
}
+
+ next_weapon = 0;
// mouse
if (mousebuttons[mousebforward])
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -228,7 +228,7 @@
static int G_NextWeapon(int direction)
{
weapontype_t weapon;
- int i;
+ int start_i, i;
// Find index in the table.
@@ -249,13 +249,13 @@
}
}
- // 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 @@
// 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;
--- a/src/hexen/g_game.c
+++ b/src/hexen/g_game.c
@@ -451,9 +451,11 @@
// 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 @@
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;
--- a/src/strife/g_game.c
+++ b/src/strife/g_game.c
@@ -289,7 +289,7 @@
static int G_NextWeapon(int direction)
{
weapontype_t weapon;
- int i;
+ int start_i, i;
// Find index in the table.
@@ -311,12 +311,12 @@
}
// 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 @@
// 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
{
@@ -534,6 +533,8 @@
}
}
}
+
+ next_weapon = 0;
// mouse
if (mousebuttons[mousebforward])