summaryrefslogtreecommitdiff
path: root/src/doom/g_game.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/doom/g_game.c')
-rw-r--r--src/doom/g_game.c184
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;