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