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