From 76811a18810c8c055e41b8e2b94d7046fffcd5a1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 24 Aug 2020 20:34:18 +0200 Subject: [PATCH] - InputState cleanup This removes most of the InputState class because it is no longer used. The only remaining places still checking scan codes are the modifiers for sizeup and sizedown. All the rest was remapped to safer methods. The multiplayer taunts are currently inoperable, they will need support of shift-bindings to get proper support. --- source/blood/src/blood.cpp | 2 +- source/blood/src/controls.cpp | 28 +------ source/blood/src/endgame.cpp | 1 - source/core/gamecontrol.cpp | 36 ++++++++- source/core/gamecontrol.h | 6 +- source/core/inputstate.cpp | 33 ++------ source/core/inputstate.h | 130 +------------------------------- source/exhumed/src/2d.cpp | 10 +-- source/exhumed/src/input.cpp | 3 +- source/exhumed/src/player.cpp | 3 - source/games/duke/src/input.cpp | 101 +++++++++---------------- source/sw/src/input.cpp | 47 +----------- 12 files changed, 90 insertions(+), 310 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 5527ad6a5..ea8738da3 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -324,7 +324,7 @@ void PreloadCache(void) int cnt = 0; int percentDisplayed = -1; - for (int i = 0; i < kMaxTiles && !inputState.GetKeyStatus(sc_Space); i++) + for (int i = 0; i < kMaxTiles; i++) { if (TestBitString(gotpic, i)) { diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index cb9c33edd..023fe8961 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -70,10 +70,7 @@ int gViewLookRecenter; void LocalKeys(void) { - bool alt = inputState.AltPressed(); - bool ctrl = inputState.CtrlPressed(); - bool shift = inputState.ShiftPressed(); - if (buttonMap.ButtonDown(gamefunc_Third_Person_View) && !alt && !shift) + if (buttonMap.ButtonDown(gamefunc_Third_Person_View)) { buttonMap.ClearButton(gamefunc_Third_Person_View); if (gViewPos > VIEWPOS_0) @@ -105,27 +102,6 @@ void LocalKeys(void) gView = &gPlayer[gViewIndex]; } } - char key; - if ((key = inputState.keyGetScan()) != 0) - { - if ((alt || shift) && gGameOptions.nGameType > 0 && key >= sc_F1 && key <= sc_F10) - { - char fk = key - sc_F1; - if (alt) - { - sndStartSample(4400 + fk, 128, 1, 0); - //netBroadcastTaunt(myconnectindex, fk); - } - else - { - // todo: Open chat editor with the specified text - //gPlayerMsg.Set(*CombatMacros[fk]); - //gPlayerMsg.Send(); - } - buttonMap.ClearButton(gamefunc_Third_Person_View); - return; - } - } } @@ -390,7 +366,7 @@ void registerinputcommands() C_RegisterFunction("slot", "slot : select a weapon from the given slot (1-10)", ccmd_slot); C_RegisterFunction("weapprev", nullptr, [](CCmdFuncPtr)->int { if (gPlayer[myconnectindex].nextWeapon == 0) BitsToSend.prevWeapon = 1; return CCMD_OK; }); C_RegisterFunction("weapnext", nullptr, [](CCmdFuncPtr)->int { if (gPlayer[myconnectindex].nextWeapon == 0) BitsToSend.nextWeapon = 1; return CCMD_OK; }); - C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend.pause = 1; return CCMD_OK; }); + C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend.pause = 1; sendPause = true; return CCMD_OK; }); C_RegisterFunction("proximitybombs", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = 11; return CCMD_OK; }); C_RegisterFunction("remotebombs", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = 12; return CCMD_OK; }); C_RegisterFunction("jumpboots", nullptr, [](CCmdFuncPtr)->int { UsesToSend.useJumpBoots = 1; return CCMD_OK; }); diff --git a/source/blood/src/endgame.cpp b/source/blood/src/endgame.cpp index 9046b7aa6..83fc22494 100644 --- a/source/blood/src/endgame.cpp +++ b/source/blood/src/endgame.cpp @@ -146,7 +146,6 @@ void CEndGameMgr::Setup(void) EndLevel(); Mus_Stop(); sndStartSample(268, 128, -1, false); - inputState.keyFlushScans(); } extern int gInitialNetPlayers; diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 6f8e6c033..09a5677bb 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -100,6 +100,7 @@ static ClockTicks lastototalclk; static uint64_t elapsedTime; static uint64_t lastTime; +bool sendPause; int automapMode; bool automapFollow; @@ -1212,9 +1213,9 @@ void updatePauseStatus() paused = 0; } - if (inputState.GetKeyStatus(sc_Pause)) + if (sendPause) { - inputState.ClearKeyStatus(sc_Pause); + sendPause = false; paused = pausedWithKey ? 0 : 2; pausedWithKey = !!paused; } @@ -1227,3 +1228,34 @@ bool OkForLocalization(FTextureID texnum, const char* substitute) { return false; } + + +// Mainly a dummy. +CCMD(taunt) +{ + if (argv.argc() > 2) + { + int taunt = atoi(argv[1]); + int mode = atoi(argv[2]); + + // In a ZDoom-style protocol this should be sent: + // Net_WriteByte(DEM_TAUNT); + // Net_WriteByte(taunt); + // Net_WriteByte(mode); + if (mode == 1) + { + // todo: + //gi->PlayTaunt(taunt); + // Duke: + // startrts(taunt, 1) + // Blood: + // sndStartSample(4400 + taunt, 128, 1, 0); + // SW: + // PlaySoundRTS(taunt); + // Exhumed does not implement RTS, should be like Duke + // + } + Printf(PRINT_NOTIFY, "%s", **CombatMacros[taunt - 1]); + + } +} diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index c76fc4d72..140305b91 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -220,8 +220,4 @@ enum AM_Mode }; extern int automapMode; extern bool automapFollow; - -inline bool automapControlsActive() -{ - return automapMode != am_off; -} +extern bool sendPause; diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index b2b0bef64..7e08d456f 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -80,25 +80,6 @@ void InputState::GetMouseDelta(ControlInfo * info) } -//========================================================================== -// -// -// -//========================================================================== - -void InputState::keySetState(int32_t key, int32_t state) -{ - KeyStatus[key] = (uint8_t)state; - - if (state) - { - g_keyFIFO[g_keyFIFOend] = key; - g_keyFIFO[(g_keyFIFOend + 1) & (KEYFIFOSIZ - 1)] = state; - g_keyFIFOend = ((g_keyFIFOend + 2) & (KEYFIFOSIZ - 1)); - } -} - - //========================================================================== // // @@ -109,12 +90,11 @@ void InputState::AddEvent(const event_t *ev) { if (ev->type == EV_KeyDown || ev->type == EV_KeyUp) { - keySetState(ev->data1, ev->type == EV_KeyDown); - if (ev->data2 && ev->type == EV_KeyDown) - { - g_keyAsciiFIFO[g_keyAsciiEnd] = (char16_t)ev->data2; - g_keyAsciiEnd = ((g_keyAsciiEnd + 1) & (KEYFIFOSIZ - 1)); - } + int key = ev->data1; + bool state = ev->type == EV_KeyDown; + KeyStatus[key] = (uint8_t)state; + if (state && !(key > KEY_LASTJOYBUTTON && key < KEY_PAD_LTHUMB_RIGHT)) + AnyKeyStatus = true; } } @@ -127,8 +107,7 @@ void InputState::AddEvent(const event_t *ev) void InputState::ClearAllInput() { memset(KeyStatus, 0, sizeof(KeyStatus)); - keyFlushChars(); - keyFlushScans(); + AnyKeyStatus = false; buttonMap.ResetButtonStates(); // this is important. If all input is cleared, the buttons must be cleared as well. gi->clearlocalinputstate(); // also clear game local input state. } diff --git a/source/core/inputstate.h b/source/core/inputstate.h index add8dbd18..22f0d5c24 100644 --- a/source/core/inputstate.h +++ b/source/core/inputstate.h @@ -13,9 +13,6 @@ #include "gamecvars.h" -typedef uint16_t kb_scancode; -// This encapsulates the entire game-readable input state which previously was spread out across several files. - struct ControlInfo { float dx; @@ -31,148 +28,32 @@ struct ControlInfo class InputState { - enum - { - KEYFIFOSIZ = 64, - }; - - enum EAction - { - Action_Pause = 1, - }; - uint8_t KeyStatus[NUM_KEYS]; - - kb_scancode g_keyFIFO[KEYFIFOSIZ]; - char16_t g_keyAsciiFIFO[KEYFIFOSIZ]; - uint8_t g_keyFIFOpos; - uint8_t g_keyFIFOend; - uint8_t g_keyAsciiPos; - uint8_t g_keyAsciiEnd; - + bool AnyKeyStatus; vec2f_t g_mousePos; - void keySetState(int32_t key, int32_t state); - public: - uint8_t GetKeyStatus(int key) - { - return KeyStatus[key]; - } - - void ClearKeyStatus(int key) - { - KeyStatus[key] = 0; - } - - bool AltPressed() - { - return KeyStatus[sc_LeftAlt] || KeyStatus[sc_RightAlt]; - } - - bool CtrlPressed() - { - return KeyStatus[sc_LeftControl] || KeyStatus[sc_RightControl]; - } - - bool WinPressed() - { - return KeyStatus[sc_LeftWin] || KeyStatus[sc_RightWin]; - } - bool ShiftPressed() { return KeyStatus[sc_LeftShift] || KeyStatus[sc_RightShift]; } - - bool EscapePressed() - { - return !!KeyStatus[sc_Escape]; - } - - void SetBindsEnabled(bool on) - { - } - - bool keyBufferWaiting() - { - return (g_keyAsciiPos != g_keyAsciiEnd); - } - - int keyBufferFull(void) - { - return ((g_keyAsciiEnd + 1) & (KEYFIFOSIZ - 1)) == g_keyAsciiPos; - } - - kb_scancode keyGetScan() - { - if (g_keyFIFOpos == g_keyFIFOend) - return 0; - - auto const c = g_keyFIFO[g_keyFIFOpos]; - g_keyFIFOpos = ((g_keyFIFOpos + 2) & (KEYFIFOSIZ - 1)); - return c; - } - - void keyFlushScans(void) - { - memset(&g_keyFIFO, 0, sizeof(g_keyFIFO)); - g_keyFIFOpos = g_keyFIFOend = 0; - } - - // - // character-based input functions - // - char keyGetChar(void) - { - if (g_keyAsciiPos == g_keyAsciiEnd) - return 0; - - char const c = g_keyAsciiFIFO[g_keyAsciiPos]; - g_keyAsciiPos = ((g_keyAsciiPos + 1) & (KEYFIFOSIZ - 1)); - - return c; - } - - void keyFlushChars(void) - { - memset(&g_keyAsciiFIFO, 0, sizeof(g_keyAsciiFIFO)); - g_keyAsciiPos = g_keyAsciiEnd = 0; - } - - inline bool UnboundKeyPressed(int scan) - { - return (GetKeyStatus(scan) != 0 && Bindings.GetBind(scan) == nullptr); - } void AddEvent(const event_t* ev); - void MouseSetPos(float x, float y) - { - g_mousePos = { x, y }; - } void MouseAddToPos(float x, float y) { g_mousePos.x += x; g_mousePos.y += y; } - bool gamePadActive() - { - // fixme: This needs to be tracked. - return false; - } void GetMouseDelta(ControlInfo* info); void ClearAllInput(); bool CheckAllInput() { - int res; - do - res = keyGetScan(); - while (res > KEY_LASTJOYBUTTON && res < KEY_PAD_LTHUMB_RIGHT); // Controller movement events should not register here. - ClearAllInput(); + bool res = AnyKeyStatus; + AnyKeyStatus = false; return res; } }; @@ -181,8 +62,3 @@ extern InputState inputState; void CONTROL_GetInput(ControlInfo* info); int32_t handleevents(void); - - -#define WIN_IS_PRESSED ( inputState.WinPressed() ) -#define ALT_IS_PRESSED ( inputState.AltPressed() ) -#define SHIFTS_IS_PRESSED ( inputState.ShiftPressed() ) diff --git a/source/exhumed/src/2d.cpp b/source/exhumed/src/2d.cpp index b1948fe67..9375625a2 100644 --- a/source/exhumed/src/2d.cpp +++ b/source/exhumed/src/2d.cpp @@ -760,9 +760,9 @@ public: bool ProcessInput() override { - if (inputState.GetKeyStatus(sc_UpArrow)) + if (buttonMap.ButtonDown(gamefunc_Move_Forward)) { - inputState.ClearKeyStatus(sc_UpArrow); + buttonMap.ClearButton(gamefunc_Move_Forward); if (curYPos == destYPos && nLevelNew <= nLevelBest) { @@ -783,10 +783,10 @@ public: return true; } - if (inputState.GetKeyStatus(sc_DownArrow)) + if (buttonMap.ButtonDown(gamefunc_Move_Backward)) { - inputState.ClearKeyStatus(sc_DownArrow); - + buttonMap.ClearButton(gamefunc_Move_Backward); + if (curYPos == destYPos && nLevelNew > 0) { nLevelNew--; diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index afb44910e..c94e115cb 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "aistuff.h" #include "status.h" #include "view.h" +#include "gamecontrol.h" #include BEGIN_PS_NS @@ -204,7 +205,7 @@ int ccmd_centerview(CCmdFuncPtr parm); void registerinputcommands() { C_RegisterFunction("slot", "slot : select a weapon from the given slot (1-10)", ccmd_slot); - //C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_PAUSE; return CCMD_OK; }); + C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { /*BitsToSend |= SKB_PAUSE;*/ sendPause = true; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, ccmd_centerview); C_RegisterFunction("invprev", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) SetPrevItem(nLocalPlayer); return CCMD_OK; }); C_RegisterFunction("invnext", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) SetNextItem(nLocalPlayer); return CCMD_OK; }); diff --git a/source/exhumed/src/player.cpp b/source/exhumed/src/player.cpp index ebfd2f63e..d974dfad5 100644 --- a/source/exhumed/src/player.cpp +++ b/source/exhumed/src/player.cpp @@ -2715,9 +2715,6 @@ do_default_b: { EndLevel = true; } - else { - //inputState.keySetState(32, 1); // Huh, what? - } DestroyItemAnim(nValB); mydeletesprite(nValB); diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 5731d5369..73e26e49d 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -35,6 +35,7 @@ source as it is released. #include "ns.h" #include "global.h" +#include "gamecontrol.h" BEGIN_DUKE_NS @@ -91,79 +92,45 @@ void nonsharedkeys(void) FTA(QUOTE_WEAPON_MODE_OFF - ud.showweapons, &ps[screenpeek]); } - // Fixme: This really should be done via CCMD, not via hard coded key checks - but that needs alternative Shift and Alt bindings. - if (SHIFTS_IS_PRESSED || ALT_IS_PRESSED) + if (buttonMap.ButtonDown(gamefunc_Third_Person_View)) { - int taunt = 0; - - // NOTE: sc_F1 .. sc_F10 are contiguous. sc_F11 is not sc_F10+1. - for (int j = sc_F1; j <= sc_F10; j++) - if (inputState.UnboundKeyPressed(j)) - { - inputState.ClearKeyStatus(j); - taunt = j - sc_F1 + 1; - break; - } - - if (taunt) + buttonMap.ClearButton(gamefunc_Third_Person_View); + + if (!isRRRA() || (!ps[myconnectindex].OnMotorcycle && !ps[myconnectindex].OnBoat)) { - if (SHIFTS_IS_PRESSED) - { - Printf(PRINT_NOTIFY, "%s", **CombatMacros[taunt - 1]); - //Net_SendTaunt(taunt); - return; - } - - if (startrts(taunt, 1)) - { - //Net_SendRTS(taunt); - return; - } - } - } - - if (!ALT_IS_PRESSED && !SHIFTS_IS_PRESSED) - { - if (buttonMap.ButtonDown(gamefunc_Third_Person_View)) - { - buttonMap.ClearButton(gamefunc_Third_Person_View); - - if (!isRRRA() || (!ps[myconnectindex].OnMotorcycle && !ps[myconnectindex].OnBoat)) - { - if (ps[myconnectindex].over_shoulder_on) - ps[myconnectindex].over_shoulder_on = 0; - else - { - ps[myconnectindex].over_shoulder_on = 1; - cameradist = 0; - cameraclock = (int)totalclock; - } - FTA(QUOTE_VIEW_MODE_OFF + ps[myconnectindex].over_shoulder_on, &ps[myconnectindex]); - } - } - - if (automapMode != am_off) - { - int j; - if (nonsharedtimer > 0 || totalclock < nonsharedtimer) - { - j = (int)totalclock - nonsharedtimer; - nonsharedtimer += j; - } + if (ps[myconnectindex].over_shoulder_on) + ps[myconnectindex].over_shoulder_on = 0; else { - j = 0; - nonsharedtimer = (int)totalclock; + ps[myconnectindex].over_shoulder_on = 1; + cameradist = 0; + cameraclock = (int)totalclock; } - - if (buttonMap.ButtonDown(gamefunc_Enlarge_Screen)) - ps[myconnectindex].zoom += mulscale6(j, max(ps[myconnectindex].zoom, 256)); - if (buttonMap.ButtonDown(gamefunc_Shrink_Screen)) - ps[myconnectindex].zoom -= mulscale6(j, max(ps[myconnectindex].zoom, 256)); - - ps[myconnectindex].zoom = clamp(ps[myconnectindex].zoom, 48, 2048); + FTA(QUOTE_VIEW_MODE_OFF + ps[myconnectindex].over_shoulder_on, &ps[myconnectindex]); } } + + if (automapMode != am_off) + { + int j; + if (nonsharedtimer > 0 || totalclock < nonsharedtimer) + { + j = (int)totalclock - nonsharedtimer; + nonsharedtimer += j; + } + else + { + j = 0; + nonsharedtimer = (int)totalclock; + } + + if (buttonMap.ButtonDown(gamefunc_Enlarge_Screen)) + ps[myconnectindex].zoom += mulscale6(j, max(ps[myconnectindex].zoom, 256)); + if (buttonMap.ButtonDown(gamefunc_Shrink_Screen)) + ps[myconnectindex].zoom -= mulscale6(j, max(ps[myconnectindex].zoom, 256)); + + ps[myconnectindex].zoom = clamp(ps[myconnectindex].zoom, 48, 2048); + } } //--------------------------------------------------------------------------- @@ -1240,7 +1207,7 @@ void registerinputcommands() C_RegisterFunction("slot", "slot : select a weapon from the given slot (1-10)", ccmd_slot); C_RegisterFunction("weapprev", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = 11; return CCMD_OK; }); C_RegisterFunction("weapnext", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = 12; return CCMD_OK; }); - C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_PAUSE; return CCMD_OK; }); + C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_PAUSE; sendPause = true; return CCMD_OK; }); C_RegisterFunction("steroids", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_STEROIDS; return CCMD_OK; }); C_RegisterFunction("nightvision", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_NIGHTVISION; return CCMD_OK; }); C_RegisterFunction("medkit", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_MEDKIT; return CCMD_OK; }); diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index f2ae13e25..cace1e61f 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -44,50 +44,12 @@ int inv_hotkey = 0; void FunctionKeys(PLAYERp pp) { - static int rts_delay = 0; - int fn_key = 0; - - rts_delay++; - - if (inputState.GetKeyStatus(sc_F1)) { fn_key = 1; } - if (inputState.GetKeyStatus(sc_F2)) { fn_key = 2; } - if (inputState.GetKeyStatus(sc_F3)) { fn_key = 3; } - if (inputState.GetKeyStatus(sc_F4)) { fn_key = 4; } - if (inputState.GetKeyStatus(sc_F5)) { fn_key = 5; } - if (inputState.GetKeyStatus(sc_F6)) { fn_key = 6; } - if (inputState.GetKeyStatus(sc_F7)) { fn_key = 7; } - if (inputState.GetKeyStatus(sc_F8)) { fn_key = 8; } - if (inputState.GetKeyStatus(sc_F9)) { fn_key = 9; } - if (inputState.GetKeyStatus(sc_F10)) { fn_key = 10; } - - if (inputState.AltPressed()) - { - if (rts_delay > 16 && fn_key && !adult_lockout) - { - inputState.ClearKeyStatus(sc_F1 + fn_key - 1); - rts_delay = 0; - PlaySoundRTS(fn_key); - } - - return; - } - - if (inputState.ShiftPressed()) - { - if (fn_key) - { - inputState.ClearKeyStatus(sc_F1 + fn_key - 1); - } - - return; - } - // F7 VIEW control if (buttonMap.ButtonDown(gamefunc_Third_Person_View)) { buttonMap.ClearButton(gamefunc_Third_Person_View); - if (SHIFTS_IS_PRESSED) + if (inputState.ShiftPressed()) { if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE)) pp->view_outside_dang = NORM_ANGLE(pp->view_outside_dang + 256); @@ -367,11 +329,6 @@ getinput(SW_PACKET *loc, SWBOOL tied) } #endif } - else if (inputState.GetKeyStatus(sc_Pause)) - { - SET_LOC_KEY(loc->bits, SK_PAUSE, true); - inputState.ClearKeyStatus(sc_Pause); - } SET_LOC_KEY(loc->bits, SK_RUN, buttonMap.ButtonDown(gamefunc_Run)); SET_LOC_KEY(loc->bits, SK_SHOOT, buttonMap.ButtonDown(gamefunc_Fire)); @@ -543,7 +500,7 @@ void registerinputcommands() C_RegisterFunction("slot", "slot : select a weapon from the given slot (1-10)", ccmd_slot); C_RegisterFunction("weapprev", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = -2; return CCMD_OK; }); C_RegisterFunction("weapnext", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = -1; return CCMD_OK; }); - C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_PAUSE); return CCMD_OK; }); + C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_PAUSE); sendPause = true; return CCMD_OK; }); C_RegisterFunction("smoke_bomb", nullptr, [](CCmdFuncPtr)->int { inv_hotkey = INVENTORY_CLOAK + 1; return CCMD_OK; }); C_RegisterFunction("nightvision", nullptr, [](CCmdFuncPtr)->int { inv_hotkey = INVENTORY_NIGHT_VISION + 1; return CCMD_OK; }); C_RegisterFunction("medkit", nullptr, [](CCmdFuncPtr)->int { inv_hotkey = INVENTORY_MEDKIT + 1; return CCMD_OK; });