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_CLIENT_PREDICTION_ENTITIES_CHARACTER_H
4#define GAME_CLIENT_PREDICTION_ENTITIES_CHARACTER_H
5
6#include <generated/protocol.h>
7
8#include <game/client/prediction/entity.h>
9#include <game/gamecore.h>
10#include <game/race_state.h>
11
12enum
13{
14 FAKETUNE_FREEZE = 1 << 0,
15 FAKETUNE_SOLO = 1 << 1,
16 FAKETUNE_NOJUMP = 1 << 2,
17 FAKETUNE_NOCOLL = 1 << 3,
18 FAKETUNE_NOHOOK = 1 << 4,
19 FAKETUNE_JETPACK = 1 << 5,
20 FAKETUNE_NOHAMMER = 1 << 6,
21};
22
23class CCharacter : public CEntity
24{
25 friend class CGameWorld;
26
27public:
28 ~CCharacter() override;
29
30 void PreTick() override;
31 void Tick() override;
32 void TickDeferred() override;
33
34 bool IsGrounded();
35
36 void SetWeapon(int Weapon);
37 void SetSolo(bool Solo);
38 void SetSuper(bool Super);
39 void HandleWeaponSwitch();
40 void DoWeaponSwitch();
41
42 void HandleWeapons();
43 void HandleNinja();
44 void HandleJetpack();
45
46 void OnPredictedInput(const CNetObj_PlayerInput *pNewInput);
47 void OnDirectInput(const CNetObj_PlayerInput *pNewInput);
48 void ReleaseHook();
49 void ResetHook();
50 void ResetInput();
51 void FireWeapon();
52
53 bool TakeDamage(vec2 Force, int Dmg, int From, int Weapon);
54
55 void GiveWeapon(int Weapon, bool Remove = false);
56 void GiveNinja();
57 void RemoveNinja();
58
59 void ResetVelocity();
60 void SetVelocity(vec2 NewVelocity);
61 void SetRawVelocity(vec2 NewVelocity);
62 void AddVelocity(vec2 Addition);
63 void ApplyMoveRestrictions();
64
65 bool m_IsLocal;
66
67 CTeamsCore *TeamsCore();
68 bool Freeze(int Seconds);
69 bool Freeze();
70 bool UnFreeze();
71 void GiveAllWeapons();
72 int Team();
73 bool CanCollide(int ClientId) override;
74 bool SameTeam(int ClientId);
75 bool m_NinjaJetpack;
76 int m_FreezeTime;
77 bool m_FrozenLastTick;
78 vec2 m_PrevPos;
79 vec2 m_PrevPrevPos;
80 int m_TeleCheckpoint;
81
82 int m_TileIndex;
83 int m_TileFIndex;
84
85 bool m_LastRefillJumps;
86
87 // Setters/Getters because i don't want to modify vanilla vars access modifiers
88 int GetLastWeapon() const { return m_LastWeapon; }
89 void SetLastWeapon(int LastWeap) { m_LastWeapon = LastWeap; }
90 int GetActiveWeapon() const { return m_Core.m_ActiveWeapon; }
91 void SetActiveWeapon(int ActiveWeapon);
92 CCharacterCore GetCore() { return m_Core; }
93 void SetCore(const CCharacterCore &Core) { m_Core = Core; }
94 const CCharacterCore *Core() const { return &m_Core; }
95 bool GetWeaponGot(int Type) { return m_Core.m_aWeapons[Type].m_Got; }
96 void SetWeaponGot(int Type, bool Value) { m_Core.m_aWeapons[Type].m_Got = Value; }
97 int GetWeaponAmmo(int Type) { return m_Core.m_aWeapons[Type].m_Ammo; }
98 void SetWeaponAmmo(int Type, int Value) { m_Core.m_aWeapons[Type].m_Ammo = Value; }
99 void SetNinjaActivationDir(vec2 ActivationDir) { m_Core.m_Ninja.m_ActivationDir = ActivationDir; }
100 void SetNinjaActivationTick(int ActivationTick) { m_Core.m_Ninja.m_ActivationTick = ActivationTick; }
101 void SetNinjaCurrentMoveTime(int CurrentMoveTime) { m_Core.m_Ninja.m_CurrentMoveTime = CurrentMoveTime; }
102 int GetCid() { return m_Id; }
103 void SetInput(const CNetObj_PlayerInput *pNewInput)
104 {
105 m_LatestInput = m_Input = *pNewInput;
106 // it is not allowed to aim in the center
107 if(m_Input.m_TargetX == 0 && m_Input.m_TargetY == 0)
108 {
109 m_Input.m_TargetY = m_LatestInput.m_TargetY = -1;
110 }
111 }
112 int GetJumped() const { return m_Core.m_Jumped; }
113 int GetAttackTick() const { return m_AttackTick; }
114 int GetStrongWeakId() const { return m_StrongWeakId; }
115
116 CCharacter(CGameWorld *pGameWorld, int Id, CNetObj_Character *pChar, CNetObj_DDNetCharacter *pExtended = nullptr);
117 void Read(CNetObj_Character *pChar, CNetObj_DDNetCharacter *pExtended, bool IsLocal);
118 void SetCoreWorld(CGameWorld *pGameWorld);
119
120 int m_LastSnapWeapon;
121 bool m_KeepHooked;
122 int m_GameTeam;
123 bool m_CanMoveInFreeze;
124
125 bool Match(CCharacter *pChar) const;
126 void ResetPrediction();
127 void SetTuneZone(int Zone);
128 int GetOverriddenTuneZone() const;
129 int GetPureTuneZone() const;
130
131 bool HammerHitDisabled() const { return m_Core.m_HammerHitDisabled; }
132 bool ShotgunHitDisabled() const { return m_Core.m_ShotgunHitDisabled; }
133 bool LaserHitDisabled() const { return m_Core.m_LaserHitDisabled; }
134 bool GrenadeHitDisabled() const { return m_Core.m_GrenadeHitDisabled; }
135
136 bool IsSuper() const { return m_Core.m_Super; }
137
138private:
139 // weapon info
140 int m_aHitObjects[MAX_CLIENTS];
141 int m_NumObjectsHit;
142
143 int m_LastWeapon;
144 int m_QueuedWeapon;
145
146 int m_ReloadTimer;
147 int m_AttackTick;
148
149 int m_MoveRestrictions;
150
151 // these are non-heldback inputs
152 CNetObj_PlayerInput m_LatestPrevInput;
153 CNetObj_PlayerInput m_LatestInput;
154
155 // input
156 CNetObj_PlayerInput m_PrevInput;
157 CNetObj_PlayerInput m_Input;
158 CNetObj_PlayerInput m_SavedInput;
159
160 int m_NumInputs;
161
162 // tune
163 int m_TuneZone;
164 int m_TuneZoneOverride;
165
166 // the player core for the physics
167 CCharacterCore m_Core;
168
169 // DDRace
170
171 static bool IsSwitchActiveCb(int Number, void *pUser);
172 void HandleTiles(int Index);
173 void HandleSkippableTiles(int Index);
174 void DDRaceTick();
175 void DDRacePostCoreTick();
176 void HandleTuneLayer();
177
178 int m_StrongWeakId;
179
180 int m_LastWeaponSwitchTick;
181 int m_LastTuneZoneTick;
182};
183
184#endif
185