| 817 | } |
| 818 | |
| 819 | int CPlayer::Pause(int State, bool Force) |
| 820 | { |
| 821 | if(State < PAUSE_NONE || State > PAUSE_SPEC) // Invalid pause state passed |
| 822 | return 0; |
| 823 | |
| 824 | if(!m_pCharacter) |
| 825 | return 0; |
| 826 | |
| 827 | char aBuf[128]; |
| 828 | if(State != m_Paused) |
| 829 | { |
| 830 | // Get to wanted state |
| 831 | switch(State) |
| 832 | { |
| 833 | case PAUSE_PAUSED: |
| 834 | case PAUSE_NONE: |
| 835 | if(m_pCharacter->IsPaused()) // First condition might be unnecessary |
| 836 | { |
| 837 | if(!Force && m_LastPause && m_LastPause + (int64_t)g_Config.m_SvSpecFrequency * Server()->TickSpeed() > Server()->Tick()) |
| 838 | { |
| 839 | GameServer()->SendChatTarget(m_ClientId, "Can't /spec that quickly."); |
| 840 | return m_Paused; // Do not update state. Do not collect $200 |
| 841 | } |
| 842 | m_pCharacter->Pause(false); |
| 843 | m_ViewPos = m_pCharacter->m_Pos; |
| 844 | GameServer()->CreatePlayerSpawn(m_pCharacter->m_Pos, GameServer()->m_pController->GetMaskForPlayerWorldEvent(m_ClientId)); |
| 845 | } |
| 846 | [[fallthrough]]; |
| 847 | case PAUSE_SPEC: |
| 848 | if(g_Config.m_SvPauseMessages) |
| 849 | { |
| 850 | str_format(aBuf, sizeof(aBuf), (State > PAUSE_NONE) ? "'%s' speced" : "'%s' resumed", Server()->ClientName(m_ClientId)); |
| 851 | GameServer()->SendChat(-1, TEAM_ALL, aBuf); |
| 852 | } |
| 853 | break; |
| 854 | } |
| 855 | |
| 856 | // Update state |
| 857 | m_Paused = State; |
| 858 | m_LastPause = Server()->Tick(); |
| 859 | |
| 860 | // Sixup needs a teamchange |
| 861 | protocol7::CNetMsg_Sv_Team Msg; |
| 862 | Msg.m_ClientId = m_ClientId; |
| 863 | Msg.m_CooldownTick = Server()->Tick(); |
| 864 | Msg.m_Silent = true; |
| 865 | Msg.m_Team = m_Paused ? protocol7::TEAM_SPECTATORS : m_Team; |
| 866 | |
| 867 | GameServer()->Server()->SendPackMsg(&Msg, MSGFLAG_VITAL | MSGFLAG_NORECORD, m_ClientId); |
| 868 | } |
| 869 | |
| 870 | return m_Paused; |
| 871 | } |
| 872 | |
| 873 | int CPlayer::ForcePause(int Time) |
| 874 | { |