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_GAMECLIENT_H |
4 | #define GAME_CLIENT_GAMECLIENT_H |
5 | |
6 | #include "render.h" |
7 | #include <base/color.h> |
8 | #include <base/vmath.h> |
9 | #include <engine/client.h> |
10 | #include <engine/console.h> |
11 | #include <engine/shared/config.h> |
12 | |
13 | #include <game/collision.h> |
14 | #include <game/gamecore.h> |
15 | #include <game/layers.h> |
16 | #include <game/teamscore.h> |
17 | |
18 | #include <game/client/prediction/gameworld.h> |
19 | |
20 | // components |
21 | #include "components/background.h" |
22 | #include "components/binds.h" |
23 | #include "components/broadcast.h" |
24 | #include "components/camera.h" |
25 | #include "components/chat.h" |
26 | #include "components/console.h" |
27 | #include "components/controls.h" |
28 | #include "components/countryflags.h" |
29 | #include "components/damageind.h" |
30 | #include "components/debughud.h" |
31 | #include "components/effects.h" |
32 | #include "components/emoticon.h" |
33 | #include "components/flow.h" |
34 | #include "components/freezebars.h" |
35 | #include "components/ghost.h" |
36 | #include "components/hud.h" |
37 | #include "components/infomessages.h" |
38 | #include "components/items.h" |
39 | #include "components/mapimages.h" |
40 | #include "components/maplayers.h" |
41 | #include "components/mapsounds.h" |
42 | #include "components/menu_background.h" |
43 | #include "components/menus.h" |
44 | #include "components/motd.h" |
45 | #include "components/nameplates.h" |
46 | #include "components/particles.h" |
47 | #include "components/players.h" |
48 | #include "components/race_demo.h" |
49 | #include "components/scoreboard.h" |
50 | #include "components/skins.h" |
51 | #include "components/sounds.h" |
52 | #include "components/spectator.h" |
53 | #include "components/statboard.h" |
54 | #include "components/tooltips.h" |
55 | #include "components/voting.h" |
56 | |
57 | class CGameInfo |
58 | { |
59 | public: |
60 | bool m_FlagStartsRace; |
61 | bool m_TimeScore; |
62 | bool m_UnlimitedAmmo; |
63 | bool m_DDRaceRecordMessage; |
64 | bool m_RaceRecordMessage; |
65 | bool m_RaceSounds; |
66 | |
67 | bool m_AllowEyeWheel; |
68 | bool m_AllowHookColl; |
69 | bool m_AllowZoom; |
70 | |
71 | bool m_BugDDRaceGhost; |
72 | bool m_BugDDRaceInput; |
73 | bool m_BugFNGLaserRange; |
74 | bool m_BugVanillaBounce; |
75 | |
76 | bool m_PredictFNG; |
77 | bool m_PredictDDRace; |
78 | bool m_PredictDDRaceTiles; |
79 | bool m_PredictVanilla; |
80 | |
81 | bool m_EntitiesDDNet; |
82 | bool m_EntitiesDDRace; |
83 | bool m_EntitiesRace; |
84 | bool m_EntitiesFNG; |
85 | bool m_EntitiesVanilla; |
86 | bool m_EntitiesBW; |
87 | bool m_EntitiesFDDrace; |
88 | |
89 | bool m_Race; |
90 | bool m_Pvp; |
91 | |
92 | bool m_DontMaskEntities; |
93 | bool m_AllowXSkins; |
94 | |
95 | bool m_HudHealthArmor; |
96 | bool m_HudAmmo; |
97 | bool m_HudDDRace; |
98 | |
99 | bool m_NoWeakHookAndBounce; |
100 | bool m_NoSkinChangeForFrozen; |
101 | }; |
102 | |
103 | class CSnapEntities |
104 | { |
105 | public: |
106 | IClient::CSnapItem m_Item; |
107 | const void *m_pData; |
108 | const CNetObj_EntityEx *m_pDataEx; |
109 | }; |
110 | |
111 | class CGameClient : public IGameClient |
112 | { |
113 | public: |
114 | // all components |
115 | CInfoMessages m_InfoMessages; |
116 | CCamera m_Camera; |
117 | CChat m_Chat; |
118 | CMotd m_Motd; |
119 | CBroadcast m_Broadcast; |
120 | CGameConsole m_GameConsole; |
121 | CBinds m_Binds; |
122 | CParticles m_Particles; |
123 | CMenus ; |
124 | CSkins m_Skins; |
125 | CCountryFlags m_CountryFlags; |
126 | CFlow m_Flow; |
127 | CHud m_Hud; |
128 | CDebugHud m_DebugHud; |
129 | CControls m_Controls; |
130 | CEffects m_Effects; |
131 | CScoreboard m_Scoreboard; |
132 | CStatboard m_Statboard; |
133 | CSounds m_Sounds; |
134 | CEmoticon m_Emoticon; |
135 | CDamageInd m_DamageInd; |
136 | CVoting m_Voting; |
137 | CSpectator m_Spectator; |
138 | |
139 | CPlayers m_Players; |
140 | CNamePlates m_NamePlates; |
141 | CFreezeBars m_FreezeBars; |
142 | CItems m_Items; |
143 | CMapImages m_MapImages; |
144 | |
145 | CMapLayers m_MapLayersBackground = CMapLayers{CMapLayers::TYPE_BACKGROUND}; |
146 | CMapLayers m_MapLayersForeground = CMapLayers{CMapLayers::TYPE_FOREGROUND}; |
147 | CBackground m_Background; |
148 | CMenuBackground ; |
149 | |
150 | CMapSounds m_MapSounds; |
151 | |
152 | CRaceDemo m_RaceDemo; |
153 | CGhost m_Ghost; |
154 | |
155 | CTooltips m_Tooltips; |
156 | |
157 | private: |
158 | std::vector<class CComponent *> m_vpAll; |
159 | std::vector<class CComponent *> m_vpInput; |
160 | CNetObjHandler m_NetObjHandler; |
161 | |
162 | class IEngine *m_pEngine; |
163 | class IInput *m_pInput; |
164 | class IGraphics *m_pGraphics; |
165 | class ITextRender *m_pTextRender; |
166 | class IClient *m_pClient; |
167 | class ISound *m_pSound; |
168 | class IConfigManager *m_pConfigManager; |
169 | class CConfig *m_pConfig; |
170 | class IConsole *m_pConsole; |
171 | class IStorage *m_pStorage; |
172 | class IDemoPlayer *m_pDemoPlayer; |
173 | class IFavorites *m_pFavorites; |
174 | class IServerBrowser *m_pServerBrowser; |
175 | class IEditor *m_pEditor; |
176 | class IFriends *m_pFriends; |
177 | class IFriends *m_pFoes; |
178 | #if defined(CONF_AUTOUPDATE) |
179 | class IUpdater *m_pUpdater; |
180 | #endif |
181 | class IHttp *m_pHttp; |
182 | |
183 | CLayers m_Layers; |
184 | CCollision m_Collision; |
185 | CUi m_UI; |
186 | |
187 | void ProcessEvents(); |
188 | void UpdatePositions(); |
189 | |
190 | int m_EditorMovementDelay = 5; |
191 | void UpdateEditorIngameMoved(); |
192 | |
193 | int m_PredictedTick; |
194 | int m_aLastNewPredictedTick[NUM_DUMMIES]; |
195 | |
196 | int m_LastRoundStartTick; |
197 | |
198 | int m_LastFlagCarrierRed; |
199 | int m_LastFlagCarrierBlue; |
200 | |
201 | int m_aCheckInfo[NUM_DUMMIES]; |
202 | |
203 | char m_aDDNetVersionStr[64]; |
204 | |
205 | static void ConTeam(IConsole::IResult *pResult, void *pUserData); |
206 | static void ConKill(IConsole::IResult *pResult, void *pUserData); |
207 | |
208 | static void ConchainLanguageUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
209 | static void ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
210 | static void ConchainSpecialDummyInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
211 | static void ConchainRefreshSkins(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
212 | static void ConchainSpecialDummy(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
213 | static void ConchainClTextEntitiesSize(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
214 | |
215 | static void ConTuneZone(IConsole::IResult *pResult, void *pUserData); |
216 | |
217 | static void (IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
218 | |
219 | // only used in OnPredict |
220 | vec2 m_aLastPos[MAX_CLIENTS]; |
221 | bool m_aLastActive[MAX_CLIENTS]; |
222 | |
223 | // only used in OnNewSnapshot |
224 | bool m_GameOver = false; |
225 | bool m_GamePaused = false; |
226 | int m_PrevLocalId = -1; |
227 | |
228 | public: |
229 | IKernel *Kernel() { return IInterface::Kernel(); } |
230 | IEngine *Engine() const { return m_pEngine; } |
231 | class IGraphics *Graphics() const { return m_pGraphics; } |
232 | class IClient *Client() const { return m_pClient; } |
233 | class CUi *Ui() { return &m_UI; } |
234 | class ISound *Sound() const { return m_pSound; } |
235 | class IInput *Input() const { return m_pInput; } |
236 | class IStorage *Storage() const { return m_pStorage; } |
237 | class IConfigManager *ConfigManager() const { return m_pConfigManager; } |
238 | class CConfig *Config() const { return m_pConfig; } |
239 | class IConsole *Console() { return m_pConsole; } |
240 | class ITextRender *TextRender() const { return m_pTextRender; } |
241 | class IDemoPlayer *DemoPlayer() const { return m_pDemoPlayer; } |
242 | class IDemoRecorder *DemoRecorder(int Recorder) const { return Client()->DemoRecorder(Recorder); } |
243 | class IFavorites *Favorites() const { return m_pFavorites; } |
244 | class IServerBrowser *ServerBrowser() const { return m_pServerBrowser; } |
245 | class CRenderTools *RenderTools() { return &m_RenderTools; } |
246 | class CLayers *Layers() { return &m_Layers; } |
247 | CCollision *Collision() { return &m_Collision; } |
248 | class IEditor *Editor() { return m_pEditor; } |
249 | class IFriends *Friends() { return m_pFriends; } |
250 | class IFriends *Foes() { return m_pFoes; } |
251 | #if defined(CONF_AUTOUPDATE) |
252 | class IUpdater *Updater() |
253 | { |
254 | return m_pUpdater; |
255 | } |
256 | #endif |
257 | class IHttp *Http() |
258 | { |
259 | return m_pHttp; |
260 | } |
261 | |
262 | int NetobjNumCorrections() |
263 | { |
264 | return m_NetObjHandler.NumObjCorrections(); |
265 | } |
266 | const char *NetobjCorrectedOn() { return m_NetObjHandler.CorrectedObjOn(); } |
267 | |
268 | bool m_SuppressEvents; |
269 | bool m_NewTick; |
270 | bool m_NewPredictedTick; |
271 | int m_aFlagDropTick[2]; |
272 | |
273 | enum |
274 | { |
275 | SERVERMODE_PURE = 0, |
276 | SERVERMODE_MOD, |
277 | SERVERMODE_PUREMOD, |
278 | }; |
279 | int m_ServerMode; |
280 | CGameInfo m_GameInfo; |
281 | |
282 | int m_DemoSpecId; |
283 | |
284 | vec2 m_LocalCharacterPos; |
285 | |
286 | // predicted players |
287 | CCharacterCore m_PredictedPrevChar; |
288 | CCharacterCore m_PredictedChar; |
289 | |
290 | // snap pointers |
291 | struct CSnapState |
292 | { |
293 | const CNetObj_Character *m_pLocalCharacter; |
294 | const CNetObj_Character *m_pLocalPrevCharacter; |
295 | const CNetObj_PlayerInfo *m_pLocalInfo; |
296 | const CNetObj_SpectatorInfo *m_pSpectatorInfo; |
297 | const CNetObj_SpectatorInfo *m_pPrevSpectatorInfo; |
298 | const CNetObj_Flag *m_apFlags[2]; |
299 | const CNetObj_GameInfo *m_pGameInfoObj; |
300 | const CNetObj_GameData *m_pGameDataObj; |
301 | int m_GameDataSnapId; |
302 | |
303 | const CNetObj_PlayerInfo *m_apPlayerInfos[MAX_CLIENTS]; |
304 | const CNetObj_PlayerInfo *m_apInfoByScore[MAX_CLIENTS]; |
305 | const CNetObj_PlayerInfo *m_apInfoByName[MAX_CLIENTS]; |
306 | const CNetObj_PlayerInfo *m_apInfoByDDTeamScore[MAX_CLIENTS]; |
307 | const CNetObj_PlayerInfo *m_apInfoByDDTeamName[MAX_CLIENTS]; |
308 | |
309 | int m_LocalClientId; |
310 | int m_NumPlayers; |
311 | int m_aTeamSize[2]; |
312 | |
313 | // spectate data |
314 | struct CSpectateInfo |
315 | { |
316 | bool m_Active; |
317 | int m_SpectatorId; |
318 | bool m_UsePosition; |
319 | vec2 m_Position; |
320 | } m_SpecInfo; |
321 | |
322 | // |
323 | struct CCharacterInfo |
324 | { |
325 | bool m_Active; |
326 | |
327 | // snapshots |
328 | CNetObj_Character m_Prev; |
329 | CNetObj_Character m_Cur; |
330 | |
331 | CNetObj_DDNetCharacter m_ExtendedData; |
332 | const CNetObj_DDNetCharacter *m_PrevExtendedData; |
333 | bool m_HasExtendedData; |
334 | bool m_HasExtendedDisplayInfo; |
335 | |
336 | // interpolated position |
337 | vec2 m_Position; |
338 | }; |
339 | |
340 | CCharacterInfo m_aCharacters[MAX_CLIENTS]; |
341 | }; |
342 | |
343 | CSnapState m_Snap; |
344 | int m_aLocalTuneZone[NUM_DUMMIES]; |
345 | bool m_aReceivedTuning[NUM_DUMMIES]; |
346 | int m_aExpectingTuningForZone[NUM_DUMMIES]; |
347 | int m_aExpectingTuningSince[NUM_DUMMIES]; |
348 | CTuningParams m_aTuning[NUM_DUMMIES]; |
349 | |
350 | // client data |
351 | struct CClientData |
352 | { |
353 | int m_UseCustomColor; |
354 | int m_ColorBody; |
355 | int m_ColorFeet; |
356 | |
357 | char m_aName[MAX_NAME_LENGTH]; |
358 | char m_aClan[MAX_CLAN_LENGTH]; |
359 | int m_Country; |
360 | char m_aSkinName[24]; |
361 | int m_SkinColor; |
362 | int m_Team; |
363 | int m_Emoticon; |
364 | float m_EmoticonStartFraction; |
365 | int m_EmoticonStartTick; |
366 | |
367 | bool m_Solo; |
368 | bool m_Jetpack; |
369 | bool m_CollisionDisabled; |
370 | bool m_EndlessHook; |
371 | bool m_EndlessJump; |
372 | bool m_HammerHitDisabled; |
373 | bool m_GrenadeHitDisabled; |
374 | bool m_LaserHitDisabled; |
375 | bool m_ShotgunHitDisabled; |
376 | bool m_HookHitDisabled; |
377 | bool m_Super; |
378 | bool m_HasTelegunGun; |
379 | bool m_HasTelegunGrenade; |
380 | bool m_HasTelegunLaser; |
381 | int m_FreezeEnd; |
382 | bool m_DeepFrozen; |
383 | bool m_LiveFrozen; |
384 | |
385 | CCharacterCore m_Predicted; |
386 | CCharacterCore m_PrevPredicted; |
387 | |
388 | CTeeRenderInfo m_SkinInfo; // this is what the server reports |
389 | CTeeRenderInfo m_RenderInfo; // this is what we use |
390 | |
391 | float m_Angle; |
392 | bool m_Active; |
393 | bool m_ChatIgnore; |
394 | bool m_EmoticonIgnore; |
395 | bool m_Friend; |
396 | bool m_Foe; |
397 | |
398 | int m_AuthLevel; |
399 | bool m_Afk; |
400 | bool m_Paused; |
401 | bool m_Spec; |
402 | |
403 | // Editor allows 256 switches for now. |
404 | bool m_aSwitchStates[256]; |
405 | |
406 | CNetObj_Character m_Snapped; |
407 | CNetObj_Character m_Evolved; |
408 | |
409 | // rendered characters |
410 | CNetObj_Character m_RenderCur; |
411 | CNetObj_Character m_RenderPrev; |
412 | vec2 m_RenderPos; |
413 | bool m_IsPredicted; |
414 | bool m_IsPredictedLocal; |
415 | int64_t m_aSmoothStart[2]; |
416 | int64_t m_aSmoothLen[2]; |
417 | vec2 m_aPredPos[200]; |
418 | int m_aPredTick[200]; |
419 | bool m_SpecCharPresent; |
420 | vec2 m_SpecChar; |
421 | |
422 | void UpdateRenderInfo(bool IsTeamPlay); |
423 | void Reset(); |
424 | }; |
425 | |
426 | CClientData m_aClients[MAX_CLIENTS]; |
427 | |
428 | class CClientStats |
429 | { |
430 | int m_IngameTicks; |
431 | int m_JoinTick; |
432 | bool m_Active; |
433 | |
434 | public: |
435 | CClientStats(); |
436 | |
437 | int m_aFragsWith[NUM_WEAPONS]; |
438 | int m_aDeathsFrom[NUM_WEAPONS]; |
439 | int m_Frags; |
440 | int m_Deaths; |
441 | int m_Suicides; |
442 | int m_BestSpree; |
443 | int m_CurrentSpree; |
444 | |
445 | int m_FlagGrabs; |
446 | int m_FlagCaptures; |
447 | |
448 | void Reset(); |
449 | |
450 | bool IsActive() const { return m_Active; } |
451 | void JoinGame(int Tick) |
452 | { |
453 | m_Active = true; |
454 | m_JoinTick = Tick; |
455 | }; |
456 | void JoinSpec(int Tick) |
457 | { |
458 | m_Active = false; |
459 | m_IngameTicks += Tick - m_JoinTick; |
460 | }; |
461 | int GetIngameTicks(int Tick) const { return m_IngameTicks + Tick - m_JoinTick; } |
462 | float GetFPM(int Tick, int TickSpeed) const { return (float)(m_Frags * TickSpeed * 60) / GetIngameTicks(Tick); } |
463 | }; |
464 | |
465 | CClientStats m_aStats[MAX_CLIENTS]; |
466 | |
467 | CRenderTools m_RenderTools; |
468 | |
469 | void OnReset(); |
470 | |
471 | size_t ComponentCount() { return m_vpAll.size(); } |
472 | |
473 | // hooks |
474 | void OnConnected() override; |
475 | void OnRender() override; |
476 | void OnUpdate() override; |
477 | void OnDummyDisconnect() override; |
478 | virtual void OnRelease(); |
479 | void OnInit() override; |
480 | void OnConsoleInit() override; |
481 | void OnStateChange(int NewState, int OldState) override; |
482 | void OnMessage(int MsgId, CUnpacker *pUnpacker, int Conn, bool Dummy) override; |
483 | void InvalidateSnapshot() override; |
484 | void OnNewSnapshot() override; |
485 | void OnPredict() override; |
486 | void OnActivateEditor() override; |
487 | void OnDummySwap() override; |
488 | int OnSnapInput(int *pData, bool Dummy, bool Force) override; |
489 | void OnShutdown() override; |
490 | void OnEnterGame() override; |
491 | void OnRconType(bool UsernameReq) override; |
492 | void OnRconLine(const char *pLine) override; |
493 | virtual void OnGameOver(); |
494 | virtual void OnStartGame(); |
495 | virtual void OnStartRound(); |
496 | virtual void OnFlagGrab(int TeamId); |
497 | void OnWindowResize() override; |
498 | |
499 | bool m_LanguageChanged = false; |
500 | void OnLanguageChange(); |
501 | void HandleLanguageChanged(); |
502 | |
503 | void RefreshSkins(); |
504 | |
505 | void RenderShutdownMessage() override; |
506 | |
507 | const char *GetItemName(int Type) const override; |
508 | const char *Version() const override; |
509 | const char *NetVersion() const override; |
510 | int DDNetVersion() const override; |
511 | const char *DDNetVersionStr() const override; |
512 | |
513 | // actions |
514 | // TODO: move these |
515 | void SendSwitchTeam(int Team); |
516 | void SendInfo(bool Start); |
517 | void SendDummyInfo(bool Start) override; |
518 | void SendKill(int ClientId) const; |
519 | |
520 | int m_NextChangeInfo; |
521 | |
522 | // DDRace |
523 | |
524 | int m_aLocalIds[NUM_DUMMIES]; |
525 | CNetObj_PlayerInput m_DummyInput; |
526 | CNetObj_PlayerInput m_HammerInput; |
527 | unsigned int m_DummyFire; |
528 | bool m_ReceivedDDNetPlayer; |
529 | |
530 | class CTeamsCore m_Teams; |
531 | |
532 | int IntersectCharacter(vec2 HookPos, vec2 NewPos, vec2 &NewPos2, int ownId); |
533 | |
534 | int GetLastRaceTick() const override; |
535 | |
536 | bool IsTeamPlay() { return m_Snap.m_pGameInfoObj && m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS; } |
537 | |
538 | bool AntiPingPlayers() { return g_Config.m_ClAntiPing && g_Config.m_ClAntiPingPlayers && !m_Snap.m_SpecInfo.m_Active && Client()->State() != IClient::STATE_DEMOPLAYBACK && (m_aTuning[g_Config.m_ClDummy].m_PlayerCollision || m_aTuning[g_Config.m_ClDummy].m_PlayerHooking); } |
539 | bool AntiPingGrenade() { return g_Config.m_ClAntiPing && g_Config.m_ClAntiPingGrenade && !m_Snap.m_SpecInfo.m_Active && Client()->State() != IClient::STATE_DEMOPLAYBACK; } |
540 | bool AntiPingWeapons() { return g_Config.m_ClAntiPing && g_Config.m_ClAntiPingWeapons && !m_Snap.m_SpecInfo.m_Active && Client()->State() != IClient::STATE_DEMOPLAYBACK; } |
541 | bool AntiPingGunfire() { return AntiPingGrenade() && AntiPingWeapons() && g_Config.m_ClAntiPingGunfire; } |
542 | bool Predict() const; |
543 | bool PredictDummy() { return g_Config.m_ClPredictDummy && Client()->DummyConnected() && m_Snap.m_LocalClientId >= 0 && m_PredictedDummyId >= 0 && !m_aClients[m_PredictedDummyId].m_Paused; } |
544 | const CTuningParams *GetTuning(int i) { return &m_aTuningList[i]; } |
545 | ColorRGBA GetDDTeamColor(int DDTeam, float Lightness = 0.5f) const; |
546 | |
547 | CGameWorld m_GameWorld; |
548 | CGameWorld m_PredictedWorld; |
549 | CGameWorld m_PrevPredictedWorld; |
550 | |
551 | std::vector<SSwitchers> &Switchers() { return m_GameWorld.m_Core.m_vSwitchers; } |
552 | std::vector<SSwitchers> &PredSwitchers() { return m_PredictedWorld.m_Core.m_vSwitchers; } |
553 | |
554 | void DummyResetInput() override; |
555 | void Echo(const char *pString) override; |
556 | bool IsOtherTeam(int ClientId) const; |
557 | int SwitchStateTeam() const; |
558 | bool IsLocalCharSuper() const; |
559 | bool CanDisplayWarning() const override; |
560 | CNetObjHandler *GetNetObjHandler() override; |
561 | |
562 | void LoadGameSkin(const char *pPath, bool AsDir = false); |
563 | void LoadEmoticonsSkin(const char *pPath, bool AsDir = false); |
564 | void LoadParticlesSkin(const char *pPath, bool AsDir = false); |
565 | void LoadHudSkin(const char *pPath, bool AsDir = false); |
566 | void (const char *pPath, bool AsDir = false); |
567 | |
568 | struct SClientGameSkin |
569 | { |
570 | // health armor hud |
571 | IGraphics::CTextureHandle m_SpriteHealthFull; |
572 | IGraphics::CTextureHandle m_SpriteHealthEmpty; |
573 | IGraphics::CTextureHandle m_SpriteArmorFull; |
574 | IGraphics::CTextureHandle m_SpriteArmorEmpty; |
575 | |
576 | // cursors |
577 | IGraphics::CTextureHandle m_SpriteWeaponHammerCursor; |
578 | IGraphics::CTextureHandle m_SpriteWeaponGunCursor; |
579 | IGraphics::CTextureHandle m_SpriteWeaponShotgunCursor; |
580 | IGraphics::CTextureHandle m_SpriteWeaponGrenadeCursor; |
581 | IGraphics::CTextureHandle m_SpriteWeaponNinjaCursor; |
582 | IGraphics::CTextureHandle m_SpriteWeaponLaserCursor; |
583 | |
584 | IGraphics::CTextureHandle m_aSpriteWeaponCursors[6]; |
585 | |
586 | // weapons and hook |
587 | IGraphics::CTextureHandle m_SpriteHookChain; |
588 | IGraphics::CTextureHandle m_SpriteHookHead; |
589 | IGraphics::CTextureHandle m_SpriteWeaponHammer; |
590 | IGraphics::CTextureHandle m_SpriteWeaponGun; |
591 | IGraphics::CTextureHandle m_SpriteWeaponShotgun; |
592 | IGraphics::CTextureHandle m_SpriteWeaponGrenade; |
593 | IGraphics::CTextureHandle m_SpriteWeaponNinja; |
594 | IGraphics::CTextureHandle m_SpriteWeaponLaser; |
595 | |
596 | IGraphics::CTextureHandle m_aSpriteWeapons[6]; |
597 | |
598 | // particles |
599 | IGraphics::CTextureHandle m_aSpriteParticles[9]; |
600 | |
601 | // stars |
602 | IGraphics::CTextureHandle m_aSpriteStars[3]; |
603 | |
604 | // projectiles |
605 | IGraphics::CTextureHandle m_SpriteWeaponGunProjectile; |
606 | IGraphics::CTextureHandle m_SpriteWeaponShotgunProjectile; |
607 | IGraphics::CTextureHandle m_SpriteWeaponGrenadeProjectile; |
608 | IGraphics::CTextureHandle m_SpriteWeaponHammerProjectile; |
609 | IGraphics::CTextureHandle m_SpriteWeaponNinjaProjectile; |
610 | IGraphics::CTextureHandle m_SpriteWeaponLaserProjectile; |
611 | |
612 | IGraphics::CTextureHandle m_aSpriteWeaponProjectiles[6]; |
613 | |
614 | // muzzles |
615 | IGraphics::CTextureHandle m_aSpriteWeaponGunMuzzles[3]; |
616 | IGraphics::CTextureHandle m_aSpriteWeaponShotgunMuzzles[3]; |
617 | IGraphics::CTextureHandle m_aaSpriteWeaponNinjaMuzzles[3]; |
618 | |
619 | IGraphics::CTextureHandle m_aaSpriteWeaponsMuzzles[6][3]; |
620 | |
621 | // pickups |
622 | IGraphics::CTextureHandle m_SpritePickupHealth; |
623 | IGraphics::CTextureHandle m_SpritePickupArmor; |
624 | IGraphics::CTextureHandle m_SpritePickupArmorShotgun; |
625 | IGraphics::CTextureHandle m_SpritePickupArmorGrenade; |
626 | IGraphics::CTextureHandle m_SpritePickupArmorNinja; |
627 | IGraphics::CTextureHandle m_SpritePickupArmorLaser; |
628 | IGraphics::CTextureHandle m_SpritePickupGrenade; |
629 | IGraphics::CTextureHandle m_SpritePickupShotgun; |
630 | IGraphics::CTextureHandle m_SpritePickupLaser; |
631 | IGraphics::CTextureHandle m_SpritePickupNinja; |
632 | IGraphics::CTextureHandle m_SpritePickupGun; |
633 | IGraphics::CTextureHandle m_SpritePickupHammer; |
634 | |
635 | IGraphics::CTextureHandle m_aSpritePickupWeapons[6]; |
636 | IGraphics::CTextureHandle m_aSpritePickupWeaponArmor[4]; |
637 | |
638 | // flags |
639 | IGraphics::CTextureHandle m_SpriteFlagBlue; |
640 | IGraphics::CTextureHandle m_SpriteFlagRed; |
641 | |
642 | // ninja bar (0.7) |
643 | IGraphics::CTextureHandle m_SpriteNinjaBarFullLeft; |
644 | IGraphics::CTextureHandle m_SpriteNinjaBarFull; |
645 | IGraphics::CTextureHandle m_SpriteNinjaBarEmpty; |
646 | IGraphics::CTextureHandle m_SpriteNinjaBarEmptyRight; |
647 | |
648 | bool IsSixup() |
649 | { |
650 | return m_SpriteNinjaBarFullLeft.IsValid(); |
651 | } |
652 | }; |
653 | |
654 | SClientGameSkin m_GameSkin; |
655 | bool m_GameSkinLoaded = false; |
656 | |
657 | struct SClientParticlesSkin |
658 | { |
659 | IGraphics::CTextureHandle m_SpriteParticleSlice; |
660 | IGraphics::CTextureHandle m_SpriteParticleBall; |
661 | IGraphics::CTextureHandle m_aSpriteParticleSplat[3]; |
662 | IGraphics::CTextureHandle m_SpriteParticleSmoke; |
663 | IGraphics::CTextureHandle m_SpriteParticleShell; |
664 | IGraphics::CTextureHandle m_SpriteParticleExpl; |
665 | IGraphics::CTextureHandle m_SpriteParticleAirJump; |
666 | IGraphics::CTextureHandle m_SpriteParticleHit; |
667 | IGraphics::CTextureHandle m_aSpriteParticles[10]; |
668 | }; |
669 | |
670 | SClientParticlesSkin m_ParticlesSkin; |
671 | bool m_ParticlesSkinLoaded = false; |
672 | |
673 | struct SClientEmoticonsSkin |
674 | { |
675 | IGraphics::CTextureHandle m_aSpriteEmoticons[16]; |
676 | }; |
677 | |
678 | SClientEmoticonsSkin m_EmoticonsSkin; |
679 | bool m_EmoticonsSkinLoaded = false; |
680 | |
681 | struct SClientHudSkin |
682 | { |
683 | IGraphics::CTextureHandle m_SpriteHudAirjump; |
684 | IGraphics::CTextureHandle m_SpriteHudAirjumpEmpty; |
685 | IGraphics::CTextureHandle m_SpriteHudSolo; |
686 | IGraphics::CTextureHandle m_SpriteHudCollisionDisabled; |
687 | IGraphics::CTextureHandle m_SpriteHudEndlessJump; |
688 | IGraphics::CTextureHandle m_SpriteHudEndlessHook; |
689 | IGraphics::CTextureHandle m_SpriteHudJetpack; |
690 | IGraphics::CTextureHandle m_SpriteHudFreezeBarFullLeft; |
691 | IGraphics::CTextureHandle m_SpriteHudFreezeBarFull; |
692 | IGraphics::CTextureHandle m_SpriteHudFreezeBarEmpty; |
693 | IGraphics::CTextureHandle m_SpriteHudFreezeBarEmptyRight; |
694 | IGraphics::CTextureHandle m_SpriteHudNinjaBarFullLeft; |
695 | IGraphics::CTextureHandle m_SpriteHudNinjaBarFull; |
696 | IGraphics::CTextureHandle m_SpriteHudNinjaBarEmpty; |
697 | IGraphics::CTextureHandle m_SpriteHudNinjaBarEmptyRight; |
698 | IGraphics::CTextureHandle m_SpriteHudHookHitDisabled; |
699 | IGraphics::CTextureHandle m_SpriteHudHammerHitDisabled; |
700 | IGraphics::CTextureHandle m_SpriteHudShotgunHitDisabled; |
701 | IGraphics::CTextureHandle m_SpriteHudGrenadeHitDisabled; |
702 | IGraphics::CTextureHandle m_SpriteHudLaserHitDisabled; |
703 | IGraphics::CTextureHandle m_SpriteHudGunHitDisabled; |
704 | IGraphics::CTextureHandle m_SpriteHudDeepFrozen; |
705 | IGraphics::CTextureHandle m_SpriteHudLiveFrozen; |
706 | IGraphics::CTextureHandle m_SpriteHudTeleportGrenade; |
707 | IGraphics::CTextureHandle m_SpriteHudTeleportGun; |
708 | IGraphics::CTextureHandle m_SpriteHudTeleportLaser; |
709 | IGraphics::CTextureHandle m_SpriteHudPracticeMode; |
710 | IGraphics::CTextureHandle m_SpriteHudLockMode; |
711 | IGraphics::CTextureHandle m_SpriteHudTeam0Mode; |
712 | IGraphics::CTextureHandle m_SpriteHudDummyHammer; |
713 | IGraphics::CTextureHandle m_SpriteHudDummyCopy; |
714 | }; |
715 | |
716 | SClientHudSkin m_HudSkin; |
717 | bool m_HudSkinLoaded = false; |
718 | |
719 | struct |
720 | { |
721 | IGraphics::CTextureHandle m_SpriteParticleSnowflake; |
722 | IGraphics::CTextureHandle m_aSpriteParticles[1]; |
723 | }; |
724 | |
725 | SClientExtrasSkin ; |
726 | bool = false; |
727 | |
728 | const std::vector<CSnapEntities> &SnapEntities() { return m_vSnapEntities; } |
729 | |
730 | int m_MultiViewTeam; |
731 | int m_MultiViewPersonalZoom; |
732 | bool m_MultiViewShowHud; |
733 | bool m_MultiViewActivated; |
734 | bool m_aMultiViewId[MAX_CLIENTS]; |
735 | |
736 | void ResetMultiView(); |
737 | int FindFirstMultiViewId(); |
738 | void CleanMultiViewId(int ClientId); |
739 | |
740 | private: |
741 | std::vector<CSnapEntities> m_vSnapEntities; |
742 | void SnapCollectEntities(); |
743 | |
744 | bool m_aDDRaceMsgSent[NUM_DUMMIES]; |
745 | int m_aShowOthers[NUM_DUMMIES]; |
746 | |
747 | void UpdatePrediction(); |
748 | void UpdateRenderedCharacters(); |
749 | |
750 | int m_aLastUpdateTick[MAX_CLIENTS] = {0}; |
751 | void DetectStrongHook(); |
752 | |
753 | vec2 GetSmoothPos(int ClientId); |
754 | |
755 | int m_PredictedDummyId; |
756 | int m_IsDummySwapping; |
757 | CCharOrder m_CharOrder; |
758 | int m_aSwitchStateTeam[NUM_DUMMIES]; |
759 | |
760 | enum |
761 | { |
762 | NUM_TUNEZONES = 256 |
763 | }; |
764 | void LoadMapSettings(); |
765 | CTuningParams m_aTuningList[NUM_TUNEZONES]; |
766 | CTuningParams *TuningList() { return m_aTuningList; } |
767 | |
768 | float m_LastZoom; |
769 | float m_LastScreenAspect; |
770 | bool m_LastDummyConnected; |
771 | |
772 | void HandleMultiView(); |
773 | bool IsMultiViewIdSet(); |
774 | void CleanMultiViewIds(); |
775 | bool InitMultiView(int Team); |
776 | float CalculateMultiViewMultiplier(vec2 TargetPos); |
777 | float CalculateMultiViewZoom(vec2 MinPos, vec2 MaxPos, float Vel); |
778 | float MapValue(float MaxValue, float MinValue, float MaxRange, float MinRange, float Value); |
779 | |
780 | struct SMultiView |
781 | { |
782 | bool m_Solo; |
783 | bool m_IsInit; |
784 | bool m_Teleported; |
785 | bool m_aVanish[MAX_CLIENTS]; |
786 | vec2 m_OldPos; |
787 | int m_OldPersonalZoom; |
788 | float m_SecondChance; |
789 | float m_OldCameraDistance; |
790 | float m_aLastFreeze[MAX_CLIENTS]; |
791 | }; |
792 | |
793 | SMultiView m_MultiView; |
794 | }; |
795 | |
796 | ColorRGBA CalculateNameColor(ColorHSLA TextColorHSL); |
797 | |
798 | #endif |
799 | |