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