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 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
123private:
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
151public:
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