Merge pull request #1920 from ceski-1/weapon_switching

Weapon switching improvements
This commit is contained in:
ceski 2024-09-23 09:58:42 -07:00 committed by GitHub
commit 01a613880d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 147 additions and 65 deletions

View File

@ -223,6 +223,9 @@ typedef struct player_s
int num_visitedlevels;
level_t *visitedlevels;
// Last used weapon (last readyweapon).
weapontype_t lastweapon;
} player_t;

View File

@ -69,6 +69,7 @@ extern char *MAPNAME(int e, int m);
extern boolean modifiedgame;
extern boolean have_ssg;
#define ALLOW_SSG (gamemode == commercial || CRITICAL(have_ssg))
// compatibility with old engines (monster behavior, metrics, etc.)
extern int compatibility, default_compatibility; // killough 1/31/98

View File

@ -162,6 +162,7 @@ boolean padlook = false;
// killough 4/13/98: Make clock rate adjustable by scale factor
int realtic_clock_rate = 100;
static boolean doom_weapon_toggles;
static boolean full_weapon_cycle;
complevel_t force_complevel, default_complevel;
@ -241,7 +242,7 @@ static boolean WeaponSelectable(weapontype_t weapon)
{
// Can't select the super shotgun in Doom 1.
if (weapon == wp_supershotgun && !have_ssg)
if (weapon == wp_supershotgun && !ALLOW_SSG)
{
return false;
}
@ -318,6 +319,46 @@ static int G_NextWeapon(int direction)
return weapon_order_table[i].weapon_num;
}
static weapontype_t LastWeapon(void)
{
const weapontype_t weapon = players[consoleplayer].lastweapon;
if (weapon < wp_fist || weapon >= NUMWEAPONS || !WeaponSelectable(weapon))
{
return wp_nochange;
}
if (demo_compatibility && weapon == wp_supershotgun)
{
return wp_shotgun;
}
return weapon;
}
static weapontype_t WeaponSSG(void)
{
const player_t *player = &players[consoleplayer];
if (!ALLOW_SSG || !player->weaponowned[wp_supershotgun])
{
return wp_nochange;
}
if (!demo_compatibility)
{
return wp_supershotgun;
}
if (player->pendingweapon != wp_supershotgun
&& player->readyweapon != wp_supershotgun)
{
return wp_shotgun;
}
return wp_nochange;
}
// [FG] toggle demo warp mode
void G_EnableWarp(boolean warp)
{
@ -554,6 +595,57 @@ void G_PrepGyroTiccmd(void)
}
}
static void AdjustWeaponSelection(int *newweapon)
{
// killough 3/22/98: For network and demo consistency with the
// new weapons preferences, we must do the weapons switches here
// instead of in p_user.c. But for old demos we must do it in
// p_user.c according to the old rules. Therefore demo_compatibility
// determines where the weapons switch is made.
// killough 2/8/98:
// Allow user to switch to fist even if they have chainsaw.
// Switch to fist or chainsaw based on preferences.
// Switch to shotgun or SSG based on preferences.
//
// killough 10/98: make SG/SSG and Fist/Chainsaw
// weapon toggles optional
const player_t *player = &players[consoleplayer];
// only select chainsaw from '1' if it's owned, it's
// not already in use, and the player prefers it or
// the fist is already in use, or the player does not
// have the berserker strength.
if (*newweapon == wp_fist
&& player->weaponowned[wp_chainsaw]
&& player->readyweapon != wp_chainsaw
&& (player->readyweapon == wp_fist
|| !player->powers[pw_strength]
|| P_WeaponPreferred(wp_chainsaw, wp_fist)))
{
*newweapon = wp_chainsaw;
}
// Select SSG from '3' only if it's owned and the player
// does not have a shotgun, or if the shotgun is already
// in use, or if the SSG is not already in use and the
// player prefers it.
if (*newweapon == wp_shotgun && ALLOW_SSG
&& player->weaponowned[wp_supershotgun]
&& (!player->weaponowned[wp_shotgun]
|| player->readyweapon == wp_shotgun
|| (player->readyweapon != wp_supershotgun
&& P_WeaponPreferred(wp_supershotgun, wp_shotgun))))
{
*newweapon = wp_supershotgun;
}
// killough 2/8/98, 3/22/98 -- end of weapon selection changes
}
static boolean FilterDeathUseAction(void)
{
if (players[consoleplayer].playerstate & PST_DEAD)
@ -765,12 +857,22 @@ void G_BuildTiccmd(ticcmd_t* cmd)
boom_weapon_state_injection = false;
newweapon = P_SwitchWeapon(&players[consoleplayer]); // phares
}
else if (M_InputGameActive(input_lastweapon))
{
newweapon = LastWeapon();
}
else if (gamestate == GS_LEVEL && next_weapon != 0)
{
// [FG] prev/next weapon keys and buttons
newweapon = G_NextWeapon(next_weapon);
if (!demo_compatibility && !full_weapon_cycle)
{
AdjustWeaponSelection(&newweapon);
}
}
else
{ // phares 02/26/98: Added gamemode checks
// [FG] prev/next weapon keys and buttons
if (gamestate == GS_LEVEL && next_weapon != 0)
newweapon = G_NextWeapon(next_weapon);
else
newweapon =
M_InputGameActive(input_weapon1) ? wp_fist : // killough 5/2/98: reformatted
M_InputGameActive(input_weapon2) ? wp_pistol :
@ -780,53 +882,13 @@ void G_BuildTiccmd(ticcmd_t* cmd)
M_InputGameActive(input_weapon6) && gamemode != shareware ? wp_plasma :
M_InputGameActive(input_weapon7) && gamemode != shareware ? wp_bfg :
M_InputGameActive(input_weapon8) ? wp_chainsaw :
M_InputGameActive(input_weapon9) && !demo_compatibility && have_ssg ? wp_supershotgun :
M_InputGameActive(input_weapon9) ? WeaponSSG() :
wp_nochange;
// killough 3/22/98: For network and demo consistency with the
// new weapons preferences, we must do the weapons switches here
// instead of in p_user.c. But for old demos we must do it in
// p_user.c according to the old rules. Therefore demo_compatibility
// determines where the weapons switch is made.
// killough 2/8/98:
// Allow user to switch to fist even if they have chainsaw.
// Switch to fist or chainsaw based on preferences.
// Switch to shotgun or SSG based on preferences.
//
// killough 10/98: make SG/SSG and Fist/Chainsaw
// weapon toggles optional
if (!demo_compatibility && doom_weapon_toggles)
{
const player_t *player = &players[consoleplayer];
// only select chainsaw from '1' if it's owned, it's
// not already in use, and the player prefers it or
// the fist is already in use, or the player does not
// have the berserker strength.
if (newweapon==wp_fist && player->weaponowned[wp_chainsaw] &&
player->readyweapon!=wp_chainsaw &&
(player->readyweapon==wp_fist ||
!player->powers[pw_strength] ||
P_WeaponPreferred(wp_chainsaw, wp_fist)))
newweapon = wp_chainsaw;
// Select SSG from '3' only if it's owned and the player
// does not have a shotgun, or if the shotgun is already
// in use, or if the SSG is not already in use and the
// player prefers it.
if (newweapon == wp_shotgun && have_ssg &&
player->weaponowned[wp_supershotgun] &&
(!player->weaponowned[wp_shotgun] ||
player->readyweapon == wp_shotgun ||
(player->readyweapon != wp_supershotgun &&
P_WeaponPreferred(wp_supershotgun, wp_shotgun))))
newweapon = wp_supershotgun;
AdjustWeaponSelection(&newweapon);
}
// killough 2/8/98, 3/22/98 -- end of weapon selection changes
}
if (newweapon != wp_nochange)
@ -2914,6 +2976,7 @@ void G_PlayerReborn(int player)
p->usedown = p->attackdown = true; // don't do anything immediately
p->playerstate = PST_LIVE;
p->health = initial_health; // Ty 03/12/98 - use dehacked values
p->lastweapon = wp_fist;
p->readyweapon = p->pendingweapon = wp_pistol;
p->weaponowned[wp_fist] = true;
p->weaponowned[wp_pistol] = true;
@ -4706,6 +4769,9 @@ void G_BindWeapVariables(void)
M_BindBool("doom_weapon_toggles", &doom_weapon_toggles, NULL,
true, ss_weap, wad_no,
"Allow toggling between SG/SSG and Fist/Chainsaw");
M_BindBool("full_weapon_cycle", &full_weapon_cycle, NULL,
false, ss_weap, wad_no,
"Cycle through all weapons");
M_BindBool("player_bobbing", &default_player_bobbing, &player_bobbing,
true, ss_none, wad_no, "Physical player bobbing (affects compatibility)");

View File

@ -1006,7 +1006,7 @@ static void HU_widget_build_weapon (void)
break;
case retail:
case registered:
if (w >= wp_supershotgun && !have_ssg)
if (w >= wp_supershotgun && !ALLOW_SSG)
ok = 0;
break;
default:

View File

@ -541,7 +541,7 @@ static void cheat_fa()
// You can't own weapons that aren't in the game // phares 02/27/98
for (i=0;i<NUMWEAPONS;i++)
if (!(((i == wp_plasma || i == wp_bfg) && gamemode == shareware) ||
(i == wp_supershotgun && !have_ssg)))
(i == wp_supershotgun && !ALLOW_SSG)))
plyr->weaponowned[i] = true;
for (i=0;i<NUMAMMO;i++)
@ -1105,7 +1105,7 @@ static void cheat_keyxx(int key)
static void cheat_weap()
{ // Ty 03/27/98 - *not* externalized
displaymsg(have_ssg ? // killough 2/28/98
displaymsg(ALLOW_SSG ? // killough 2/28/98
"Weapon number 1-9" : "Weapon number 1-8");
}
@ -1113,7 +1113,7 @@ static void cheat_weapx(char *buf)
{
int w = *buf - '1';
if ((w==wp_supershotgun && !have_ssg) || // killough 2/28/98
if ((w==wp_supershotgun && !ALLOW_SSG) || // killough 2/28/98
((w==wp_bfg || w==wp_plasma) && gamemode==shareware))
return;

View File

@ -699,6 +699,7 @@ void M_BindInputVariables(void)
BIND_INPUT(input_weapon8, "Switch to weapon 8 (Chainsaw)");
BIND_INPUT(input_weapon9, "Switch to weapon 9 (Super Shotgun)");
BIND_INPUT(input_weapontoggle, "Switch between the two most-preferred weapons with ammo");
BIND_INPUT(input_lastweapon, "Switch to last used weapon");
BIND_INPUT(input_menu_reloadlevel, "Restart current level/demo");
BIND_INPUT(input_menu_nextlevel, "Go to next level");

View File

@ -56,6 +56,7 @@ enum
input_weapon8,
input_weapon9,
input_weapontoggle,
input_lastweapon,
input_menu_up,
input_menu_down,

View File

@ -1361,6 +1361,7 @@ static setup_menu_t keys_settings2[] = {
{"Chainsaw", S_INPUT, KB_X, M_SPC, {0}, m_scrn, input_weapon8},
{"SSG", S_INPUT, KB_X, M_SPC, {0}, m_scrn, input_weapon9},
{"Best", S_INPUT, KB_X, M_SPC, {0}, m_scrn, input_weapontoggle},
{"Last", S_INPUT, KB_X, M_SPC, {0}, m_scrn, input_lastweapon},
MI_GAP,
// [FG] prev/next weapon keys and buttons
{"Prev", S_INPUT, KB_X, M_SPC, {0}, m_scrn, input_prevweapon},
@ -1539,20 +1540,21 @@ static setup_menu_t weap_settings1[] = {
};
static setup_menu_t weap_settings2[] = {
{"1St Choice Weapon", S_WEAP | S_BOOM, OFF_CNTR_X, M_SPC, {"weapon_choice_1"}},
{"2Nd Choice Weapon", S_WEAP | S_BOOM, OFF_CNTR_X, M_SPC, {"weapon_choice_2"}},
{"3Rd Choice Weapon", S_WEAP | S_BOOM, OFF_CNTR_X, M_SPC, {"weapon_choice_3"}},
{"4Th Choice Weapon", S_WEAP | S_BOOM, OFF_CNTR_X, M_SPC, {"weapon_choice_4"}},
{"5Th Choice Weapon", S_WEAP | S_BOOM, OFF_CNTR_X, M_SPC, {"weapon_choice_5"}},
{"6Th Choice Weapon", S_WEAP | S_BOOM, OFF_CNTR_X, M_SPC, {"weapon_choice_6"}},
{"7Th Choice Weapon", S_WEAP | S_BOOM, OFF_CNTR_X, M_SPC, {"weapon_choice_7"}},
{"8Th Choice Weapon", S_WEAP | S_BOOM, OFF_CNTR_X, M_SPC, {"weapon_choice_8"}},
{"9Th Choice Weapon", S_WEAP | S_BOOM, OFF_CNTR_X, M_SPC, {"weapon_choice_9"}},
{"1St Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_1"}},
{"2Nd Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_2"}},
{"3Rd Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_3"}},
{"4Th Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_4"}},
{"5Th Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_5"}},
{"6Th Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_6"}},
{"7Th Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_7"}},
{"8Th Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_8"}},
{"9Th Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_9"}},
MI_GAP,
{"Use Weapon Toggles", S_ONOFF | S_BOOM, OFF_CNTR_X, M_SPC, {"doom_weapon_toggles"}},
{"Same Key Toggles Weapons", S_ONOFF | S_BOOM, M_X, M_SPC, {"doom_weapon_toggles"}},
{"Cycle Through All Weapons", S_ONOFF | S_BOOM, M_X, M_SPC, {"full_weapon_cycle"}},
MI_GAP,
// killough 8/8/98
{"Pre-Beta BFG", S_ONOFF | S_STRICT, OFF_CNTR_X, M_SPC, {"classic_bfg"}},
{"Pre-Beta BFG", S_ONOFF | S_STRICT, M_X, M_SPC, {"classic_bfg"}},
MI_END
};

View File

@ -236,7 +236,7 @@ static int P_SwitchWeaponMBF21(player_t *player)
checkweapon = wp_chainsaw;
break;
case 9:
if (have_ssg)
if (ALLOW_SSG)
checkweapon = wp_supershotgun;
break;
}
@ -315,7 +315,7 @@ int P_SwitchWeapon(player_t *player)
newweapon = wp_chainsaw;
break;
case 9:
if (player->weaponowned[wp_supershotgun] && have_ssg &&
if (player->weaponowned[wp_supershotgun] && ALLOW_SSG &&
player->ammo[am_shell] >= (demo_compatibility ? 3 : 2))
newweapon = wp_supershotgun;
break;
@ -588,6 +588,7 @@ void A_Lower(player_t *player, pspdef_t *psp)
if (player->pendingweapon < NUMWEAPONS || !mbf21)
{
player->lastweapon = player->readyweapon;
player->readyweapon = player->pendingweapon;
}

View File

@ -989,11 +989,15 @@ static void saveg_read_player_t(player_t *str)
level.map = saveg_read32();
array_push(str->visitedlevels, level);
}
// [Woof!]: weapontype_t lastweapon;
str->lastweapon = saveg_read_enum();
}
else
{
str->num_visitedlevels = 0;
array_clear(str->visitedlevels);
str->lastweapon = wp_nochange;
}
}
@ -1158,6 +1162,9 @@ static void saveg_write_player_t(player_t *str)
saveg_write32(level->episode);
saveg_write32(level->map);
}
// [Woof!]: weapontype_t lastweapon;
saveg_write_enum(str->lastweapon);
}

View File

@ -478,7 +478,7 @@ void P_PlayerThink (player_t* player)
(player->readyweapon != wp_chainsaw ||
!player->powers[pw_strength]))
newweapon = wp_chainsaw;
if (have_ssg &&
if (ALLOW_SSG &&
newweapon == wp_shotgun &&
player->weaponowned[wp_supershotgun] &&
player->readyweapon != wp_supershotgun)