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_ENTITIES_CHARACTER_H
4#define GAME_SERVER_ENTITIES_CHARACTER_H
5
6#include <game/server/entity.h>
7#include <game/server/save.h>
8
9class CGameTeams;
10class CGameWorld;
11class IAntibot;
12struct CAntibotCharacterData;
13
14enum
15{
16 FAKETUNE_FREEZE = 1,
17 FAKETUNE_SOLO = 2,
18 FAKETUNE_NOJUMP = 4,
19 FAKETUNE_NOCOLL = 8,
20 FAKETUNE_NOHOOK = 16,
21 FAKETUNE_JETPACK = 32,
22 FAKETUNE_NOHAMMER = 64,
23};
24
25class CCharacter : public CEntity
26{
27 MACRO_ALLOC_POOL_ID()
28
29 friend class CSaveTee; // need to use core
30
31public:
32 CCharacter(CGameWorld *pWorld, CNetObj_PlayerInput LastInput);
33
34 void Reset() override;
35 void Destroy() override;
36 void PreTick();
37 void Tick() override;
38 void TickDeferred() override;
39 void TickPaused() override;
40 void Snap(int SnappingClient) override;
41 void PostSnap() override;
42 void SwapClients(int Client1, int Client2) override;
43
44 bool CanSnapCharacter(int SnappingClient);
45 bool IsSnappingCharacterInView(int SnappingClientId);
46
47 bool IsGrounded();
48
49 void SetWeapon(int W);
50 void SetJetpack(bool Active);
51 void SetSolo(bool Solo);
52 void SetSuper(bool Super);
53 void SetLiveFrozen(bool Active);
54 void SetDeepFrozen(bool Active);
55 void HandleWeaponSwitch();
56 void DoWeaponSwitch();
57
58 void HandleWeapons();
59 void HandleNinja();
60 void HandleJetpack();
61
62 void OnPredictedInput(CNetObj_PlayerInput *pNewInput);
63 void OnDirectInput(CNetObj_PlayerInput *pNewInput);
64 void ReleaseHook();
65 void ResetHook();
66 void ResetInput();
67 void FireWeapon();
68
69 void Die(int Killer, int Weapon, bool SendKillMsg = true);
70 bool TakeDamage(vec2 Force, int Dmg, int From, int Weapon);
71
72 bool Spawn(class CPlayer *pPlayer, vec2 Pos);
73 bool Remove();
74
75 bool IncreaseHealth(int Amount);
76 bool IncreaseArmor(int Amount);
77
78 void GiveWeapon(int Weapon, bool Remove = false);
79 void GiveNinja();
80 void RemoveNinja();
81 void SetEndlessHook(bool Enable);
82
83 void SetEmote(int Emote, int Tick);
84
85 void Rescue();
86
87 int NeededFaketuning() const { return m_NeededFaketuning; }
88 bool IsAlive() const { return m_Alive; }
89 bool IsPaused() const { return m_Paused; }
90 class CPlayer *GetPlayer() { return m_pPlayer; }
91 CClientMask TeamMask();
92
93 void SetPosition(const vec2 &Position);
94 void Move(vec2 RelPos);
95
96 void ResetVelocity();
97 void SetVelocity(vec2 NewVelocity);
98 void SetRawVelocity(vec2 NewVelocity);
99 void AddVelocity(vec2 Addition);
100 void ApplyMoveRestrictions();
101
102private:
103 // player controlling this character
104 class CPlayer *m_pPlayer;
105
106 bool m_Alive;
107 bool m_Paused;
108 int m_PausedTick;
109 int m_NeededFaketuning;
110
111 // weapon info
112 CEntity *m_apHitObjects[10];
113 int m_NumObjectsHit;
114
115 int m_LastWeapon;
116 int m_QueuedWeapon;
117
118 int m_ReloadTimer;
119 int m_AttackTick;
120
121 int m_MoveRestrictions;
122
123 int m_DamageTaken;
124
125 int m_EmoteType;
126 int m_EmoteStop;
127
128 // last tick that the player took any action ie some input
129 int m_LastAction;
130 int m_LastNoAmmoSound;
131
132 // these are non-heldback inputs
133 CNetObj_PlayerInput m_LatestPrevPrevInput;
134 CNetObj_PlayerInput m_LatestPrevInput;
135 CNetObj_PlayerInput m_LatestInput;
136
137 // input
138 CNetObj_PlayerInput m_PrevInput;
139 CNetObj_PlayerInput m_Input;
140 CNetObj_PlayerInput m_SavedInput;
141 int m_NumInputs;
142
143 int m_DamageTakenTick;
144
145 int m_Health;
146 int m_Armor;
147
148 int m_TriggeredEvents7;
149
150 // the player core for the physics
151 CCharacterCore m_Core;
152 CGameTeams *m_pTeams = nullptr;
153
154 // info for dead reckoning
155 int m_ReckoningTick; // tick that we are performing dead reckoning From
156 CCharacterCore m_SendCore; // core that we should send
157 CCharacterCore m_ReckoningCore; // the dead reckoning core
158
159 // DDRace
160
161 void SnapCharacter(int SnappingClient, int Id);
162 static bool IsSwitchActiveCb(int Number, void *pUser);
163 void SetTimeCheckpoint(int TimeCheckpoint);
164 void HandleTiles(int Index);
165 float m_Time;
166 int m_LastBroadcast;
167 void DDRaceInit();
168 void HandleSkippableTiles(int Index);
169 void ForceSetRescue(int RescueMode);
170 void DDRaceTick();
171 void DDRacePostCoreTick();
172 void HandleBroadcast();
173 void HandleTuneLayer();
174 void SendZoneMsgs();
175 IAntibot *Antibot();
176
177 bool m_SetSavePos[NUM_RESCUEMODES];
178 CSaveTee m_RescueTee[NUM_RESCUEMODES];
179
180public:
181 CGameTeams *Teams() { return m_pTeams; }
182 void SetTeams(CGameTeams *pTeams);
183 bool TrySetRescue(int RescueMode);
184
185 void FillAntibot(CAntibotCharacterData *pData);
186 void Pause(bool Pause);
187 bool Freeze(int Seconds);
188 bool Freeze();
189 bool UnFreeze();
190 void GiveAllWeapons();
191 void ResetPickups();
192 void ResetJumps();
193 int m_DDRaceState;
194 int Team();
195 bool CanCollide(int ClientId);
196 bool SameTeam(int ClientId);
197 void StopRecording();
198 bool m_NinjaJetpack;
199 int m_TeamBeforeSuper;
200 int m_FreezeTime;
201 bool m_FrozenLastTick;
202 bool m_FreezeHammer;
203 int m_TuneZone;
204 int m_TuneZoneOld;
205 int m_PainSoundTimer;
206 int m_LastMove;
207 int m_StartTime;
208 vec2 m_PrevPos;
209 int m_TeleCheckpoint;
210
211 int m_TimeCpBroadcastEndTick;
212 int m_LastTimeCp;
213 int m_LastTimeCpBroadcasted;
214 float m_aCurrentTimeCp[MAX_CHECKPOINTS];
215
216 int m_TileIndex;
217 int m_TileFIndex;
218
219 int64_t m_LastStartWarning;
220 int64_t m_LastRescue;
221 bool m_LastRefillJumps;
222 bool m_LastPenalty;
223 bool m_LastBonus;
224 vec2 m_TeleGunPos;
225 bool m_TeleGunTeleport;
226 bool m_IsBlueTeleGunTeleport;
227 int m_StrongWeakId;
228
229 int m_SpawnTick;
230 int m_WeaponChangeTick;
231
232 // Setters/Getters because i don't want to modify vanilla vars access modifiers
233 int GetLastWeapon() const { return m_LastWeapon; }
234 void SetLastWeapon(int LastWeap) { m_LastWeapon = LastWeap; }
235 int GetActiveWeapon() const { return m_Core.m_ActiveWeapon; }
236 void SetActiveWeapon(int ActiveWeap) { m_Core.m_ActiveWeapon = ActiveWeap; }
237 void SetLastAction(int LastAction) { m_LastAction = LastAction; }
238 int GetArmor() const { return m_Armor; }
239 void SetArmor(int Armor) { m_Armor = Armor; }
240 CCharacterCore GetCore() { return m_Core; }
241 void SetCore(CCharacterCore Core) { m_Core = Core; }
242 const CCharacterCore *Core() const { return &m_Core; }
243 bool GetWeaponGot(int Type) { return m_Core.m_aWeapons[Type].m_Got; }
244 void SetWeaponGot(int Type, bool Value) { m_Core.m_aWeapons[Type].m_Got = Value; }
245 int GetWeaponAmmo(int Type) { return m_Core.m_aWeapons[Type].m_Ammo; }
246 void SetWeaponAmmo(int Type, int Value) { m_Core.m_aWeapons[Type].m_Ammo = Value; }
247 void SetNinjaActivationDir(vec2 ActivationDir) { m_Core.m_Ninja.m_ActivationDir = ActivationDir; }
248 void SetNinjaActivationTick(int ActivationTick) { m_Core.m_Ninja.m_ActivationTick = ActivationTick; }
249 void SetNinjaCurrentMoveTime(int CurrentMoveTime) { m_Core.m_Ninja.m_CurrentMoveTime = CurrentMoveTime; }
250
251 int GetLastAction() const { return m_LastAction; }
252
253 bool HasTelegunGun() const { return m_Core.m_HasTelegunGun; }
254 bool HasTelegunGrenade() const { return m_Core.m_HasTelegunGrenade; }
255 bool HasTelegunLaser() const { return m_Core.m_HasTelegunLaser; }
256
257 bool HammerHitDisabled() const { return m_Core.m_HammerHitDisabled; }
258 bool ShotgunHitDisabled() const { return m_Core.m_ShotgunHitDisabled; }
259 bool LaserHitDisabled() const { return m_Core.m_LaserHitDisabled; }
260 bool GrenadeHitDisabled() const { return m_Core.m_GrenadeHitDisabled; }
261
262 bool IsSuper() const { return m_Core.m_Super; }
263
264 CSaveTee &GetLastRescueTeeRef(int Mode = RESCUEMODE_AUTO) { return m_RescueTee[Mode]; }
265};
266
267enum
268{
269 DDRACE_NONE = 0,
270 DDRACE_STARTED,
271 DDRACE_CHEAT, // no time and won't start again unless ordered by a mod or death
272 DDRACE_FINISHED
273};
274
275#endif
276