| 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 | |
| 8 | #include <base/color.h> |
| 9 | #include <base/types.h> |
| 10 | #include <base/vmath.h> |
| 11 | |
| 12 | #include <engine/client.h> |
| 13 | #include <engine/client/enums.h> |
| 14 | #include <engine/console.h> |
| 15 | #include <engine/shared/config.h> |
| 16 | #include <engine/shared/snapshot.h> |
| 17 | |
| 18 | #include <generated/protocol7.h> |
| 19 | #include <generated/protocolglue.h> |
| 20 | |
| 21 | #include <game/client/prediction/gameworld.h> |
| 22 | #include <game/client/race.h> |
| 23 | #include <game/collision.h> |
| 24 | #include <game/gamecore.h> |
| 25 | #include <game/layers.h> |
| 26 | #include <game/map/render_map.h> |
| 27 | #include <game/mapbugs.h> |
| 28 | #include <game/teamscore.h> |
| 29 | |
| 30 | // components |
| 31 | #include "components/background.h" |
| 32 | #include "components/binds.h" |
| 33 | #include "components/broadcast.h" |
| 34 | #include "components/camera.h" |
| 35 | #include "components/censor.h" |
| 36 | #include "components/chat.h" |
| 37 | #include "components/console.h" |
| 38 | #include "components/controls.h" |
| 39 | #include "components/countryflags.h" |
| 40 | #include "components/damageind.h" |
| 41 | #include "components/debughud.h" |
| 42 | #include "components/effects.h" |
| 43 | #include "components/emoticon.h" |
| 44 | #include "components/flow.h" |
| 45 | #include "components/freezebars.h" |
| 46 | #include "components/ghost.h" |
| 47 | #include "components/hud.h" |
| 48 | #include "components/important_alert.h" |
| 49 | #include "components/infomessages.h" |
| 50 | #include "components/items.h" |
| 51 | #include "components/key_binder.h" |
| 52 | #include "components/local_server.h" |
| 53 | #include "components/mapimages.h" |
| 54 | #include "components/maplayers.h" |
| 55 | #include "components/mapsounds.h" |
| 56 | #include "components/menu_background.h" |
| 57 | #include "components/menus.h" |
| 58 | #include "components/motd.h" |
| 59 | #include "components/nameplates.h" |
| 60 | #include "components/particles.h" |
| 61 | #include "components/players.h" |
| 62 | #include "components/race_demo.h" |
| 63 | #include "components/scoreboard.h" |
| 64 | #include "components/skins.h" |
| 65 | #include "components/skins7.h" |
| 66 | #include "components/sounds.h" |
| 67 | #include "components/spectator.h" |
| 68 | #include "components/statboard.h" |
| 69 | #include "components/tooltips.h" |
| 70 | #include "components/touch_controls.h" |
| 71 | #include "components/voting.h" |
| 72 | |
| 73 | #include <memory> |
| 74 | #include <vector> |
| 75 | |
| 76 | class IMap; |
| 77 | |
| 78 | class CGameInfo |
| 79 | { |
| 80 | public: |
| 81 | bool m_FlagStartsRace; |
| 82 | bool m_TimeScore; |
| 83 | bool m_UnlimitedAmmo; |
| 84 | bool m_DDRaceRecordMessage; |
| 85 | bool m_RaceRecordMessage; |
| 86 | bool m_RaceSounds; |
| 87 | |
| 88 | bool m_AllowEyeWheel; |
| 89 | bool m_AllowHookColl; |
| 90 | bool m_AllowZoom; |
| 91 | |
| 92 | bool m_BugDDRaceGhost; |
| 93 | bool m_BugDDRaceInput; |
| 94 | bool m_BugFNGLaserRange; |
| 95 | bool m_BugVanillaBounce; |
| 96 | |
| 97 | bool m_PredictFNG; |
| 98 | bool m_PredictDDRace; |
| 99 | bool m_PredictDDRaceTiles; |
| 100 | bool m_PredictVanilla; |
| 101 | |
| 102 | bool m_EntitiesDDNet; |
| 103 | bool m_EntitiesDDRace; |
| 104 | bool m_EntitiesRace; |
| 105 | bool m_EntitiesFNG; |
| 106 | bool m_EntitiesVanilla; |
| 107 | bool m_EntitiesBW; |
| 108 | bool m_EntitiesFDDrace; |
| 109 | |
| 110 | bool m_Race; |
| 111 | bool m_Pvp; |
| 112 | |
| 113 | bool m_DontMaskEntities; |
| 114 | bool m_AllowXSkins; |
| 115 | |
| 116 | bool m_HudHealthArmor; |
| 117 | bool m_HudAmmo; |
| 118 | bool m_HudDDRace; |
| 119 | |
| 120 | bool m_NoWeakHookAndBounce; |
| 121 | bool m_NoSkinChangeForFrozen; |
| 122 | |
| 123 | bool m_DDRaceTeam; |
| 124 | |
| 125 | bool m_PredictEvents; |
| 126 | |
| 127 | bool m_Supports128Teams; |
| 128 | }; |
| 129 | |
| 130 | class CSnapEntities |
| 131 | { |
| 132 | public: |
| 133 | IClient::CSnapItem m_Item; |
| 134 | const CNetObj_EntityEx *m_pDataEx; |
| 135 | }; |
| 136 | |
| 137 | enum class EClientIdFormat |
| 138 | { |
| 139 | NO_INDENT, |
| 140 | INDENT_AUTO, |
| 141 | INDENT_FORCE, // for rendering settings preview |
| 142 | }; |
| 143 | |
| 144 | class CGameClient : public IGameClient |
| 145 | { |
| 146 | public: |
| 147 | // all components |
| 148 | CInfoMessages m_InfoMessages; |
| 149 | CCamera m_Camera; |
| 150 | CChat m_Chat; |
| 151 | CCensor m_Censor; |
| 152 | CMotd m_Motd; |
| 153 | CBroadcast m_Broadcast; |
| 154 | CGameConsole m_GameConsole; |
| 155 | CBinds m_Binds; |
| 156 | CKeyBinder m_KeyBinder; |
| 157 | CParticles m_Particles; |
| 158 | CMenus ; |
| 159 | CSkins m_Skins; |
| 160 | CSkins7 m_Skins7; |
| 161 | CCountryFlags m_CountryFlags; |
| 162 | CFlow m_Flow; |
| 163 | CHud m_Hud; |
| 164 | CImportantAlert m_ImportantAlert; |
| 165 | CDebugHud m_DebugHud; |
| 166 | CControls m_Controls; |
| 167 | CEffects m_Effects; |
| 168 | CScoreboard m_Scoreboard; |
| 169 | CStatboard m_Statboard; |
| 170 | CSounds m_Sounds; |
| 171 | CEmoticon m_Emoticon; |
| 172 | CDamageInd m_DamageInd; |
| 173 | CTouchControls m_TouchControls; |
| 174 | CVoting m_Voting; |
| 175 | CSpectator m_Spectator; |
| 176 | |
| 177 | CPlayers m_Players; |
| 178 | CNamePlates m_NamePlates; |
| 179 | CFreezeBars m_FreezeBars; |
| 180 | CItems m_Items; |
| 181 | CMapImages m_MapImages; |
| 182 | |
| 183 | CMapLayers m_MapLayersBackground = CMapLayers{ERenderType::RENDERTYPE_BACKGROUND}; |
| 184 | CMapLayers m_MapLayersForeground = CMapLayers{ERenderType::RENDERTYPE_FOREGROUND}; |
| 185 | CBackground m_Background; |
| 186 | CMenuBackground ; |
| 187 | |
| 188 | CMapSounds m_MapSounds; |
| 189 | |
| 190 | CRaceDemo m_RaceDemo; |
| 191 | CGhost m_Ghost; |
| 192 | |
| 193 | CTooltips m_Tooltips; |
| 194 | |
| 195 | CLocalServer m_LocalServer; |
| 196 | |
| 197 | private: |
| 198 | std::vector<class CComponent *> m_vpAll; |
| 199 | std::vector<class CComponent *> m_vpInput; |
| 200 | CNetObjHandler m_NetObjHandler; |
| 201 | protocol7::CNetObjHandler m_NetObjHandler7; |
| 202 | |
| 203 | class IEngine *m_pEngine; |
| 204 | class IInput *m_pInput; |
| 205 | class IGraphics *m_pGraphics; |
| 206 | class ITextRender *m_pTextRender; |
| 207 | class IClient *m_pClient; |
| 208 | class ISound *m_pSound; |
| 209 | class IConfigManager *m_pConfigManager; |
| 210 | class CConfig *m_pConfig; |
| 211 | class IConsole *m_pConsole; |
| 212 | class IStorage *m_pStorage; |
| 213 | class IDemoPlayer *m_pDemoPlayer; |
| 214 | class IFavorites *m_pFavorites; |
| 215 | class IServerBrowser *m_pServerBrowser; |
| 216 | class IEditor *m_pEditor; |
| 217 | class IFriends *m_pFriends; |
| 218 | class IFriends *m_pFoes; |
| 219 | class IDiscord *m_pDiscord; |
| 220 | #if defined(CONF_AUTOUPDATE) |
| 221 | class IUpdater *m_pUpdater; |
| 222 | #endif |
| 223 | class IHttp *m_pHttp; |
| 224 | |
| 225 | CLayers m_Layers; |
| 226 | CCollision m_Collision; |
| 227 | CUi m_UI; |
| 228 | CRaceHelper m_RaceHelper; |
| 229 | |
| 230 | void ProcessEvents(); |
| 231 | void UpdatePositions(); |
| 232 | |
| 233 | int m_EditorMovementDelay = 5; |
| 234 | void UpdateEditorIngameMoved(); |
| 235 | |
| 236 | int m_PredictedTick; |
| 237 | int m_aLastNewPredictedTick[NUM_DUMMIES]; |
| 238 | |
| 239 | int m_LastRoundStartTick; |
| 240 | int m_LastRaceTick; |
| 241 | |
| 242 | int m_LastFlagCarrierRed; |
| 243 | int m_LastFlagCarrierBlue; |
| 244 | |
| 245 | int m_aCheckInfo[NUM_DUMMIES]; |
| 246 | |
| 247 | char m_aDDNetVersionStr[64]; |
| 248 | |
| 249 | static void ConTeam(IConsole::IResult *pResult, void *pUserData); |
| 250 | static void ConKill(IConsole::IResult *pResult, void *pUserData); |
| 251 | static void ConReadyChange7(IConsole::IResult *pResult, void *pUserData); |
| 252 | |
| 253 | static void ConchainLanguageUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
| 254 | static void ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
| 255 | static void ConchainSpecialDummyInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
| 256 | static void ConchainRefreshSkins(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
| 257 | static void ConchainRefreshEventSkins(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
| 258 | static void ConchainSpecialDummy(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
| 259 | |
| 260 | static void ConTuneParam(IConsole::IResult *pResult, void *pUserData); |
| 261 | static void ConTuneZone(IConsole::IResult *pResult, void *pUserData); |
| 262 | static void ConMapbug(IConsole::IResult *pResult, void *pUserData); |
| 263 | |
| 264 | static void (IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
| 265 | |
| 266 | static std::function<bool(int, int, int, int)> GetScoreComparator(bool TimeScore, bool ReceivedMillisecondFinishTimes, bool Race7); |
| 267 | |
| 268 | // only used in OnPredict |
| 269 | vec2 m_aLastPos[MAX_CLIENTS]; |
| 270 | bool m_aLastActive[MAX_CLIENTS]; |
| 271 | |
| 272 | // only used in OnNewSnapshot |
| 273 | bool m_GameOver = false; |
| 274 | bool m_GamePaused = false; |
| 275 | |
| 276 | public: |
| 277 | IKernel *Kernel() { return IInterface::Kernel(); } |
| 278 | IEngine *Engine() const { return m_pEngine; } |
| 279 | class IGraphics *Graphics() const { return m_pGraphics; } |
| 280 | class IClient *Client() const { return m_pClient; } |
| 281 | class CUi *Ui() { return &m_UI; } |
| 282 | class ISound *Sound() const { return m_pSound; } |
| 283 | class IInput *Input() const { return m_pInput; } |
| 284 | class IStorage *Storage() const { return m_pStorage; } |
| 285 | class IConfigManager *ConfigManager() const { return m_pConfigManager; } |
| 286 | class CConfig *Config() const { return m_pConfig; } |
| 287 | class IConsole *Console() { return m_pConsole; } |
| 288 | class ITextRender *TextRender() const { return m_pTextRender; } |
| 289 | class IDemoPlayer *DemoPlayer() const { return m_pDemoPlayer; } |
| 290 | class IDemoRecorder *DemoRecorder(int Recorder) const { return Client()->DemoRecorder(Recorder); } |
| 291 | class IFavorites *Favorites() const { return m_pFavorites; } |
| 292 | class IServerBrowser *ServerBrowser() const { return m_pServerBrowser; } |
| 293 | class CRenderTools *RenderTools() { return &m_RenderTools; } |
| 294 | class CRenderMap *RenderMap() { return &m_RenderMap; } |
| 295 | class CLayers *Layers() { return &m_Layers; } |
| 296 | CCollision *Collision() { return &m_Collision; } |
| 297 | const CCollision *Collision() const { return &m_Collision; } |
| 298 | const CRaceHelper *RaceHelper() const { return &m_RaceHelper; } |
| 299 | class IEditor *Editor() { return m_pEditor; } |
| 300 | class IFriends *Friends() { return m_pFriends; } |
| 301 | class IFriends *Foes() { return m_pFoes; } |
| 302 | #if defined(CONF_AUTOUPDATE) |
| 303 | class IUpdater *Updater() |
| 304 | { |
| 305 | return m_pUpdater; |
| 306 | } |
| 307 | #endif |
| 308 | class IHttp *Http() |
| 309 | { |
| 310 | return m_pHttp; |
| 311 | } |
| 312 | |
| 313 | int NetobjNumCorrections() |
| 314 | { |
| 315 | return m_NetObjHandler.NumObjCorrections(); |
| 316 | } |
| 317 | const char *NetobjCorrectedOn() { return m_NetObjHandler.CorrectedObjOn(); } |
| 318 | |
| 319 | bool m_SuppressEvents; |
| 320 | bool m_NewTick; |
| 321 | bool m_NewPredictedTick; |
| 322 | int m_aFlagDropTick[2]; |
| 323 | |
| 324 | enum |
| 325 | { |
| 326 | SERVERMODE_PURE = 0, |
| 327 | SERVERMODE_MOD, |
| 328 | SERVERMODE_PUREMOD, |
| 329 | }; |
| 330 | int m_ServerMode; |
| 331 | CGameInfo m_GameInfo; |
| 332 | |
| 333 | int m_DemoSpecId; |
| 334 | |
| 335 | vec2 m_LocalCharacterPos; |
| 336 | |
| 337 | /** |
| 338 | * Our prediction for the local character at tick |
| 339 | * `IClient::PredGameTick() - 1`. |
| 340 | */ |
| 341 | CCharacterCore m_PredictedPrevChar; |
| 342 | /** |
| 343 | * Our prediction for the local character at tick |
| 344 | * `IClient::PredGameTick()`. |
| 345 | */ |
| 346 | CCharacterCore m_PredictedChar; |
| 347 | |
| 348 | // snap pointers |
| 349 | class CSnapState |
| 350 | { |
| 351 | public: |
| 352 | const CNetObj_Character *m_pLocalCharacter; |
| 353 | const CNetObj_Character *m_pLocalPrevCharacter; |
| 354 | const CNetObj_PlayerInfo *m_pLocalInfo; |
| 355 | const CNetObj_SpectatorInfo *m_pSpectatorInfo; |
| 356 | const CNetObj_SpectatorInfo *m_pPrevSpectatorInfo; |
| 357 | const CNetObj_SpectatorCount *m_pSpectatorCount; |
| 358 | int m_NumFlags; |
| 359 | const CNetObj_Flag *m_apFlags[CSnapshot::MAX_ITEMS]; |
| 360 | const CNetObj_Flag *m_apPrevFlags[CSnapshot::MAX_ITEMS]; |
| 361 | const CNetObj_GameInfo *m_pGameInfoObj; |
| 362 | const CNetObj_GameData *m_pGameDataObj; |
| 363 | const CNetObj_GameData *m_pPrevGameDataObj; |
| 364 | |
| 365 | const CNetObj_PlayerInfo *m_apPlayerInfos[MAX_CLIENTS]; |
| 366 | const CNetObj_PlayerInfo *m_apPrevPlayerInfos[MAX_CLIENTS]; |
| 367 | |
| 368 | const CNetObj_PlayerInfo *m_apInfoByScore[MAX_CLIENTS]; |
| 369 | const CNetObj_PlayerInfo *m_apInfoByName[MAX_CLIENTS]; |
| 370 | const CNetObj_PlayerInfo *m_apInfoByDDTeamScore[MAX_CLIENTS]; |
| 371 | const CNetObj_PlayerInfo *m_apInfoByDDTeamName[MAX_CLIENTS]; |
| 372 | |
| 373 | int m_LocalClientId; |
| 374 | int m_NumPlayers; |
| 375 | int m_aTeamSize[2]; |
| 376 | int m_HighestClientId; |
| 377 | |
| 378 | class CSpectateInfo |
| 379 | { |
| 380 | public: |
| 381 | bool m_Active; |
| 382 | int m_SpectatorId; |
| 383 | bool m_UsePosition; |
| 384 | vec2 m_Position; |
| 385 | |
| 386 | bool m_HasCameraInfo; |
| 387 | float m_Zoom; |
| 388 | int m_Deadzone; |
| 389 | int m_FollowFactor; |
| 390 | }; |
| 391 | CSpectateInfo m_SpecInfo; |
| 392 | |
| 393 | class CCharacterInfo |
| 394 | { |
| 395 | public: |
| 396 | bool m_Active; |
| 397 | |
| 398 | // snapshots |
| 399 | CNetObj_Character m_Prev; |
| 400 | CNetObj_Character m_Cur; |
| 401 | |
| 402 | CNetObj_DDNetCharacter m_ExtendedData; |
| 403 | const CNetObj_DDNetCharacter *m_pPrevExtendedData; |
| 404 | bool m_HasExtendedData; |
| 405 | bool m_HasExtendedDisplayInfo; |
| 406 | }; |
| 407 | CCharacterInfo m_aCharacters[MAX_CLIENTS]; |
| 408 | }; |
| 409 | |
| 410 | CSnapState m_Snap; |
| 411 | int m_aLocalTuneZone[NUM_DUMMIES]; // current tunezone (0-255) |
| 412 | bool m_aReceivedTuning[NUM_DUMMIES]; // was tuning message received after zone change |
| 413 | int m_aExpectingTuningForZone[NUM_DUMMIES]; // tunezone changed, waiting for tuning for that zone |
| 414 | int m_aExpectingTuningSince[NUM_DUMMIES]; // how many snaps received since tunezone changed |
| 415 | CTuningParams m_aTuning[NUM_DUMMIES]; // current local player tuning, only what the player/dummy has |
| 416 | |
| 417 | std::bitset<RECORDER_MAX> m_ActiveRecordings; |
| 418 | |
| 419 | // spectate cursor data |
| 420 | class CCursorInfo |
| 421 | { |
| 422 | friend class CGameClient; |
| 423 | static constexpr int CURSOR_SAMPLES = 8; // how many samples to keep |
| 424 | static constexpr int SAMPLE_FRAME_WINDOW = 3; // how many samples should be used for polynomial interpolation |
| 425 | static constexpr int SAMPLE_FRAME_OFFSET = 2; // how many samples in the past should be included |
| 426 | static constexpr double INTERP_DELAY = 4.25; // how many ticks in the past to show, enables extrapolation with smaller value (<= SAMPLE_FRAME_WINDOW - SAMPLE_FRAME_OFFSET + 3) |
| 427 | static constexpr double REST_THRESHOLD = 3.0; // how many ticks of the same samples are considered to be resting |
| 428 | |
| 429 | int m_CursorOwnerId; |
| 430 | double m_aTargetSamplesTime[CURSOR_SAMPLES]; |
| 431 | vec2 m_aTargetSamplesData[CURSOR_SAMPLES]; |
| 432 | int m_NumSamples; |
| 433 | |
| 434 | bool m_Available; |
| 435 | int m_Weapon; |
| 436 | vec2 m_Target; |
| 437 | vec2 m_WorldTarget; |
| 438 | vec2 m_Position; |
| 439 | |
| 440 | public: |
| 441 | bool IsAvailable() const { return m_Available; } |
| 442 | int Weapon() const { return m_Weapon; } |
| 443 | vec2 Target() const { return m_Target; } |
| 444 | vec2 WorldTarget() const { return m_WorldTarget; } |
| 445 | vec2 Position() const { return m_Position; } |
| 446 | } m_CursorInfo; |
| 447 | |
| 448 | // client data |
| 449 | class CClientData |
| 450 | { |
| 451 | friend class CGameClient; |
| 452 | CGameClient *m_pGameClient; |
| 453 | int m_ClientId; |
| 454 | |
| 455 | public: |
| 456 | int m_UseCustomColor; |
| 457 | int m_ColorBody; |
| 458 | int m_ColorFeet; |
| 459 | |
| 460 | char m_aName[MAX_NAME_LENGTH]; |
| 461 | char m_aClan[MAX_CLAN_LENGTH]; |
| 462 | /** |
| 463 | * Country code in ISO 3166-1 numeric. |
| 464 | */ |
| 465 | int m_Country; |
| 466 | char m_aSkinName[MAX_SKIN_LENGTH]; |
| 467 | int m_Team; |
| 468 | int m_Emoticon; |
| 469 | float m_EmoticonStartFraction; |
| 470 | int m_EmoticonStartTick; |
| 471 | |
| 472 | bool m_Solo; |
| 473 | bool m_Jetpack; |
| 474 | bool m_CollisionDisabled; |
| 475 | bool m_EndlessHook; |
| 476 | bool m_EndlessJump; |
| 477 | bool m_HammerHitDisabled; |
| 478 | bool m_GrenadeHitDisabled; |
| 479 | bool m_LaserHitDisabled; |
| 480 | bool m_ShotgunHitDisabled; |
| 481 | bool m_HookHitDisabled; |
| 482 | bool m_Super; |
| 483 | bool m_Invincible; |
| 484 | bool m_HasTelegunGun; |
| 485 | bool m_HasTelegunGrenade; |
| 486 | bool m_HasTelegunLaser; |
| 487 | int m_FreezeEnd; |
| 488 | bool m_DeepFrozen; |
| 489 | bool m_LiveFrozen; |
| 490 | |
| 491 | CCharacterCore m_Predicted; |
| 492 | CCharacterCore m_PrevPredicted; |
| 493 | |
| 494 | std::shared_ptr<CManagedTeeRenderInfo> m_pSkinInfo = nullptr; // this is what the server reports |
| 495 | CTeeRenderInfo m_RenderInfo; // this is what we use |
| 496 | |
| 497 | float m_Angle; |
| 498 | bool m_Active; |
| 499 | bool m_ChatIgnore; |
| 500 | bool m_EmoticonIgnore; |
| 501 | bool m_Friend; |
| 502 | bool m_Foe; |
| 503 | |
| 504 | int m_AuthLevel; |
| 505 | bool m_Afk; |
| 506 | bool m_Paused; |
| 507 | bool m_Spec; |
| 508 | |
| 509 | int m_FinishTimeSeconds; |
| 510 | int m_FinishTimeMillis; |
| 511 | |
| 512 | // Editor allows 256 switches for now. |
| 513 | bool m_aSwitchStates[256]; |
| 514 | |
| 515 | CNetObj_Character m_Snapped; |
| 516 | CNetObj_Character m_Evolved; |
| 517 | |
| 518 | CNetMsg_Sv_PreInput m_aPreInputs[200]; |
| 519 | |
| 520 | // rendered characters |
| 521 | CNetObj_Character m_RenderCur; |
| 522 | CNetObj_Character m_RenderPrev; |
| 523 | vec2 m_RenderPos; |
| 524 | bool m_IsPredicted; |
| 525 | bool m_IsPredictedLocal; |
| 526 | int64_t m_aSmoothStart[2]; |
| 527 | int64_t m_aSmoothLen[2]; |
| 528 | vec2 m_aPredPos[200]; |
| 529 | int m_aPredTick[200]; |
| 530 | bool m_SpecCharPresent; |
| 531 | vec2 m_SpecChar; |
| 532 | |
| 533 | void UpdateSkinInfo(); |
| 534 | void UpdateSkin7HatSprite(int Dummy); |
| 535 | void UpdateSkin7BotDecoration(int Dummy); |
| 536 | void UpdateRenderInfo(); |
| 537 | void Reset(); |
| 538 | CSkinDescriptor ToSkinDescriptor() const; |
| 539 | |
| 540 | int ClientId() const { return m_ClientId; } |
| 541 | |
| 542 | class CSixup |
| 543 | { |
| 544 | public: |
| 545 | void Reset(); |
| 546 | |
| 547 | char m_aaSkinPartNames[protocol7::NUM_SKINPARTS][protocol7::MAX_SKIN_LENGTH]; |
| 548 | int m_aUseCustomColors[protocol7::NUM_SKINPARTS]; |
| 549 | int m_aSkinPartColors[protocol7::NUM_SKINPARTS]; |
| 550 | }; |
| 551 | |
| 552 | // 0.7 Skin |
| 553 | CSixup m_aSixup[NUM_DUMMIES]; |
| 554 | }; |
| 555 | |
| 556 | CClientData m_aClients[MAX_CLIENTS]; |
| 557 | |
| 558 | class CClientStats |
| 559 | { |
| 560 | int m_IngameTicks; |
| 561 | int m_JoinTick; |
| 562 | bool m_Active; |
| 563 | |
| 564 | public: |
| 565 | CClientStats(); |
| 566 | |
| 567 | int m_aFragsWith[NUM_WEAPONS]; |
| 568 | int m_aDeathsFrom[NUM_WEAPONS]; |
| 569 | int m_Frags; |
| 570 | int m_Deaths; |
| 571 | int m_Suicides; |
| 572 | int m_BestSpree; |
| 573 | int m_CurrentSpree; |
| 574 | |
| 575 | int m_FlagGrabs; |
| 576 | int m_FlagCaptures; |
| 577 | |
| 578 | void Reset(); |
| 579 | |
| 580 | bool IsActive() const { return m_Active; } |
| 581 | void JoinGame(int Tick) |
| 582 | { |
| 583 | m_Active = true; |
| 584 | m_JoinTick = Tick; |
| 585 | } |
| 586 | void JoinSpec(int Tick) |
| 587 | { |
| 588 | m_Active = false; |
| 589 | m_IngameTicks += Tick - m_JoinTick; |
| 590 | } |
| 591 | int GetIngameTicks(int Tick) const { return m_IngameTicks + Tick - m_JoinTick; } |
| 592 | float GetFPM(int Tick, int TickSpeed) const { return (float)(m_Frags * TickSpeed * 60) / GetIngameTicks(Tick); } |
| 593 | }; |
| 594 | |
| 595 | CClientStats m_aStats[MAX_CLIENTS]; |
| 596 | |
| 597 | CRenderTools m_RenderTools; |
| 598 | CRenderMap m_RenderMap; |
| 599 | |
| 600 | bool m_BackButtonHandledKeyBind = false; |
| 601 | |
| 602 | void OnReset(); |
| 603 | |
| 604 | size_t ComponentCount() const { return m_vpAll.size(); } |
| 605 | |
| 606 | // hooks |
| 607 | void OnConnected() override; |
| 608 | void OnRender() override; |
| 609 | void OnUpdate() override; |
| 610 | void OnDummyDisconnect() override; |
| 611 | virtual void OnRelease(); |
| 612 | void OnInit() override; |
| 613 | void OnConsoleInit() override; |
| 614 | void OnStateChange(int NewState, int OldState) override; |
| 615 | template<typename T> |
| 616 | void ApplySkin7InfoFromGameMsg(const T *pMsg, int ClientId, int Conn); |
| 617 | void ApplySkin7InfoFromSnapObj(const protocol7::CNetObj_De_ClientInfo *pObj, int ClientId) override; |
| 618 | int OnDemoRecSnap7(CSnapshot *pFrom, CSnapshotBuffer *pTo, int Conn) override; |
| 619 | void *TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn); |
| 620 | int TranslateSnap(CSnapshotBuffer *pSnapDstSix, CSnapshot *pSnapSrcSeven, int Conn, bool Dummy) override; |
| 621 | void OnMessage(int MsgId, CUnpacker *pUnpacker, int Conn, bool Dummy) override; |
| 622 | void InvalidateSnapshot() override; |
| 623 | void OnNewSnapshot(bool DummySwapped) override; |
| 624 | void OnPredict() override; |
| 625 | void OnActivateEditor() override; |
| 626 | void OnDummySwap() override; |
| 627 | int OnSnapInput(int *pData, bool Dummy, bool Force) override; |
| 628 | void OnShutdown() override; |
| 629 | void OnEnterGame() override; |
| 630 | void OnRconType(bool UsernameReq) override; |
| 631 | void OnRconLine(const char *pLine) override; |
| 632 | virtual void OnGameOver(); |
| 633 | virtual void OnStartGame(); |
| 634 | virtual void OnStartRound(); |
| 635 | virtual void OnFlagGrab(int TeamId); |
| 636 | void OnWindowResize() override; |
| 637 | |
| 638 | void InitializeLanguage() override; |
| 639 | bool m_LanguageChanged = false; |
| 640 | void OnLanguageChange(); |
| 641 | void HandleLanguageChanged(); |
| 642 | |
| 643 | void ForceUpdateConsoleRemoteCompletionSuggestions() override; |
| 644 | |
| 645 | void RefreshSkin(const std::shared_ptr<CManagedTeeRenderInfo> &pManagedTeeRenderInfo); |
| 646 | void RefreshSkins(int SkinDescriptorFlags); |
| 647 | void OnSkinUpdate(const char *pSkinName); |
| 648 | std::shared_ptr<CManagedTeeRenderInfo> CreateManagedTeeRenderInfo(const CTeeRenderInfo &TeeRenderInfo, const CSkinDescriptor &SkinDescriptor); |
| 649 | std::shared_ptr<CManagedTeeRenderInfo> CreateManagedTeeRenderInfo(const CClientData &Client); |
| 650 | void CollectManagedTeeRenderInfos(const std::function<void(const char *pSkinName)> &ActiveSkinAcceptor); |
| 651 | |
| 652 | void RenderShutdownMessage() override; |
| 653 | void ProcessDemoSnapshot(CSnapshot *pSnap) override; |
| 654 | |
| 655 | const char *GetItemName(int Type) const override; |
| 656 | const char *Version() const override; |
| 657 | const char *NetVersion() const override; |
| 658 | const char *NetVersion7() const override; |
| 659 | int DDNetVersion() const override; |
| 660 | const char *DDNetVersionStr() const override; |
| 661 | int ClientVersion7() const override; |
| 662 | |
| 663 | void DoTeamChangeMessage7(const char *pName, int ClientId, int Team, const char *pPrefix = "" ); |
| 664 | |
| 665 | // actions |
| 666 | // TODO: move these |
| 667 | void SendSwitchTeam(int Team) const; |
| 668 | void SendStartInfo7(bool Dummy); |
| 669 | void SendSkinChange7(bool Dummy); |
| 670 | // Returns true if the requested skin change got applied by the server |
| 671 | bool GotWantedSkin7(bool Dummy); |
| 672 | void SendInfo(bool Start); |
| 673 | void SendDummyInfo(bool Start) override; |
| 674 | void SendKill() const; |
| 675 | void SendReadyChange7(); // NOLINT(readability-make-member-function-const) |
| 676 | |
| 677 | void ApplyPreInputs(int Tick, bool Direct, CGameWorld &GameWorld); |
| 678 | |
| 679 | int m_aNextChangeInfo[NUM_DUMMIES]; |
| 680 | |
| 681 | // DDRace |
| 682 | |
| 683 | int m_aLocalIds[NUM_DUMMIES]; |
| 684 | CNetObj_PlayerInput m_DummyInput; |
| 685 | CNetObj_PlayerInput m_HammerInput; |
| 686 | unsigned int m_DummyFire; |
| 687 | bool m_ReceivedDDNetPlayer; |
| 688 | bool m_ReceivedDDNetPlayerFinishTimes; |
| 689 | bool m_ReceivedDDNetPlayerFinishTimesMillis; |
| 690 | |
| 691 | CTeamsCore m_Teams; |
| 692 | |
| 693 | int IntersectCharacter(vec2 HookPos, vec2 NewPos, vec2 &NewPos2, int OwnId, vec2 *pPlayerPosition = nullptr); |
| 694 | |
| 695 | int LastRaceTick() const; |
| 696 | int CurrentRaceTime() const; |
| 697 | |
| 698 | bool IsTeamPlay() const; |
| 699 | bool IsWorldPaused() const; |
| 700 | bool IsDemoPlaybackPaused() const; |
| 701 | float GetAnimationPlaybackSpeed() const; |
| 702 | |
| 703 | int AntiPingPlayers() const; |
| 704 | bool AntiPingGrenade() const; |
| 705 | bool AntiPingWeapons() const; |
| 706 | bool AntiPingGunfire() const; |
| 707 | bool Predict() const; |
| 708 | bool PredictDummy() const; |
| 709 | |
| 710 | const CTuningParams *GetTuning(int i) const { return &m_aTuningList[i]; } |
| 711 | ColorRGBA GetDDTeamColor(int DDTeam, float Lightness = 0.5f) const; |
| 712 | void FormatClientId(int ClientId, char (&aClientId)[16], EClientIdFormat Format) const; |
| 713 | |
| 714 | CGameWorld m_GameWorld; |
| 715 | CGameWorld m_PredictedWorld; |
| 716 | CGameWorld m_PrevPredictedWorld; |
| 717 | |
| 718 | std::vector<SSwitchers> &Switchers() { return m_GameWorld.m_Core.m_vSwitchers; } |
| 719 | std::vector<SSwitchers> &PredSwitchers() { return m_PredictedWorld.m_Core.m_vSwitchers; } |
| 720 | |
| 721 | void DummyResetInput() override; |
| 722 | void Echo(const char *pString) override; |
| 723 | bool IsOtherTeam(int ClientId) const; |
| 724 | int SwitchStateTeam() const; |
| 725 | bool IsLocalCharSuper() const; |
| 726 | bool CanDisplayWarning() const override; |
| 727 | |
| 728 | IMap *Map() override { return m_pMap.get(); } |
| 729 | const IMap *Map() const override { return m_pMap.get(); } |
| 730 | CNetObjHandler *GetNetObjHandler() override; |
| 731 | protocol7::CNetObjHandler *GetNetObjHandler7() override; |
| 732 | |
| 733 | void LoadGameSkin(const char *pPath, bool AsDir = false); |
| 734 | void LoadEmoticonsSkin(const char *pPath, bool AsDir = false); |
| 735 | void LoadParticlesSkin(const char *pPath, bool AsDir = false); |
| 736 | void LoadHudSkin(const char *pPath, bool AsDir = false); |
| 737 | void (const char *pPath, bool AsDir = false); |
| 738 | |
| 739 | struct SClientGameSkin |
| 740 | { |
| 741 | // health armor hud |
| 742 | IGraphics::CTextureHandle m_SpriteHealthFull; |
| 743 | IGraphics::CTextureHandle m_SpriteHealthEmpty; |
| 744 | IGraphics::CTextureHandle m_SpriteArmorFull; |
| 745 | IGraphics::CTextureHandle m_SpriteArmorEmpty; |
| 746 | |
| 747 | // cursors |
| 748 | IGraphics::CTextureHandle m_SpriteWeaponHammerCursor; |
| 749 | IGraphics::CTextureHandle m_SpriteWeaponGunCursor; |
| 750 | IGraphics::CTextureHandle m_SpriteWeaponShotgunCursor; |
| 751 | IGraphics::CTextureHandle m_SpriteWeaponGrenadeCursor; |
| 752 | IGraphics::CTextureHandle m_SpriteWeaponNinjaCursor; |
| 753 | IGraphics::CTextureHandle m_SpriteWeaponLaserCursor; |
| 754 | |
| 755 | IGraphics::CTextureHandle m_aSpriteWeaponCursors[6]; |
| 756 | |
| 757 | // weapons and hook |
| 758 | IGraphics::CTextureHandle m_SpriteHookChain; |
| 759 | IGraphics::CTextureHandle m_SpriteHookHead; |
| 760 | IGraphics::CTextureHandle m_SpriteWeaponHammer; |
| 761 | IGraphics::CTextureHandle m_SpriteWeaponGun; |
| 762 | IGraphics::CTextureHandle m_SpriteWeaponShotgun; |
| 763 | IGraphics::CTextureHandle m_SpriteWeaponGrenade; |
| 764 | IGraphics::CTextureHandle m_SpriteWeaponNinja; |
| 765 | IGraphics::CTextureHandle m_SpriteWeaponLaser; |
| 766 | |
| 767 | IGraphics::CTextureHandle m_aSpriteWeapons[6]; |
| 768 | |
| 769 | // particles |
| 770 | IGraphics::CTextureHandle m_aSpriteParticles[9]; |
| 771 | |
| 772 | // stars |
| 773 | IGraphics::CTextureHandle m_aSpriteStars[3]; |
| 774 | |
| 775 | // projectiles |
| 776 | IGraphics::CTextureHandle m_SpriteWeaponGunProjectile; |
| 777 | IGraphics::CTextureHandle m_SpriteWeaponShotgunProjectile; |
| 778 | IGraphics::CTextureHandle m_SpriteWeaponGrenadeProjectile; |
| 779 | IGraphics::CTextureHandle m_SpriteWeaponHammerProjectile; |
| 780 | IGraphics::CTextureHandle m_SpriteWeaponNinjaProjectile; |
| 781 | IGraphics::CTextureHandle m_SpriteWeaponLaserProjectile; |
| 782 | |
| 783 | IGraphics::CTextureHandle m_aSpriteWeaponProjectiles[6]; |
| 784 | |
| 785 | // muzzles |
| 786 | IGraphics::CTextureHandle m_aSpriteWeaponGunMuzzles[3]; |
| 787 | IGraphics::CTextureHandle m_aSpriteWeaponShotgunMuzzles[3]; |
| 788 | IGraphics::CTextureHandle m_aaSpriteWeaponNinjaMuzzles[3]; |
| 789 | |
| 790 | IGraphics::CTextureHandle m_aaSpriteWeaponsMuzzles[6][3]; |
| 791 | |
| 792 | // pickups |
| 793 | IGraphics::CTextureHandle m_SpritePickupHealth; |
| 794 | IGraphics::CTextureHandle m_SpritePickupArmor; |
| 795 | IGraphics::CTextureHandle m_SpritePickupArmorShotgun; |
| 796 | IGraphics::CTextureHandle m_SpritePickupArmorGrenade; |
| 797 | IGraphics::CTextureHandle m_SpritePickupArmorNinja; |
| 798 | IGraphics::CTextureHandle m_SpritePickupArmorLaser; |
| 799 | IGraphics::CTextureHandle m_SpritePickupGrenade; |
| 800 | IGraphics::CTextureHandle m_SpritePickupShotgun; |
| 801 | IGraphics::CTextureHandle m_SpritePickupLaser; |
| 802 | IGraphics::CTextureHandle m_SpritePickupNinja; |
| 803 | IGraphics::CTextureHandle m_SpritePickupGun; |
| 804 | IGraphics::CTextureHandle m_SpritePickupHammer; |
| 805 | |
| 806 | IGraphics::CTextureHandle m_aSpritePickupWeapons[6]; |
| 807 | IGraphics::CTextureHandle m_aSpritePickupWeaponArmor[4]; |
| 808 | |
| 809 | // flags |
| 810 | IGraphics::CTextureHandle m_SpriteFlagBlue; |
| 811 | IGraphics::CTextureHandle m_SpriteFlagRed; |
| 812 | |
| 813 | // ninja bar (0.7) |
| 814 | IGraphics::CTextureHandle m_SpriteNinjaBarFullLeft; |
| 815 | IGraphics::CTextureHandle m_SpriteNinjaBarFull; |
| 816 | IGraphics::CTextureHandle m_SpriteNinjaBarEmpty; |
| 817 | IGraphics::CTextureHandle m_SpriteNinjaBarEmptyRight; |
| 818 | |
| 819 | bool IsSixup() const |
| 820 | { |
| 821 | return m_SpriteNinjaBarFullLeft.IsValid(); |
| 822 | } |
| 823 | }; |
| 824 | |
| 825 | SClientGameSkin m_GameSkin; |
| 826 | bool m_GameSkinLoaded = false; |
| 827 | |
| 828 | struct SClientParticlesSkin |
| 829 | { |
| 830 | IGraphics::CTextureHandle m_SpriteParticleSlice; |
| 831 | IGraphics::CTextureHandle m_SpriteParticleBall; |
| 832 | IGraphics::CTextureHandle m_aSpriteParticleSplat[3]; |
| 833 | IGraphics::CTextureHandle m_SpriteParticleSmoke; |
| 834 | IGraphics::CTextureHandle m_SpriteParticleShell; |
| 835 | IGraphics::CTextureHandle m_SpriteParticleExpl; |
| 836 | IGraphics::CTextureHandle m_SpriteParticleAirJump; |
| 837 | IGraphics::CTextureHandle m_SpriteParticleHit; |
| 838 | IGraphics::CTextureHandle m_aSpriteParticles[10]; |
| 839 | }; |
| 840 | |
| 841 | SClientParticlesSkin m_ParticlesSkin; |
| 842 | bool m_ParticlesSkinLoaded = false; |
| 843 | |
| 844 | struct SClientEmoticonsSkin |
| 845 | { |
| 846 | IGraphics::CTextureHandle m_aSpriteEmoticons[16]; |
| 847 | }; |
| 848 | |
| 849 | SClientEmoticonsSkin m_EmoticonsSkin; |
| 850 | bool m_EmoticonsSkinLoaded = false; |
| 851 | |
| 852 | struct SClientHudSkin |
| 853 | { |
| 854 | IGraphics::CTextureHandle m_SpriteHudAirjump; |
| 855 | IGraphics::CTextureHandle m_SpriteHudAirjumpEmpty; |
| 856 | IGraphics::CTextureHandle m_SpriteHudSolo; |
| 857 | IGraphics::CTextureHandle m_SpriteHudCollisionDisabled; |
| 858 | IGraphics::CTextureHandle m_SpriteHudEndlessJump; |
| 859 | IGraphics::CTextureHandle m_SpriteHudEndlessHook; |
| 860 | IGraphics::CTextureHandle m_SpriteHudJetpack; |
| 861 | IGraphics::CTextureHandle m_SpriteHudFreezeBarFullLeft; |
| 862 | IGraphics::CTextureHandle m_SpriteHudFreezeBarFull; |
| 863 | IGraphics::CTextureHandle m_SpriteHudFreezeBarEmpty; |
| 864 | IGraphics::CTextureHandle m_SpriteHudFreezeBarEmptyRight; |
| 865 | IGraphics::CTextureHandle m_SpriteHudNinjaBarFullLeft; |
| 866 | IGraphics::CTextureHandle m_SpriteHudNinjaBarFull; |
| 867 | IGraphics::CTextureHandle m_SpriteHudNinjaBarEmpty; |
| 868 | IGraphics::CTextureHandle m_SpriteHudNinjaBarEmptyRight; |
| 869 | IGraphics::CTextureHandle m_SpriteHudHookHitDisabled; |
| 870 | IGraphics::CTextureHandle m_SpriteHudHammerHitDisabled; |
| 871 | IGraphics::CTextureHandle m_SpriteHudShotgunHitDisabled; |
| 872 | IGraphics::CTextureHandle m_SpriteHudGrenadeHitDisabled; |
| 873 | IGraphics::CTextureHandle m_SpriteHudLaserHitDisabled; |
| 874 | IGraphics::CTextureHandle m_SpriteHudGunHitDisabled; |
| 875 | IGraphics::CTextureHandle m_SpriteHudDeepFrozen; |
| 876 | IGraphics::CTextureHandle m_SpriteHudLiveFrozen; |
| 877 | IGraphics::CTextureHandle m_SpriteHudTeleportGrenade; |
| 878 | IGraphics::CTextureHandle m_SpriteHudTeleportGun; |
| 879 | IGraphics::CTextureHandle m_SpriteHudTeleportLaser; |
| 880 | IGraphics::CTextureHandle m_SpriteHudPracticeMode; |
| 881 | IGraphics::CTextureHandle m_SpriteHudLockMode; |
| 882 | IGraphics::CTextureHandle m_SpriteHudTeam0Mode; |
| 883 | IGraphics::CTextureHandle m_SpriteHudDummyHammer; |
| 884 | IGraphics::CTextureHandle m_SpriteHudDummyCopy; |
| 885 | }; |
| 886 | |
| 887 | SClientHudSkin m_HudSkin; |
| 888 | bool m_HudSkinLoaded = false; |
| 889 | |
| 890 | struct |
| 891 | { |
| 892 | IGraphics::CTextureHandle m_SpriteParticleSnowflake; |
| 893 | IGraphics::CTextureHandle m_SpriteParticleSparkle; |
| 894 | IGraphics::CTextureHandle ; |
| 895 | IGraphics::CTextureHandle ; |
| 896 | IGraphics::CTextureHandle m_aSpriteParticles[4]; |
| 897 | }; |
| 898 | |
| 899 | SClientExtrasSkin ; |
| 900 | bool = false; |
| 901 | |
| 902 | const std::vector<CSnapEntities> &SnapEntities() { return m_vSnapEntities; } |
| 903 | |
| 904 | int m_MultiViewTeam; |
| 905 | float m_MultiViewPersonalZoom; |
| 906 | bool m_MultiViewShowHud; |
| 907 | bool m_MultiViewActivated; |
| 908 | bool m_aMultiViewId[MAX_CLIENTS]; |
| 909 | |
| 910 | void ResetMultiView(); |
| 911 | int FindFirstMultiViewId(); |
| 912 | void CleanMultiViewId(int ClientId); |
| 913 | int m_MapBestTimeSeconds; |
| 914 | int m_MapBestTimeMillis; |
| 915 | char m_aMapDescription[512]; |
| 916 | |
| 917 | private: |
| 918 | std::unique_ptr<IMap> m_pMap; |
| 919 | |
| 920 | std::vector<CSnapEntities> m_vSnapEntities; |
| 921 | void SnapCollectEntities(); |
| 922 | |
| 923 | bool m_aDDRaceMsgSent[NUM_DUMMIES]; |
| 924 | int m_aShowOthers[NUM_DUMMIES]; |
| 925 | int m_aEnableSpectatorCount[NUM_DUMMIES]; // current setting as sent to the server, -1 if not yet sent |
| 926 | |
| 927 | class CImageAsset |
| 928 | { |
| 929 | public: |
| 930 | bool IsLoaded() const { return m_ImageInfo.m_pData != nullptr; } |
| 931 | |
| 932 | char m_aPath[IO_MAX_PATH_LENGTH]; |
| 933 | bool m_IsDefault; |
| 934 | CImageInfo m_ImageInfo; |
| 935 | std::optional<CImageInfo> m_FallbackImageInfo; |
| 936 | }; |
| 937 | |
| 938 | CImageAsset LoadAssetFromPath(const char *pPath, bool AsDir, int AssetId, const char *pDirectory) const; |
| 939 | |
| 940 | std::vector<std::shared_ptr<CManagedTeeRenderInfo>> m_vpManagedTeeRenderInfos; |
| 941 | void UpdateManagedTeeRenderInfos(); |
| 942 | |
| 943 | void UpdateLocalTuning(); |
| 944 | void UpdatePrediction(); |
| 945 | void UpdateSpectatorCursor(); |
| 946 | void UpdateRenderedCharacters(); |
| 947 | void HandlePredictedEvents(int Tick); |
| 948 | |
| 949 | void OnInput(const IInput::CEvent &Event); |
| 950 | |
| 951 | int m_aLastUpdateTick[MAX_CLIENTS] = {0}; |
| 952 | void DetectStrongHook(); |
| 953 | |
| 954 | vec2 GetSmoothPos(int ClientId); |
| 955 | |
| 956 | int m_IsDummySwapping; |
| 957 | CCharOrder m_CharOrder; |
| 958 | int m_aSwitchStateTeam[NUM_DUMMIES]; |
| 959 | |
| 960 | void LoadMapSettings(); |
| 961 | CMapBugs m_MapBugs; |
| 962 | |
| 963 | // tunings for every zone on the map, 0 is a global tune |
| 964 | CTuningParams m_aTuningList[TuneZone::NUM]; |
| 965 | CTuningParams *TuningList() { return m_aTuningList; } |
| 966 | |
| 967 | float m_LastShowDistanceZoom; |
| 968 | float m_LastZoom; |
| 969 | float m_LastScreenAspect; |
| 970 | float m_LastDeadzone; |
| 971 | float m_LastFollowFactor; |
| 972 | bool m_LastDummyConnected; |
| 973 | |
| 974 | void HandleMultiView(); |
| 975 | bool IsMultiViewIdSet(); |
| 976 | void CleanMultiViewIds(); |
| 977 | bool InitMultiView(int Team); |
| 978 | float CalculateMultiViewMultiplier(vec2 TargetPos); |
| 979 | float CalculateMultiViewZoom(vec2 MinPos, vec2 MaxPos, float Vel); |
| 980 | float MapValue(float MaxValue, float MinValue, float MaxRange, float MinRange, float Value); |
| 981 | |
| 982 | struct SMultiView |
| 983 | { |
| 984 | bool m_Solo; |
| 985 | bool m_IsInit; |
| 986 | bool m_Teleported; |
| 987 | bool m_aVanish[MAX_CLIENTS]; |
| 988 | vec2 m_OldPos; |
| 989 | int m_OldPersonalZoom; |
| 990 | float m_SecondChance; |
| 991 | float m_OldCameraDistance; |
| 992 | float m_aLastFreeze[MAX_CLIENTS]; |
| 993 | }; |
| 994 | |
| 995 | SMultiView m_MultiView; |
| 996 | |
| 997 | void OnSaveCodeNetMessage(const CNetMsg_Sv_SaveCode *pMsg); |
| 998 | void StoreSave(const char *pTeamMembers, const char *pGeneratedCode) const; |
| 999 | }; |
| 1000 | |
| 1001 | ColorRGBA CalculateNameColor(ColorHSLA TextColorHSL); |
| 1002 | |
| 1003 | #endif |
| 1004 | |