diff options
Diffstat (limited to 'src/doom/g_game.c')
-rw-r--r-- | src/doom/g_game.c | 184 |
1 files changed, 164 insertions, 20 deletions
diff --git a/src/doom/g_game.c b/src/doom/g_game.c index 9b569594..ad7155a0 100644 --- a/src/doom/g_game.c +++ b/src/doom/g_game.c @@ -176,14 +176,37 @@ static int *weapon_keys[] = { &key_weapon8 }; +// Set to -1 or +1 to switch to the previous or next weapon. + +static int next_weapon = 0; + +// Used for prev/next weapon keys. + +static const struct +{ + weapontype_t weapon; + weapontype_t weapon_num; +} weapon_order_table[] = { + { wp_fist, wp_fist }, + { wp_chainsaw, wp_fist }, + { wp_pistol, wp_pistol }, + { wp_shotgun, wp_shotgun }, + { wp_supershotgun, wp_shotgun }, + { wp_chaingun, wp_chaingun }, + { wp_missile, wp_missile }, + { wp_plasma, wp_plasma }, + { wp_bfg, wp_bfg } +}; + #define SLOWTURNTICS 6 #define NUMKEYS 256 +#define MAX_JOY_BUTTONS 20 static boolean gamekeydown[NUMKEYS]; static int turnheld; // for accelerative turning -static boolean mousearray[4]; +static boolean mousearray[MAX_MOUSE_BUTTONS + 1]; static boolean *mousebuttons = &mousearray[1]; // allow [-1] // mouse values are used once @@ -197,8 +220,6 @@ static int dclicktime2; static boolean dclickstate2; static int dclicks2; -#define MAX_JOY_BUTTONS 20 - // joystick values are repeated static int joyxmove; static int joyymove; @@ -337,7 +358,63 @@ int G_CmdChecksum (ticcmd_t* cmd) return sum; } - + +static boolean WeaponSelectable(weapontype_t weapon) +{ + // Can't select a weapon if we don't own it. + + if (!players[consoleplayer].weaponowned[weapon]) + { + return false; + } + + // Can't select the fist if we have the chainsaw, unless + // we also have the berserk pack. + + if (weapon == wp_fist + && players[consoleplayer].weaponowned[wp_chainsaw] + && !players[consoleplayer].powers[pw_strength]) + { + return false; + } + + return true; +} + +static int G_NextWeapon(int direction) +{ + weapontype_t weapon; + int i; + + // Find index in the table. + + if (players[consoleplayer].pendingweapon == wp_nochange) + { + weapon = players[consoleplayer].readyweapon; + } + else + { + weapon = players[consoleplayer].pendingweapon; + } + + for (i=0; i<arrlen(weapon_order_table); ++i) + { + if (weapon_order_table[i].weapon == weapon) + { + break; + } + } + + // Switch weapon. + + do + { + i += direction; + i = (i + arrlen(weapon_order_table)) % arrlen(weapon_order_table); + } while (!WeaponSelectable(weapon_order_table[i].weapon)); + + return weapon_order_table[i].weapon_num; +} // // G_BuildTiccmd @@ -465,20 +542,34 @@ void G_BuildTiccmd (ticcmd_t* cmd) dclicks = 0; } - // chainsaw overrides + // If the previous or next weapon button is pressed, the + // next_weapon variable is set to change weapons when + // we generate a ticcmd. Choose a new weapon. - for (i=0; i<arrlen(weapon_keys); ++i) + if (next_weapon != 0) { - int key = *weapon_keys[i]; + i = G_NextWeapon(next_weapon); + cmd->buttons |= BT_CHANGE; + cmd->buttons |= i << BT_WEAPONSHIFT; + next_weapon = 0; + } + else + { + // Check weapon keys. - if (gamekeydown[key]) + for (i=0; i<arrlen(weapon_keys); ++i) { - cmd->buttons |= BT_CHANGE; - cmd->buttons |= i<<BT_WEAPONSHIFT; - break; + int key = *weapon_keys[i]; + + if (gamekeydown[key]) + { + cmd->buttons |= BT_CHANGE; + cmd->buttons |= i<<BT_WEAPONSHIFT; + break; + } } } - + // mouse if (mousebuttons[mousebforward]) { @@ -657,7 +748,6 @@ void G_DoLoadLevel (void) players[consoleplayer].message = "Press escape to quit."; } } - static void SetJoyButtons(unsigned int buttons_mask) { @@ -665,10 +755,54 @@ static void SetJoyButtons(unsigned int buttons_mask) for (i=0; i<MAX_JOY_BUTTONS; ++i) { - joybuttons[i] = (buttons_mask & (1 << i)) != 0; + int button_on = (buttons_mask & (1 << i)) != 0; + + // Detect button press: + + if (!joybuttons[i] && button_on) + { + // Weapon cycling: + + if (i == joybprevweapon) + { + next_weapon = -1; + } + else if (i == joybnextweapon) + { + next_weapon = 1; + } + } + + joybuttons[i] = button_on; } } - + +static void SetMouseButtons(unsigned int buttons_mask) +{ + int i; + + for (i=0; i<MAX_MOUSE_BUTTONS; ++i) + { + unsigned int button_on = (buttons_mask & (1 << i)) != 0; + + // Detect button press: + + if (!mousebuttons[i] && button_on) + { + if (i == mousebprevweapon) + { + next_weapon = -1; + } + else if (i == mousebnextweapon) + { + next_weapon = 1; + } + } + + mousebuttons[i] = button_on; + } +} + // // G_Responder // Get info needed to make ticcmd_ts for the players. @@ -677,7 +811,7 @@ boolean G_Responder (event_t* ev) { // allow spy mode changes even during the demo if (gamestate == GS_LEVEL && ev->type == ev_keydown - && ev->data1 == KEY_F12 && (singledemo || !deathmatch) ) + && ev->data1 == key_spy && (singledemo || !deathmatch) ) { // spy mode do @@ -737,6 +871,18 @@ boolean G_Responder (event_t* ev) testcontrols_mousespeed = abs(ev->data2); } + // If the next/previous weapon keys are pressed, set the next_weapon + // variable to change weapons when the next ticcmd is generated. + + if (ev->type == ev_keydown && ev->data1 == key_prevweapon) + { + next_weapon = -1; + } + else if (ev->type == ev_keydown && ev->data1 == key_nextweapon) + { + next_weapon = 1; + } + switch (ev->type) { case ev_keydown: @@ -757,9 +903,7 @@ boolean G_Responder (event_t* ev) return false; // always let key up events filter down case ev_mouse: - mousebuttons[0] = ev->data1 & 1; - mousebuttons[1] = ev->data1 & 2; - mousebuttons[2] = ev->data1 & 4; + SetMouseButtons(ev->data1); mousex = ev->data2*(mouseSensitivity+5)/10; mousey = ev->data3*(mouseSensitivity+5)/10; return true; // eat events @@ -1784,7 +1928,7 @@ void G_WriteDemoTiccmd (ticcmd_t* cmd) { byte *demo_start; - if (gamekeydown['q']) // press q to end demo recording + if (gamekeydown[key_demo_quit]) // press q to end demo recording G_CheckDemoStatus (); demo_start = demo_p; |