| 1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
| 2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
| 3 | #ifndef GAME_SERVER_PLAYER_H |
| 4 | #define GAME_SERVER_PLAYER_H |
| 5 | |
| 6 | #include "teeinfo.h" |
| 7 | |
| 8 | #include <base/vmath.h> |
| 9 | |
| 10 | #include <engine/shared/protocol.h> |
| 11 | |
| 12 | #include <game/alloc.h> |
| 13 | #include <game/server/save.h> |
| 14 | |
| 15 | #include <memory> |
| 16 | #include <optional> |
| 17 | |
| 18 | class CCharacter; |
| 19 | class CGameContext; |
| 20 | class IServer; |
| 21 | struct CNetObj_PlayerInput; |
| 22 | struct CScorePlayerResult; |
| 23 | |
| 24 | // player object |
| 25 | class CPlayer |
| 26 | { |
| 27 | MACRO_ALLOC_POOL_ID() |
| 28 | |
| 29 | public: |
| 30 | CPlayer(CGameContext *pGameServer, uint32_t UniqueClientId, int ClientId, int Team); |
| 31 | ~CPlayer(); |
| 32 | |
| 33 | void Reset(); |
| 34 | |
| 35 | void TryRespawn(); |
| 36 | void Respawn(bool WeakHook = false); // with WeakHook == true the character will be spawned after all calls of Tick from other Players |
| 37 | CCharacter *ForceSpawn(vec2 Pos); // required for loading savegames |
| 38 | void SetTeam(int Team, bool DoChatMsg = true); |
| 39 | int GetTeam() const { return m_Team; } |
| 40 | int GetCid() const { return m_ClientId; } |
| 41 | uint32_t GetUniqueCid() const { return m_UniqueClientId; } |
| 42 | int GetClientVersion() const; |
| 43 | bool SetTimerType(int TimerType); |
| 44 | |
| 45 | void Tick(); |
| 46 | void PostTick(); |
| 47 | |
| 48 | // will be called after all Tick and PostTick calls from other players |
| 49 | void PostPostTick(); |
| 50 | void Snap(int SnappingClient); |
| 51 | void FakeSnap(); |
| 52 | |
| 53 | void OnDirectInput(const CNetObj_PlayerInput *pNewInput); |
| 54 | void OnPredictedInput(const CNetObj_PlayerInput *pNewInput); |
| 55 | void OnPredictedEarlyInput(const CNetObj_PlayerInput *pNewInput); |
| 56 | void OnDisconnect(); |
| 57 | |
| 58 | void KillCharacter(int Weapon = WEAPON_GAME, bool SendKillMsg = true); |
| 59 | CCharacter *GetCharacter(); |
| 60 | const CCharacter *GetCharacter() const; |
| 61 | |
| 62 | void SpectatePlayerName(const char *pName); |
| 63 | |
| 64 | //--------------------------------------------------------- |
| 65 | // this is used for snapping so we know how we can clip the view for the player |
| 66 | vec2 m_ViewPos; |
| 67 | int m_TuneZone; |
| 68 | int m_TuneZoneOld; |
| 69 | |
| 70 | // states if the client is chatting, accessing a menu etc. |
| 71 | int m_PlayerFlags; |
| 72 | |
| 73 | // used for snapping to just update latency if the scoreboard is active |
| 74 | int m_aCurLatency[MAX_CLIENTS]; |
| 75 | |
| 76 | int m_SentSnaps = 0; |
| 77 | |
| 78 | int SpectatorId() const { return m_SpectatorId; } |
| 79 | void SetSpectatorId(int Id); |
| 80 | |
| 81 | bool m_IsReady; |
| 82 | |
| 83 | // |
| 84 | int m_Vote; |
| 85 | int m_VotePos; |
| 86 | // |
| 87 | int m_LastVoteCall; |
| 88 | int m_LastVoteTry; |
| 89 | int m_LastChat; |
| 90 | int m_LastSetTeam; |
| 91 | int m_LastSetSpectatorMode; |
| 92 | int m_LastChangeInfo; |
| 93 | int m_LastEmote; |
| 94 | int m_LastEmoteGlobal; |
| 95 | int m_LastKill; |
| 96 | int m_aLastCommands[4]; |
| 97 | int m_LastCommandPos; |
| 98 | int m_LastWhisperTo; |
| 99 | int m_LastInvited; |
| 100 | |
| 101 | int m_SendVoteIndex; |
| 102 | |
| 103 | CTeeInfo m_TeeInfos; |
| 104 | |
| 105 | int m_DieTick; |
| 106 | int m_PreviousDieTick; |
| 107 | std::optional<int> m_Score; |
| 108 | int m_JoinTick; |
| 109 | int m_LastActionTick; |
| 110 | int m_TeamChangeTick; |
| 111 | |
| 112 | // network latency calculations |
| 113 | struct |
| 114 | { |
| 115 | int m_Accum; |
| 116 | int m_AccumMin; |
| 117 | int m_AccumMax; |
| 118 | int m_Avg; |
| 119 | int m_Min; |
| 120 | int m_Max; |
| 121 | } m_Latency; |
| 122 | |
| 123 | private: |
| 124 | const uint32_t m_UniqueClientId; |
| 125 | CCharacter *m_pCharacter; |
| 126 | int m_NumInputs; |
| 127 | CGameContext *m_pGameServer; |
| 128 | |
| 129 | CGameContext *GameServer() const { return m_pGameServer; } |
| 130 | IServer *Server() const; |
| 131 | |
| 132 | // |
| 133 | bool m_Spawning; |
| 134 | bool m_WeakHookSpawn; |
| 135 | int m_ClientId; |
| 136 | int m_Team; |
| 137 | |
| 138 | // used for spectator mode |
| 139 | int m_SpectatorId; |
| 140 | |
| 141 | int m_Paused; |
| 142 | int64_t m_ForcePauseTime; |
| 143 | int64_t m_LastPause; |
| 144 | bool m_Afk; |
| 145 | |
| 146 | int m_DefEmote; |
| 147 | int m_OverrideEmote; |
| 148 | int m_OverrideEmoteReset; |
| 149 | bool m_Halloween; |
| 150 | |
| 151 | public: |
| 152 | enum |
| 153 | { |
| 154 | PAUSE_NONE = 0, |
| 155 | PAUSE_PAUSED, |
| 156 | PAUSE_SPEC |
| 157 | }; |
| 158 | |
| 159 | enum |
| 160 | { |
| 161 | TIMERTYPE_DEFAULT = -1, |
| 162 | TIMERTYPE_GAMETIMER, |
| 163 | TIMERTYPE_BROADCAST, |
| 164 | TIMERTYPE_GAMETIMER_AND_BROADCAST, |
| 165 | TIMERTYPE_SIXUP, |
| 166 | TIMERTYPE_NONE, |
| 167 | }; |
| 168 | |
| 169 | bool m_DND; |
| 170 | bool m_Whispers; |
| 171 | int64_t m_FirstVoteTick; |
| 172 | char m_aTimeoutCode[64]; |
| 173 | |
| 174 | void ProcessPause(); |
| 175 | int Pause(int State, bool Force); |
| 176 | int ForcePause(int Time); |
| 177 | int IsPaused() const; |
| 178 | bool CanSpec() const; |
| 179 | |
| 180 | bool IsPlaying() const; |
| 181 | int64_t m_LastKickVote; |
| 182 | int64_t m_LastDDRaceTeamChange; |
| 183 | int m_ShowOthers; |
| 184 | bool m_ShowAll; |
| 185 | bool m_EnableSpectatorCount; |
| 186 | vec2 m_ShowDistance; |
| 187 | bool m_SpecTeam; |
| 188 | bool m_NinjaJetpack; |
| 189 | |
| 190 | // camera info is used sparingly for converting aim target to absolute world coordinates |
| 191 | class CCameraInfo |
| 192 | { |
| 193 | friend class CPlayer; |
| 194 | bool m_HasCameraInfo; |
| 195 | float m_Zoom; |
| 196 | int m_Deadzone; |
| 197 | int m_FollowFactor; |
| 198 | |
| 199 | public: |
| 200 | vec2 ConvertTargetToWorld(vec2 Position, vec2 Target) const; |
| 201 | void Write(const CNetMsg_Cl_CameraInfo *pMsg); |
| 202 | void Reset(); |
| 203 | } m_CameraInfo; |
| 204 | |
| 205 | int m_ChatScore; |
| 206 | |
| 207 | bool m_Moderating; |
| 208 | |
| 209 | void UpdatePlaytime(); |
| 210 | void AfkTimer(); |
| 211 | void SetAfk(bool Afk); |
| 212 | void SetInitialAfk(bool Afk); |
| 213 | bool IsAfk() const { return m_Afk; } |
| 214 | |
| 215 | int64_t m_LastPlaytime; |
| 216 | int64_t m_LastEyeEmote; |
| 217 | int64_t m_LastBroadcast; |
| 218 | bool m_LastBroadcastImportance; |
| 219 | |
| 220 | CNetObj_PlayerInput *m_pLastTarget; |
| 221 | bool m_LastTargetInit; |
| 222 | |
| 223 | bool m_EyeEmoteEnabled; |
| 224 | int m_TimerType; |
| 225 | |
| 226 | int GetDefaultEmote() const; |
| 227 | void OverrideDefaultEmote(int Emote, int Tick); |
| 228 | bool CanOverrideDefaultEmote() const; |
| 229 | |
| 230 | bool m_FirstPacket; |
| 231 | int64_t m_LastSqlQuery; |
| 232 | void ProcessScoreResult(CScorePlayerResult &Result); |
| 233 | std::shared_ptr<CScorePlayerResult> m_ScoreQueryResult; |
| 234 | std::shared_ptr<CScorePlayerResult> m_ScoreFinishResult; |
| 235 | bool m_NotEligibleForFinish; |
| 236 | int64_t m_EligibleForFinishCheck; |
| 237 | bool m_VotedForPractice; |
| 238 | int m_SwapTargetsClientId; //Client ID of the swap target for the given player |
| 239 | bool m_BirthdayAnnounced; |
| 240 | |
| 241 | int m_RescueMode; |
| 242 | |
| 243 | CSaveTee m_LastTeleTee; |
| 244 | std::optional<CSaveTee> m_LastDeath; |
| 245 | }; |
| 246 | |
| 247 | #endif |
| 248 | |