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 | |
9 | class CGameTeams; |
10 | class CGameWorld; |
11 | class IAntibot; |
12 | struct CAntibotCharacterData; |
13 | |
14 | enum |
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 | |
25 | class CCharacter : public CEntity |
26 | { |
27 | MACRO_ALLOC_POOL_ID() |
28 | |
29 | friend class CSaveTee; // need to use core |
30 | |
31 | public: |
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 | |
102 | private: |
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 | |
180 | public: |
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 | |
267 | enum |
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 | |