1#ifndef GAME_SERVER_SAVE_H
2#define GAME_SERVER_SAVE_H
3
4#include <base/vmath.h>
5
6#include <engine/shared/protocol.h>
7
8#include <generated/protocol.h>
9
10#include <game/team_state.h>
11
12#include <optional>
13
14class IGameController;
15class CGameContext;
16class CGameWorld;
17class CCharacter;
18class CSaveTeam;
19
20enum
21{
22 RESCUEMODE_AUTO = 0,
23 RESCUEMODE_MANUAL,
24 NUM_RESCUEMODES
25};
26
27enum class ESaveResult
28{
29 SUCCESS,
30 TEAM_FLOCK,
31 TEAM_NOT_FOUND,
32 CHAR_NOT_FOUND,
33 NOT_STARTED,
34 TEAM_0_MODE,
35 DRAGGER_ACTIVE
36};
37
38class CSaveTee
39{
40public:
41 CSaveTee();
42 ~CSaveTee() = default;
43 void Save(CCharacter *pChr, bool AddPenalty = true);
44 bool Load(CCharacter *pChr, std::optional<int> Team = std::nullopt);
45 char *GetString(const CSaveTeam *pTeam);
46 int FromString(const char *pString);
47 void LoadHookedPlayer(const CSaveTeam *pTeam);
48 bool IsHooking() const;
49 vec2 GetPos() const { return m_Pos; }
50 const char *GetName() const { return m_aName; }
51 int GetClientId() const { return m_ClientId; }
52 void SetClientId(int ClientId) { m_ClientId = ClientId; }
53
54 enum
55 {
56 HIT_ALL = 0,
57 HAMMER_HIT_DISABLED = 1,
58 SHOTGUN_HIT_DISABLED = 2,
59 GRENADE_HIT_DISABLED = 4,
60 LASER_HIT_DISABLED = 8
61 };
62
63private:
64 int m_ClientId;
65
66 char m_aString[2048];
67 char m_aName[16];
68
69 int m_Alive;
70 int m_Paused;
71 int m_NeededFaketuning;
72
73 // Teamstuff
74 int m_TeeStarted;
75 int m_TeeFinished;
76 int m_IsSolo;
77
78 class CWeaponStat
79 {
80 public:
81 int m_AmmoRegenStart;
82 int m_Ammo;
83 int m_Ammocost;
84 int m_Got;
85 } m_aWeapons[NUM_WEAPONS];
86
87 // ninja
88 struct
89 {
90 vec2 m_ActivationDir;
91 int m_ActivationTick;
92 int m_CurrentMoveTime;
93 int m_OldVelAmount;
94 } m_Ninja;
95
96 int m_LastWeapon;
97 int m_QueuedWeapon;
98
99 int m_EndlessJump;
100 int m_Jetpack;
101 int m_NinjaJetpack;
102 int m_FreezeTime;
103 int m_FreezeStart;
104 int m_DeepFrozen;
105 int m_LiveFrozen;
106 int m_EndlessHook;
107 int m_DDRaceState;
108
109 int m_HitDisabledFlags;
110 int m_CollisionEnabled;
111 int m_TuneZone;
112 int m_TuneZoneOld;
113 int m_HookHitEnabled;
114 int m_Time;
115 vec2 m_Pos;
116 vec2 m_PrevPos;
117 int m_TeleCheckpoint;
118 int m_LastPenalty;
119
120 int m_TimeCpBroadcastEndTime;
121 int m_LastTimeCp;
122 int m_LastTimeCpBroadcasted;
123 float m_aCurrentTimeCp[MAX_CHECKPOINTS];
124
125 int m_NotEligibleForFinish;
126
127 int m_HasTelegunGun;
128 int m_HasTelegunGrenade;
129 int m_HasTelegunLaser;
130
131 // Core
132 vec2 m_CorePos;
133 vec2 m_Vel;
134 int m_ActiveWeapon;
135 int m_Jumped;
136 int m_JumpedTotal;
137 int m_Jumps;
138 vec2 m_HookPos;
139 vec2 m_HookDir;
140 vec2 m_HookTeleBase;
141 int m_HookTick;
142 int m_HookState;
143 int m_HookedPlayer;
144 int m_NewHook;
145
146 // player input
147 int m_InputDirection;
148 int m_InputJump;
149 int m_InputFire;
150 int m_InputHook;
151
152 int m_ReloadTimer;
153
154 char m_aGameUuid[UUID_MAXSTRSIZE];
155};
156
157class CSaveHotReloadTee
158{
159public:
160 CSaveHotReloadTee() = default;
161 ~CSaveHotReloadTee() = default;
162 void Save(CCharacter *pChr, bool AddPenalty = true);
163 bool Load(CCharacter *pChr, int Team);
164
165private:
166 CSaveTee m_SaveTee;
167 bool m_Super;
168 bool m_Invincible;
169 CSaveTee m_SavedTeleTee;
170 std::optional<CSaveTee> m_LastDeath;
171};
172
173class CSaveTeam
174{
175public:
176 CSaveTeam();
177 ~CSaveTeam();
178 char *GetString();
179 int GetMembersCount() const { return m_MembersCount; }
180 // MatchPlayers has to be called afterwards
181 int FromString(const char *pString);
182 // returns true if a team can load, otherwise writes a nice error Message in pMessage
183 bool MatchPlayers(const char (*paNames)[MAX_NAME_LENGTH], const int *pClientId, int NumPlayer, char *pMessage, int MessageLen) const;
184 ESaveResult Save(CGameContext *pGameServer, int Team, bool Dry = false, bool Force = false);
185 bool Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakStrong, bool IgnorePlayers = false);
186
187 CSaveTee *m_pSavedTees = nullptr;
188
189 // returns true if an error occurred
190 static bool HandleSaveError(ESaveResult Result, int ClientId, CGameContext *pGameContext);
191
192private:
193 CCharacter *MatchCharacter(CGameContext *pGameServer, int ClientId, int SaveId, bool KeepCurrentCharacter) const;
194
195 char m_aString[65536];
196
197 struct SSimpleSwitchers
198 {
199 int m_Status;
200 int m_EndTime;
201 int m_Type;
202 };
203 SSimpleSwitchers *m_pSwitchers = nullptr;
204
205 ETeamState m_TeamState = ETeamState::EMPTY;
206 int m_MembersCount = 0;
207 int m_HighestSwitchNumber = 0;
208 int m_TeamLocked = 0;
209 int m_Practice = 0;
210};
211
212#endif // GAME_SERVER_SAVE_H
213