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
55 void OnDirectInput(const CNetObj_PlayerInput *pNewInput);
56 void OnPredictedInput(const CNetObj_PlayerInput *pNewInput);
57 void OnPredictedEarlyInput(const CNetObj_PlayerInput *pNewInput);
58 void OnDisconnect();
59
60 void KillCharacter(int Weapon = WEAPON_GAME, bool SendKillMsg = true);
61 CCharacter *GetCharacter();
62 const CCharacter *GetCharacter() const;
63
64 void SpectatePlayerName(const char *pName);
65
66 //---------------------------------------------------------
67 // this is used for snapping so we know how we can clip the view for the player
68 vec2 m_ViewPos;
69 int m_TuneZone;
70 int m_TuneZoneOld;
71
72 // states if the client is chatting, accessing a menu etc.
73 int m_PlayerFlags;
74
75 // used for snapping to just update latency if the scoreboard is active
76 int m_aCurLatency[MAX_CLIENTS];
77
78 int m_SentSnaps = 0;
79
80 int SpectatorId() const { return m_SpectatorId; }
81 void SetSpectatorId(int Id);
82
83 bool m_IsReady;
84
85 //
86 int m_Vote;
87 int m_VotePos;
88 //
89 int m_LastVoteCall;
90 int m_LastVoteTry;
91 int m_LastChat;
92 int m_LastSetTeam;
93 int m_LastSetSpectatorMode;
94 int m_LastChangeInfo;
95 int m_LastEmote;
96 int m_LastEmoteGlobal;
97 int m_LastKill;
98 int m_aLastCommands[4];
99 int m_LastCommandPos;
100 int m_LastWhisperTo;
101 int m_LastInvited;
102
103 int m_SendVoteIndex;
104
105 CTeeInfo m_TeeInfos;
106
107 int m_DieTick;
108 int m_PreviousDieTick;
109 int m_JoinTick;
110 int m_LastActionTick;
111 int m_TeamChangeTick;
112
113 // network latency calculations
114 struct
115 {
116 int m_Accum;
117 int m_AccumMin;
118 int m_AccumMax;
119 int m_Avg;
120 int m_Min;
121 int m_Max;
122 } m_Latency;
123
124private:
125 const uint32_t m_UniqueClientId;
126 CCharacter *m_pCharacter;
127 int m_NumInputs;
128 CGameContext *m_pGameServer;
129
130 CGameContext *GameServer() const { return m_pGameServer; }
131 IServer *Server() const;
132
133 //
134 bool m_Spawning;
135 bool m_WeakHookSpawn;
136 int m_ClientId;
137 int m_Team;
138
139 // used for spectator mode
140 int m_SpectatorId;
141
142 int m_Paused;
143 int64_t m_ForcePauseTime;
144 int64_t m_LastPause;
145 bool m_Afk;
146
147 int m_DefEmote;
148 int m_OverrideEmote;
149 int m_OverrideEmoteReset;
150 bool m_Halloween;
151
152public:
153 enum
154 {
155 PAUSE_NONE = 0,
156 PAUSE_PAUSED,
157 PAUSE_SPEC
158 };
159
160 enum
161 {
162 TIMERTYPE_DEFAULT = -1,
163 TIMERTYPE_GAMETIMER,
164 TIMERTYPE_BROADCAST,
165 TIMERTYPE_GAMETIMER_AND_BROADCAST,
166 TIMERTYPE_SIXUP,
167 TIMERTYPE_NONE,
168 };
169
170 bool m_DND;
171 bool m_Whispers;
172 int64_t m_FirstVoteTick;
173 char m_aTimeoutCode[64];
174
175 void ProcessPause();
176 int Pause(int State, bool Force);
177 int ForcePause(int Time);
178 int IsPaused() const;
179 bool CanSpec() const;
180
181 bool IsPlaying() const;
182 int64_t m_LastKickVote;
183 int64_t m_LastDDRaceTeamChange;
184 int m_ShowOthers;
185 bool m_ShowAll;
186 bool m_EnableSpectatorCount;
187 vec2 m_ShowDistance;
188 bool m_SpecTeam;
189 bool m_NinjaJetpack;
190
191 // camera info is used sparingly for converting aim target to absolute world coordinates
192 class CCameraInfo
193 {
194 friend class CPlayer;
195 bool m_HasCameraInfo;
196 float m_Zoom;
197 int m_Deadzone;
198 int m_FollowFactor;
199
200 public:
201 vec2 ConvertTargetToWorld(vec2 Position, vec2 Target) const;
202 void Write(const CNetMsg_Cl_CameraInfo *pMsg);
203 void Reset();
204 } m_CameraInfo;
205
206 int m_ChatScore;
207
208 bool m_Moderating;
209
210 void UpdatePlaytime();
211 void AfkTimer();
212 void SetAfk(bool Afk);
213 void SetInitialAfk(bool Afk);
214 bool IsAfk() const { return m_Afk; }
215
216 int64_t m_LastPlaytime;
217 int64_t m_LastEyeEmote;
218 int64_t m_LastBroadcast;
219 bool m_LastBroadcastImportance;
220
221 CNetObj_PlayerInput *m_pLastTarget;
222 bool m_LastTargetInit;
223
224 bool m_EyeEmoteEnabled;
225 int m_TimerType;
226
227 int GetDefaultEmote() const;
228 void OverrideDefaultEmote(int Emote, int Tick);
229 bool CanOverrideDefaultEmote() const;
230
231 bool m_FirstPacket;
232 int64_t m_LastSqlQuery;
233 void ProcessScoreResult(CScorePlayerResult &Result);
234 std::shared_ptr<CScorePlayerResult> m_ScoreQueryResult;
235 std::shared_ptr<CScorePlayerResult> m_ScoreFinishResult;
236 bool m_NotEligibleForFinish;
237 int64_t m_EligibleForFinishCheck;
238 bool m_VotedForPractice;
239 int m_SwapTargetsClientId; //Client ID of the swap target for the given player
240 bool m_BirthdayAnnounced;
241
242 int m_RescueMode;
243
244 CSaveTee m_LastTeleTee;
245 std::optional<CSaveTee> m_LastDeath;
246};
247
248#endif
249