From 6d6375349747e1870f9c74bc950bfd25b6bb2b51 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 19 Jan 2015 21:50:28 -0500 Subject: 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. --- src/doom/g_game.c | 13 +++++++------ src/heretic/g_game.c | 11 ++++++----- src/hexen/g_game.c | 12 ++++++++---- src/strife/g_game.c | 11 ++++++----- 4 files changed, 27 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/doom/g_game.c b/src/doom/g_game.c index 0b9dda08..64f5b274 100644 --- a/src/doom/g_game.c +++ b/src/doom/g_game.c @@ -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]) { diff --git a/src/heretic/g_game.c b/src/heretic/g_game.c index 389c0e1d..1154925a 100644 --- a/src/heretic/g_game.c +++ b/src/heretic/g_game.c @@ -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; diff --git a/src/hexen/g_game.c b/src/hexen/g_game.c index 6d10dcfd..3593ffe2 100644 --- a/src/hexen/g_game.c +++ b/src/hexen/g_game.c @@ -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; diff --git a/src/strife/g_game.c b/src/strife/g_game.c index 8d074a1f..e0c0ae27 100644 --- a/src/strife/g_game.c +++ b/src/strife/g_game.c @@ -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]) { -- cgit v1.2.3