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
57class CGameInfo
58{
59public:
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
103class CSnapEntities
104{
105public:
106 IClient::CSnapItem m_Item;
107 const void *m_pData;
108 const CNetObj_EntityEx *m_pDataEx;
109};
110
111class CGameClient : public IGameClient
112{
113public:
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 m_Menus;
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 m_MenuBackground;
149
150 CMapSounds m_MapSounds;
151
152 CRaceDemo m_RaceDemo;
153 CGhost m_Ghost;
154
155 CTooltips m_Tooltips;
156
157private:
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 ConchainMenuMap(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
228public:
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 LoadExtrasSkin(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 SClientExtrasSkin
720 {
721 IGraphics::CTextureHandle m_SpriteParticleSnowflake;
722 IGraphics::CTextureHandle m_aSpriteParticles[1];
723 };
724
725 SClientExtrasSkin m_ExtrasSkin;
726 bool m_ExtrasSkinLoaded = 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
740private:
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
796ColorRGBA CalculateNameColor(ColorHSLA TextColorHSL);
797
798#endif
799