├── .gitattributes ├── .gitignore ├── IGameMovement.cpp └── IGameMovement.h /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /IGameMovement.cpp: -------------------------------------------------------------------------------- 1 | #include "precompiled.h" 2 | #include "IGameMovement.h" 3 | #include "C_CSGameRules.h" 4 | #include "Gametypes.h" 5 | #include 6 | #include "ClassIDS.h" 7 | #include "UsedConvars.h" 8 | #include "vphysics_interface.h" 9 | #include "Includes.h" 10 | #include "LocalPlayer.h" 11 | 12 | static CCSGameMovement g_GameMovement; 13 | IGameMovement* g_pGameMovement = (IGameMovement*)&g_GameMovement; 14 | extern bool g_bIsExiting; 15 | 16 | inline const Vector& CMoveData::GetAbsOrigin() const 17 | { 18 | return _m_vecAbsOrigin; 19 | } 20 | 21 | // This is implemented with a more exhaustive test in gamemovement.cpp. We check if the origin being requested is 22 | // inside solid, which it never should be 23 | inline void CMoveData::SetAbsOrigin(const Vector& vec) 24 | { 25 | _m_vecAbsOrigin = vec; 26 | } 27 | 28 | //----------------------------------------------------------------------------- 29 | // Traces the player's collision bounds in quadrants, looking for a plane that 30 | // can be stood upon (normal's z >= 0.7f). Regardless of success or failure, 31 | // replace the fraction and endpos with the original ones, so we don't try to 32 | // move the player down to the new floor and get stuck on a leaning wall that 33 | // the original trace hit first. 34 | //----------------------------------------------------------------------------- 35 | void TracePlayerBBoxForGround(const Vector& start, const Vector& end, const Vector& minsSrc, const Vector& maxsSrc, IHandleEntity* player, unsigned int fMask, int collisionGroup, trace_t& pm) 36 | { 37 | Ray_t ray; 38 | Vector mins, maxs; 39 | 40 | float fraction = pm.fraction; 41 | Vector endpos = pm.endpos; 42 | 43 | // Check the -x, -y quadrant 44 | mins = minsSrc; 45 | maxs.Init(min(0, maxsSrc.x), min(0, maxsSrc.y), maxsSrc.z); 46 | ray.Init(start, end, mins, maxs); 47 | UTIL_TraceRay(ray, fMask, player, collisionGroup, &pm); 48 | if (pm.m_pEnt && pm.plane.normal[2] >= 0.7) 49 | { 50 | pm.fraction = fraction; 51 | pm.endpos = endpos; 52 | return; 53 | } 54 | 55 | // Check the +x, +y quadrant 56 | mins.Init(max(0, minsSrc.x), max(0, minsSrc.y), minsSrc.z); 57 | maxs = maxsSrc; 58 | ray.Init(start, end, mins, maxs); 59 | UTIL_TraceRay(ray, fMask, player, collisionGroup, &pm); 60 | if (pm.m_pEnt && pm.plane.normal[2] >= 0.7) 61 | { 62 | pm.fraction = fraction; 63 | pm.endpos = endpos; 64 | return; 65 | } 66 | 67 | // Check the -x, +y quadrant 68 | mins.Init(minsSrc.x, max(0, minsSrc.y), minsSrc.z); 69 | maxs.Init(min(0, maxsSrc.x), maxsSrc.y, maxsSrc.z); 70 | ray.Init(start, end, mins, maxs); 71 | UTIL_TraceRay(ray, fMask, player, collisionGroup, &pm); 72 | if (pm.m_pEnt && pm.plane.normal[2] >= 0.7) 73 | { 74 | pm.fraction = fraction; 75 | pm.endpos = endpos; 76 | return; 77 | } 78 | 79 | // Check the +x, -y quadrant 80 | mins.Init(max(0, minsSrc.x), minsSrc.y, minsSrc.z); 81 | maxs.Init(maxsSrc.x, min(0, maxsSrc.y), maxsSrc.z); 82 | ray.Init(start, end, mins, maxs); 83 | UTIL_TraceRay(ray, fMask, player, collisionGroup, &pm); 84 | if (pm.m_pEnt && pm.plane.normal[2] >= 0.7) 85 | { 86 | pm.fraction = fraction; 87 | pm.endpos = endpos; 88 | return; 89 | } 90 | 91 | pm.fraction = fraction; 92 | pm.endpos = endpos; 93 | } 94 | 95 | //----------------------------------------------------------------------------- 96 | // Purpose: Constructs GameMovement interface 97 | //----------------------------------------------------------------------------- 98 | CGameMovement::CGameMovement(void) 99 | { 100 | m_nOldWaterLevel = WL_NotInWater; 101 | m_flWaterEntryTime = 0; 102 | m_nOnLadder = 0; 103 | m_bProcessingMovement = false; 104 | 105 | mv = NULL; 106 | 107 | memset(m_flStuckCheckTime, 0, sizeof(m_flStuckCheckTime)); 108 | m_pTraceListData = NULL; 109 | } 110 | 111 | //----------------------------------------------------------------------------- 112 | // Purpose: Destructor 113 | //----------------------------------------------------------------------------- 114 | CGameMovement::~CGameMovement(void) 115 | { 116 | if (!g_bIsExiting && Interfaces::EngineTrace) 117 | { 118 | Interfaces::EngineTrace->FreeTraceListData(m_pTraceListData); 119 | } 120 | } 121 | 122 | CCSGameMovement::CCSGameMovement() 123 | { 124 | } 125 | 126 | void CGameMovement::nullsub3() 127 | { 128 | } 129 | 130 | void CCSGameMovement::nullsub3() 131 | { 132 | } 133 | 134 | // ----------------------------------- 135 | // Implementation 136 | // ----------------------------------- 137 | 138 | void CGameMovement::ProcessMovement(CBasePlayer* basePlayer, CMoveData* moveData) 139 | { 140 | float storedFrametime = Interfaces::Globals->frametime; 141 | 142 | m_nTraceCount = 0; 143 | 144 | Interfaces::Globals->frametime *= basePlayer->GetLaggedMovement(); 145 | 146 | ResetGetWaterContentsForPointCache(); 147 | 148 | mv = moveData; 149 | m_bSpeedCropped = false; 150 | player = basePlayer; 151 | 152 | // Calls CBasePlayer's 269th index 153 | //(*(void (__thiscall **)(DWORD))(*(_DWORD *)basePlayer + 0x434))(basePlayer); 154 | mv->_m_flMaxSpeed = basePlayer->GetPlayerMaxSpeed(); 155 | 156 | m_bProcessingMovement = true; 157 | 158 | //DiffPrint("start %f %f %f", mv->GetAbsOrigin().x, mv->GetAbsOrigin().y, mv->GetAbsOrigin().z); 159 | 160 | //(*(void (__thiscall **)(DWORD))(*(_DWORD *)gameMovement_0 + 0x44))(gameMovement_0); 161 | PlayerMove(); 162 | 163 | // FinishMove(); inlined 164 | mv->m_nOldButtons = mv->m_nButtons; 165 | 166 | //DiffPrint("end %f %f %f", mv->GetAbsOrigin().x, mv->GetAbsOrigin().y, mv->GetAbsOrigin().z); 167 | 168 | Interfaces::Globals->frametime = storedFrametime; 169 | 170 | m_bProcessingMovement = false; 171 | } 172 | 173 | void CCSGameMovement::ProcessMovement(CBasePlayer* basePlayer, CMoveData* moveData) 174 | { 175 | m_pCSPlayer = basePlayer; 176 | 177 | if (!m_pCSPlayer->IsBot()) 178 | CGameMovement::ProcessMovement(basePlayer, moveData); 179 | } 180 | 181 | void CGameMovement::DiffPrint(char const* fmt, ...) 182 | { 183 | } 184 | 185 | void CCSGameMovement::DiffPrint(char const* fmt, ...) 186 | { 187 | } 188 | 189 | void CGameMovement::Reset() 190 | { 191 | player = nullptr; 192 | } 193 | 194 | void CGameMovement::StartTrackPredictionErrors(CBasePlayer* basePlayer) 195 | { 196 | if (basePlayer->IsBot()) 197 | return; 198 | 199 | player = basePlayer; 200 | } 201 | 202 | void CGameMovement::FinishTrackPredictionErrors(CBasePlayer* basePlayer) 203 | { 204 | if (basePlayer->IsBot()) 205 | return; 206 | } 207 | 208 | const Vector& CGameMovement::GetPlayerMins(bool ducked) const 209 | { 210 | if (ducked) 211 | // (*(*g_pGameRules + 120))() + 0x14; 212 | return (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin; 213 | 214 | // (*(*g_pGameRules + 120))() + 0xC; 215 | return (*g_pGameRules)->GetViewVectors()->m_vHullMin; 216 | } 217 | 218 | const Vector& CGameMovement::GetPlayerMaxs(bool ducked) const 219 | { 220 | if (ducked) 221 | // (*(*g_pGameRules + 120))() + 0x30; 222 | return (*g_pGameRules)->GetViewVectors()->m_vDuckHullMax; 223 | 224 | // (*(*g_pGameRules + 120))() + 0x18; 225 | return (*g_pGameRules)->GetViewVectors()->m_vHullMax; 226 | } 227 | 228 | const Vector& CGameMovement::GetPlayerViewOffset(bool ducked) const 229 | { 230 | if (ducked) 231 | // (*(*g_pGameRules + 120))() + 0x3C; 232 | return (*g_pGameRules)->GetViewVectors()->m_vDuckView; 233 | 234 | // (*(*g_pGameRules + 120))() + 0; 235 | return (*g_pGameRules)->GetViewVectors()->m_vView; 236 | } 237 | 238 | bool CGameMovement::IsMovingPlayerStuck() const 239 | { 240 | if (m_bProcessingMovement) 241 | { 242 | if (!m_bInStuckTest) 243 | { 244 | CBasePlayer* basePlayer = player; 245 | if (basePlayer && basePlayer->GetStuckLast() > 0) 246 | return true; 247 | } 248 | } 249 | 250 | return false; 251 | } 252 | 253 | CBasePlayer* CGameMovement::GetMovingPlayer() const 254 | { 255 | if (m_bProcessingMovement) 256 | return player; 257 | 258 | return nullptr; 259 | } 260 | 261 | void CGameMovement::UnblockPusher(CBasePlayer* pPlayer, CBaseEntity* pPusher) 262 | { 263 | // TODO 264 | } 265 | 266 | void CCSGameMovement::UnblockPusher(CBasePlayer* pPlayer, CBaseEntity* pPusher) 267 | { 268 | // TODO 269 | } 270 | 271 | void CGameMovement::SetupMovementBounds(CMoveData* moveData) 272 | { 273 | if (m_pTraceListData) 274 | m_pTraceListData->Reset(); 275 | else 276 | m_pTraceListData = Interfaces::EngineTrace->AllocTraceListData(); 277 | 278 | if (moveData->m_nPlayerHandle == -1) 279 | return; 280 | 281 | CBasePlayer* basePlayer = (CBaseEntity*)moveData->m_nPlayerHandle.Get(); 282 | 283 | // ClearBounds inlined and optimized (doesn't use 99999 and -99999, but rather LOVAL/HIVAL constants) 284 | Vector moveMins = { FLT_MIN, FLT_MIN, FLT_MIN };//{ (float)0xFF7FFFFF, (float)0xFF7FFFFF, (float)0xFF7FFFFF }; 285 | Vector moveMaxs = { FLT_MAX, FLT_MAX, FLT_MAX };//{ (float)0x7F7FFFFF, (float)0x7F7FFFFF, (float)0x7F7FFFFF }; 286 | 287 | Vector start = moveData->_m_vecAbsOrigin; 288 | float radius = ((moveData->m_vecVelocity_.Length() + moveData->_m_flMaxSpeed) * Interfaces::Globals->frametime) + 1.0f; 289 | 290 | Vector playerMins = GetPlayerMins(false); 291 | Vector playerMaxs = GetPlayerMaxs(false); 292 | 293 | Vector bloat = { radius, radius, radius + basePlayer->GetStepSize() }; 294 | 295 | AddPointToBounds(start + playerMaxs + bloat, moveMins, moveMaxs); 296 | AddPointToBounds(start + playerMaxs - bloat, moveMins, moveMaxs); 297 | 298 | // (*(*enginetrace + 28))(&moveMins, &moveMaxs, *(gameMovement + 0xE4C)); 299 | Interfaces::EngineTrace->SetupLeafAndEntityListBox(moveMins, moveMaxs, m_pTraceListData); 300 | } 301 | 302 | Vector CGameMovement::GetPlayerMins() 303 | { 304 | // (*(**(this + 4) + 0x474))() 305 | if (player->GetObserverMode()) 306 | // (*(*g_pGameRules + 120))() + 72; 307 | return (*g_pGameRules)->GetViewVectors()->m_vObsHullMin; 308 | 309 | // ( *(*(v1 + 4) + 0x3034) ) 310 | if (player->GetDucked()) 311 | // (*(v3 + 120))(g_pGameRules) + 36 312 | return (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin; 313 | 314 | // (*(v3 + 120))(g_pGameRules) + 12 315 | return (*g_pGameRules)->GetViewVectors()->m_vHullMin; 316 | } 317 | 318 | Vector CGameMovement::GetPlayerMaxs() 319 | { 320 | // (*(**(this + 4) + 0x474))() 321 | if (player->GetObserverMode()) 322 | // (*(*g_pGameRules + 120))() + 84; 323 | return (*g_pGameRules)->GetViewVectors()->m_vObsHullMax; 324 | 325 | // ( *(*(v1 + 4) + 0x3034) ) 326 | if (player->GetDucked()) 327 | // (*(v3 + 120))(g_pGameRules) + 48 328 | return (*g_pGameRules)->GetViewVectors()->m_vDuckHullMax; 329 | 330 | // (*(v3 + 120))(g_pGameRules) + 24 331 | return (*g_pGameRules)->GetViewVectors()->m_vHullMax; 332 | } 333 | 334 | void CGameMovement::TracePlayerBBox(const Vector& rayStart, const Vector& rayEnd, int fMask, int collisionGroup, trace_t& tracePtr) 335 | { 336 | Ray_t ray; 337 | m_nTraceCount++; 338 | 339 | Vector playerMaxs = GetPlayerMaxs(); 340 | Vector playerMins = GetPlayerMins(); 341 | 342 | ray.Init(rayStart, rayEnd, playerMins, playerMaxs); 343 | 344 | ITraceFilter* filter = LockTraceFilter(collisionGroup); 345 | 346 | if (m_pTraceListData == nullptr || !m_pTraceListData->CanTraceRay(ray)) 347 | Interfaces::EngineTrace->TraceRay(ray, fMask, filter, &tracePtr); 348 | else 349 | Interfaces::EngineTrace->TraceRayAgainstLeafAndEntityList(ray, m_pTraceListData, fMask, filter, &tracePtr); 350 | 351 | UnlockTraceFilter(filter); 352 | } 353 | 354 | unsigned int CGameMovement::PlayerSolidMask(bool brushOnly, CBasePlayer* testPlayer /*= nullptr;*/) 355 | { 356 | if (brushOnly) 357 | return 0x1400B; 358 | 359 | return 0x201400B; 360 | } 361 | 362 | //dangerzone correct 363 | unsigned int CCSGameMovement::PlayerSolidMask(bool brushOnly, CBasePlayer* testPlayer) 364 | { 365 | bool isBot = true; 366 | 367 | if (player != nullptr) 368 | { 369 | if (!player->IsBot()) 370 | isBot = false; 371 | } 372 | 373 | unsigned int v9 = 0x1400B; 374 | 375 | if (!brushOnly) 376 | // v9 = (*(int (**)(void))(**(_DWORD **)(v2 + 4) + 592))(); 377 | // Calls CBasePlayer's 148th function 378 | v9 = player->PhysicsSolidMaskForEntity(); 379 | 380 | unsigned int result = v9 | 0x20000; 381 | 382 | if (!isBot) 383 | result = v9; 384 | 385 | return result; 386 | } 387 | 388 | void CGameMovement::FullNoClipMove(float factor, float maxaccel) 389 | { 390 | const float maxspeed = sv_maxspeed.GetVar()->GetFloat() * factor; 391 | 392 | Vector forward, right, up; 393 | AngleVectors(mv->m_vecViewAngles, &forward, &right, &up); 394 | 395 | if (mv->m_nButtons & IN_SPEED) 396 | factor *= 0.5f; 397 | 398 | float fmove = mv->m_flForwardMove * factor; 399 | float sidemove = mv->m_flSideMove * factor; 400 | 401 | VectorNormalizeFast(forward); 402 | VectorNormalizeFast(right); 403 | 404 | Vector wishVel; 405 | for (int i = 0; i < 3; ++i) 406 | wishVel[i] = forward[i] * fmove + right[i] * sidemove; 407 | 408 | wishVel.z += mv->m_flUpMove * factor; 409 | 410 | Vector wishdir = wishVel; 411 | 412 | float wishspeed = VectorNormalize(wishdir); 413 | 414 | if (wishspeed > maxspeed) 415 | { 416 | VectorScale(wishVel, maxspeed / wishspeed, wishVel); 417 | wishspeed = maxspeed; 418 | } 419 | 420 | if (maxaccel <= 0.f) 421 | { 422 | mv->m_vecVelocity_ = wishVel; 423 | } 424 | else 425 | { 426 | Accelerate(wishdir, wishspeed, maxaccel); 427 | 428 | float spd = mv->m_vecVelocity_.Length(); 429 | 430 | if (spd < 1.f) 431 | { 432 | mv->m_vecVelocity_.x = 0.f; 433 | mv->m_vecVelocity_.y = 0.f; 434 | mv->m_vecVelocity_.z = 0.f; 435 | return; 436 | } 437 | 438 | float control = (spd < maxspeed * 0.25f) ? (maxspeed * 0.25f) : spd; 439 | 440 | float friction = sv_friction.GetVar()->GetFloat() * player->GetSurfaceFriction(); 441 | 442 | float drop = control * friction * Interfaces::Globals->frametime; 443 | 444 | float newspeed = fmaxf(spd - drop, 0.f); 445 | 446 | newspeed /= spd; 447 | VectorScale(mv->m_vecVelocity_, newspeed, mv->m_vecVelocity_); 448 | } 449 | 450 | Vector temp; 451 | VectorMA(mv->_m_vecAbsOrigin, Interfaces::Globals->frametime, mv->m_vecVelocity_, temp); 452 | mv->_m_vecAbsOrigin = temp; 453 | 454 | if (maxaccel < 0.f) 455 | { 456 | mv->m_vecVelocity_.x = 0.f; 457 | mv->m_vecVelocity_.y = 0.f; 458 | mv->m_vecVelocity_.z = 0.f; 459 | } 460 | } 461 | 462 | void CGameMovement::FullObserverMove() 463 | { 464 | // (*(*ecx->player + 0x474))(); 465 | int observerMode = player->GetObserverMode(); 466 | 467 | if (observerMode == OBS_MODE_IN_EYE || observerMode == OBS_MODE_CHASE) 468 | { 469 | // (*(*ecx->player + 0x478))(); 470 | CBasePlayer* observerTarget = (CBasePlayer*)player->GetObserverTarget(); 471 | 472 | if (observerTarget != nullptr) 473 | { 474 | mv->_m_vecAbsOrigin = *observerTarget->GetAbsOrigin(); 475 | mv->m_vecViewAngles = observerTarget->GetAbsAngles(); 476 | mv->m_vecVelocity_ = *observerTarget->GetAbsVelocity(); 477 | } 478 | } 479 | else if (observerMode == OBS_MODE_ROAMING) 480 | { 481 | if (sv_specnoclip.GetVar()->GetBool()) 482 | { 483 | FullNoClipMove(sv_specaccelerate.GetVar()->GetFloat(), sv_specspeed.GetVar()->GetFloat()); 484 | } 485 | else 486 | { 487 | Vector forward, right, up; 488 | AngleVectors(mv->m_vecViewAngles, &forward, &right, &up); 489 | 490 | float factor = sv_specspeed.GetVar()->GetFloat(); 491 | 492 | if (mv->m_nButtons & IN_SPEED) 493 | factor *= 0.5f; 494 | 495 | float fmove = mv->m_flForwardMove * factor; 496 | float sidemove = mv->m_flSideMove * factor; 497 | 498 | VectorNormalizeFast(forward); 499 | VectorNormalizeFast(right); 500 | 501 | Vector wishVel; 502 | for (int i = 0; i < 3; ++i) 503 | wishVel[i] = forward[i] * fmove + right[i] * sidemove; 504 | 505 | wishVel.z += mv->m_flUpMove; 506 | 507 | Vector wishdir = wishVel; 508 | 509 | float wishspeed = VectorNormalize(wishdir); 510 | 511 | float maxspeed = sv_maxvelocity.GetVar()->GetFloat(); 512 | 513 | wishspeed = fminf(wishspeed, maxspeed); 514 | VectorScale(wishVel, mv->_m_flMaxSpeed / wishspeed, wishVel); 515 | 516 | Accelerate(wishdir, wishspeed, sv_specaccelerate.GetVar()->GetFloat()); 517 | 518 | float spd = mv->m_vecVelocity_.Length(); 519 | 520 | if (spd < 1.f) 521 | { 522 | mv->m_vecVelocity_.x = 0.f; 523 | mv->m_vecVelocity_.y = 0.f; 524 | mv->m_vecVelocity_.z = 0.f; 525 | return; 526 | } 527 | 528 | float friction = sv_friction.GetVar()->GetFloat() * player->GetSurfaceFriction(); 529 | 530 | float drop = spd * friction * Interfaces::Globals->frametime; 531 | 532 | float newspeed = fmaxf(spd - drop, 0.f); 533 | 534 | newspeed /= spd; 535 | VectorScale(mv->m_vecVelocity_, newspeed, mv->m_vecVelocity_); 536 | 537 | CGameMovement::CheckVelocity(); 538 | 539 | CGameMovement::TryPlayerMove(); 540 | } 541 | } 542 | } 543 | 544 | void CGameMovement::PlayerMove() 545 | { 546 | CheckParameters(); 547 | 548 | mv->m_outWishVel = { 0, 0, 0 }; 549 | mv->m_outJumpVel = { 0, 0, 0 }; 550 | 551 | (*Interfaces::MoveHelperClient)->ResetTouchList(); 552 | 553 | ReduceTimers(); 554 | 555 | AngleVectors(mv->m_vecViewAngles, &m_vecForward, &m_vecRight, &m_vecUp); 556 | 557 | auto moveType = player->GetMoveType(); 558 | 559 | if (moveType == MOVETYPE_NOCLIP || moveType == MOVETYPE_ISOMETRIC || moveType == MOVETYPE_OBSERVER || player->GetDeadFlag() || !CheckInterval(STUCK) || !CheckStuck()) 560 | { 561 | if (moveType != MOVETYPE_WALK || mv->m_bGameCodeMovedPlayer || !sv_optimizedmovement.GetVar()->GetBool()) 562 | CategorizePosition(); 563 | else if (mv->m_vecVelocity_.z > 250.0f) 564 | { 565 | SetGroundEntity(nullptr); 566 | } 567 | 568 | m_nOldWaterLevel = player->GetWaterLevel(); 569 | 570 | if (player->GetGroundEntity() == nullptr) 571 | { 572 | // *(*(cgamemovement + 8) + 0x48) ^ 80000000800000008000000080000000h same as negating floats 573 | player->SetFallVelocity(-mv->m_vecVelocity_.z); 574 | } 575 | 576 | m_nOnLadder = 0; 577 | 578 | // (*(*basePlayer_1 + 0x544))(*(basePlayer_1 + 0x35A0), &moveData_1->m_vecAbsOrigin, &moveData_1->m_vecVelocity); 579 | // Calls CBasePlayer's 337th index with surfacedata (player + 35A0) 580 | player->UpdateStepSound(player->GetSurfaceData(), mv->_m_vecAbsOrigin, mv->m_vecVelocity_); 581 | 582 | UpdateDuckJumpEyeOffset(); 583 | Duck(); 584 | 585 | if (!player->GetDeadFlag() && !(player->GetFlags() & FL_ONTRAIN) && !LadderMove()) 586 | { 587 | if (moveType == MOVETYPE_LADDER) 588 | { 589 | //*(basePlayer_3 + 0x258) = 2; 590 | // *(*(cgamemovement + 4) + 0x259) = 0; 591 | player->SetMoveType(MOVETYPE_WALK); 592 | player->SetMoveCollide(MOVECOLLIDE_DEFAULT); 593 | } 594 | } 595 | 596 | switch (player->GetMoveType()) 597 | { 598 | case MOVETYPE_NONE: 599 | return; 600 | 601 | case MOVETYPE_ISOMETRIC: 602 | case MOVETYPE_WALK: 603 | { 604 | FullWalkMove(); 605 | break; 606 | } 607 | 608 | case MOVETYPE_FLY: 609 | case MOVETYPE_FLYGRAVITY: 610 | { 611 | FullTossMove(); 612 | break; 613 | } 614 | case MOVETYPE_NOCLIP: 615 | { 616 | FullNoClipMove(sv_noclipspeed.GetVar()->GetFloat(), sv_noclipaccelerate.GetVar()->GetFloat()); 617 | break; 618 | } 619 | case MOVETYPE_LADDER: 620 | { 621 | FullLadderMove(); 622 | break; 623 | } 624 | 625 | case MOVETYPE_OBSERVER: 626 | { 627 | FullObserverMove(); 628 | break; 629 | } 630 | default: 631 | //DevMsg(1, "Bogus pmove player movetype %i on (%i) 0=cl 1=sv\n", player->IsServer(), 0); 632 | break; 633 | } 634 | } 635 | } 636 | 637 | void CCSGameMovement::AutoMountMove() 638 | { 639 | auto player = m_pCSPlayer; 640 | float dt = player->GetAutomoveTargetTime() - player->GetAutomoveStartTime(); 641 | float newtime = (Interfaces::Globals->curtime - (player->GetAutomoveTargetTime() - dt)) / dt; 642 | newtime = clamp(newtime, 0.0f, 1.0f); 643 | float fuck = powf(newtime, 0.6214906f); 644 | Vector origin = (player->GetAutomoveTargetEnd() - player->GetAutoMoveOrigin()) * fuck + player->GetAutoMoveOrigin(); 645 | mv->m_vecVelocity_ = vecZero; 646 | mv->_m_vecAbsOrigin = origin; 647 | if ((origin - player->GetAutomoveTargetEnd()).Length() >= 1.5f) 648 | { 649 | mv->m_flForwardMove = 0.0f; 650 | mv->m_flSideMove = 0.0f; 651 | mv->m_flUpMove = 0.0f; 652 | mv->m_nButtons &= 0xFFFFF9E5; 653 | } 654 | else 655 | { 656 | if (player->IsAutoMounting()) 657 | player->SetIsAutoMounting(0); 658 | 659 | Vector vForward, vRight, vUp; 660 | AngleVectors(mv->m_vecViewAngles, &vForward, &vRight, &vUp); 661 | 662 | VectorNormalizeFast(vForward); 663 | VectorNormalizeFast(vRight); 664 | VectorNormalizeFast(vUp); 665 | 666 | Vector2D dest; 667 | Vector delta = player->GetAutomoveTargetEnd() - player->GetAutoMoveOrigin(); 668 | 669 | if (delta.Length2D() == 0.0f) 670 | { 671 | dest = { 0.0f, 0.0f }; 672 | } 673 | else 674 | { 675 | dest.x = delta.x * (1.0f / vUp.z); 676 | dest.y = delta.y * (1.0f / vUp.z); 677 | } 678 | 679 | float newflt = ((((dest.y * vRight.x) + (dest.x * vRight.y) + (0.0f * 0.0f)) + 1.0f) * 0.5f) * fmaxf(player->GetAutomoveTargetEnd().y, 80.0f); 680 | 681 | mv->m_vecVelocity_ = { dest.x * newflt, dest.y * newflt, 0.0f }; 682 | 683 | OnLand(50.0f); 684 | player->GetPunchAdr()->x = 0.0f; 685 | } 686 | } 687 | 688 | //dangerzone correct 689 | void CCSGameMovement::PlayerMove() 690 | { 691 | if (!CanMove(m_pCSPlayer)) 692 | { 693 | mv->m_flForwardMove = 0.0f; 694 | mv->m_flSideMove = 0.0f; 695 | mv->m_flUpMove = 0.0f; 696 | mv->m_nButtons &= ~(IN_JUMP | IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT); 697 | } 698 | 699 | if (m_pCSPlayer->IsAutoMounting() <= 0) 700 | { 701 | CGameMovement::PlayerMove(); // BaseClass::PlayerMove(); 702 | 703 | if (m_pCSPlayer->GetFlags() & FL_ONGROUND) 704 | { 705 | float velocitymodifier = m_pCSPlayer->GetVelocityModifier(); 706 | if (velocitymodifier < 1.0f) 707 | { 708 | float newvelocitymodifier = velocitymodifier + (Interfaces::Globals->frametime * 0.4f); 709 | if (newvelocitymodifier >= 0.0f) 710 | newvelocitymodifier = fminf(newvelocitymodifier, 1.0f); 711 | 712 | if (velocitymodifier != newvelocitymodifier) 713 | m_pCSPlayer->SetVelocityModifier(velocitymodifier); 714 | } 715 | } 716 | 717 | m_pCSPlayer->SetDesiredCollisionGroup(m_pCSPlayer->GetCollisionGroup()); 718 | } 719 | else 720 | { 721 | AutoMountMove(); 722 | } 723 | } 724 | 725 | //----------------------------------------------------------------------------- 726 | // Performs the collision resolution for fliers. 727 | //----------------------------------------------------------------------------- 728 | void CGameMovement::PerformFlyCollisionResolution(trace_t& pm, Vector& move) 729 | { 730 | Vector base; 731 | float vel; 732 | float backoff; 733 | 734 | switch (player->GetMoveCollide()) 735 | { 736 | case MOVECOLLIDE_FLY_CUSTOM: 737 | // Do nothing; the velocity should have been modified by touch 738 | // FIXME: It seems wrong for touch to modify velocity 739 | // given that it can be called in a number of places 740 | // where collision resolution do *not* in fact occur 741 | 742 | // Should this ever occur for players!? 743 | //Assert(0); 744 | break; 745 | 746 | case MOVECOLLIDE_FLY_BOUNCE: 747 | case MOVECOLLIDE_DEFAULT: 748 | { 749 | if (player->GetMoveCollide() == MOVECOLLIDE_FLY_BOUNCE) 750 | backoff = 2.0 - player->GetSurfaceFriction(); 751 | else 752 | backoff = 1; 753 | 754 | ClipVelocity(mv->m_vecVelocity_, pm.plane.normal, mv->m_vecVelocity_, backoff); 755 | } 756 | break; 757 | 758 | default: 759 | // Invalid collide type! 760 | //Assert(0); 761 | break; 762 | } 763 | 764 | // stop if on ground 765 | if (pm.plane.normal[2] > 0.7) 766 | { 767 | base.Init(); 768 | if (mv->m_vecVelocity_[2] < sv_gravity.GetVar()->GetFloat() * Interfaces::Globals->frametime) 769 | { 770 | // we're rolling on the ground, add static friction. 771 | SetGroundEntity(&pm); 772 | mv->m_vecVelocity_[2] = 0; 773 | } 774 | 775 | vel = DotProduct(mv->m_vecVelocity_, mv->m_vecVelocity_); 776 | 777 | // Con_DPrintf("%f %f: %.0f %.0f %.0f\n", vel, trace.fraction, ent->velocity[0], ent->velocity[1], ent->velocity[2] ); 778 | 779 | if (vel < (30 * 30) || (player->GetMoveCollide() != MOVECOLLIDE_FLY_BOUNCE)) 780 | { 781 | SetGroundEntity(&pm); 782 | mv->m_vecVelocity_.Init(); 783 | } 784 | else 785 | { 786 | VectorScale(mv->m_vecVelocity_, (1.0 - pm.fraction) * Interfaces::Globals->frametime * 0.9, move); 787 | PushEntity(move, &pm); 788 | } 789 | VectorSubtract(mv->m_vecVelocity_, base, mv->m_vecVelocity_); 790 | } 791 | } 792 | 793 | float CGameMovement::CalcRoll(const QAngle& angles, const Vector& velocity, float rollangle, float rollspeed) 794 | { 795 | Vector forward, right, up; 796 | AngleVectors((QAngle)angles, &forward, &right, &up); 797 | 798 | float side = DotProduct(velocity, right); 799 | float sign = (side < 0.f) ? -1.f : 1.f; 800 | side = fabs(side); 801 | 802 | float temp = rollangle; 803 | if (side < rollspeed) 804 | side = (side * temp) / rollspeed; 805 | else 806 | side = temp; 807 | 808 | return side * sign; 809 | } 810 | 811 | void CGameMovement::DecayViewPunchAngle() 812 | { 813 | // dont know if its a float or int 814 | auto viewPunchDecay = view_punch_decay.GetVar()->GetFloat(); 815 | 816 | float timemultiplier = Interfaces::Globals->interval_per_tick * viewPunchDecay; 817 | timemultiplier = expf(-timemultiplier); 818 | QAngle viewpunch = player->GetViewPunch(); 819 | QAngle newpunch = viewpunch * timemultiplier; 820 | 821 | if (sqrtf(pow(newpunch.x, 2) + pow(newpunch.y, 2) + pow(newpunch.z, 2)) <= 0.0f) 822 | newpunch = angZero; 823 | 824 | if (newpunch != viewpunch) 825 | { 826 | player->GetLocalData()->NetworkStateChanged((void*)player->GetViewPunchAdr()); 827 | player->SetViewPunch(newpunch); 828 | } 829 | } 830 | 831 | //dangerzone correct 832 | void CGameMovement::CheckWaterJump() 833 | { 834 | if (player->GetWaterJumpTime() == 0.0f) 835 | { 836 | if (mv->m_vecVelocity_.z >= -180.f) 837 | { 838 | Vector flatVelocity = { mv->m_vecVelocity_.x, mv->m_vecVelocity_.y, 0.0f }; 839 | float curspeed = VectorNormalize(flatVelocity); 840 | 841 | Vector flatForward = { m_vecForward.x, m_vecForward.y, 0.0f }; 842 | VectorNormalizeFast(flatForward); 843 | 844 | if (curspeed != 0.0f && DotProduct(flatVelocity, flatForward) >= 0.0f) 845 | { 846 | Vector start, end; 847 | start = mv->_m_vecAbsOrigin + GetPlayerMins() + GetPlayerMaxs() * 0.5f; 848 | 849 | VectorMA(start, 24.0f, flatForward, end); 850 | 851 | auto mask = PlayerSolidMask(); 852 | 853 | trace_t tr; 854 | TracePlayerBBox(start, end, mask, COLLISION_GROUP_PLAYER_MOVEMENT, tr); 855 | 856 | if (tr.fraction < 1.f) 857 | { 858 | // physicsObj = *(v34 + 0x29C); 859 | IPhysicsObject* physObj = tr.m_pEnt->VPhysicsGetObject(); 860 | 861 | if (physObj) 862 | { 863 | if ((physObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD)) 864 | return; 865 | } 866 | 867 | // !((*(*physicsObj + 76))() & 4) ) 868 | if (!tr.m_pEnt || tr.m_pEnt->CanWaterJump()) 869 | { 870 | start.z = mv->_m_vecAbsOrigin.z + player->GetViewOffset().z + 8.f; 871 | 872 | VectorMA(start, 24.0f, flatForward, end); 873 | // vecWaterJumpVel = *(DWORD*)(player + 0x33E8); 874 | Vector waterjumpvel; 875 | VectorMA(Vector(0, 0, 0), -50.0f, tr.plane.normal, waterjumpvel); 876 | player->SetWaterJumpVel(waterjumpvel); 877 | 878 | TracePlayerBBox(start, end, mask, COLLISION_GROUP_PLAYER_MOVEMENT, tr); 879 | 880 | if (tr.fraction == 1.f) 881 | { 882 | start = end; 883 | end.z -= 1024.0f; 884 | 885 | TracePlayerBBox(start, end, mask, COLLISION_GROUP_PLAYER_MOVEMENT, tr); 886 | 887 | if (tr.fraction < 1.f && tr.plane.normal.z >= 0.7) 888 | { 889 | mv->m_vecVelocity_.z = 256.f; 890 | mv->m_nOldButtons |= IN_JUMP; 891 | player->AddFlag(FL_WATERJUMP); 892 | player->SetWaterJumpTime(2000.f); 893 | } 894 | } 895 | } 896 | } 897 | } 898 | } 899 | } 900 | } 901 | 902 | void CGameMovement::WaterMove() 903 | { 904 | Vector forward, right, up; 905 | AngleVectors(mv->m_vecViewAngles, &forward, &right, &up); 906 | 907 | Vector wishvel; 908 | 909 | wishvel.x = (forward.x * mv->m_flForwardMove) + (right.x * mv->m_flSideMove); 910 | wishvel.y = (forward.y * mv->m_flForwardMove) + (right.y * mv->m_flSideMove); 911 | wishvel.z = (forward.z * mv->m_flForwardMove) + (right.z * mv->m_flSideMove); 912 | 913 | if (sv_water_swim_mode.GetVar()->GetInt() == 1) 914 | { 915 | float headz = mv->_m_vecAbsOrigin.z + player->GetViewOffset().z; 916 | //prevent going under water 917 | float waterz = UTIL_FindWaterSurface(mv->_m_vecAbsOrigin, headz, mv->_m_vecAbsOrigin.z); 918 | float newflt = (headz - 12.0f) - waterz; 919 | 920 | if (newflt >= 0.0f) 921 | { 922 | if (newflt <= 0.0f) 923 | { 924 | wishvel.z = 0.0f; 925 | } 926 | else 927 | { 928 | wishvel.z = newflt * -5.0f; 929 | } 930 | } 931 | else 932 | { 933 | SetGroundEntity(nullptr); 934 | wishvel.z = newflt * -15.0f; 935 | } 936 | } 937 | else 938 | { 939 | if (mv->m_nButtons & IN_JUMP) 940 | { 941 | wishvel.z = mv->m_flClientMaxSpeed + wishvel.z; 942 | } 943 | else if (mv->m_flForwardMove == 0.f && mv->m_flSideMove == 0.f && mv->m_flUpMove == 0.f) 944 | { 945 | float v18 = 0.0f; 946 | float v19 = (mv->m_flForwardMove * forward.z) + (mv->m_flForwardMove * forward.z); 947 | if (v19 >= 0.0f) 948 | v18 = fminf(mv->m_flClientMaxSpeed, v19); 949 | wishvel.z += (mv->m_flUpMove + v18); 950 | } 951 | else 952 | { 953 | wishvel.z -= 60.0f; 954 | } 955 | } 956 | 957 | Vector wishdir = wishvel; 958 | float wishspeed = VectorNormalize(wishdir); 959 | 960 | if (wishspeed > mv->_m_flMaxSpeed) 961 | { 962 | VectorScale(wishvel, mv->_m_flMaxSpeed / wishspeed, wishvel); 963 | wishspeed = mv->_m_flMaxSpeed; 964 | } 965 | 966 | wishspeed *= sv_water_movespeed_multiplier.GetVar()->GetFloat(); 967 | 968 | Vector temp = mv->m_vecVelocity_; 969 | float speed = VectorNormalize(temp); 970 | 971 | float newspeed = 0.f; 972 | 973 | if (speed != 0.f) 974 | { 975 | // m_surfaceFriction = 0x3210; 976 | newspeed = speed - Interfaces::Globals->curtime * speed * sv_friction.GetVar()->GetFloat() * player->GetSurfaceFriction(); 977 | 978 | if (newspeed < 0.1f) 979 | newspeed = 0.0f; 980 | 981 | VectorScale(mv->m_vecVelocity_, newspeed / speed, mv->m_vecVelocity_); 982 | } 983 | else 984 | { 985 | newspeed = 0.f; 986 | } 987 | 988 | if (wishspeed >= 0.1f) 989 | { 990 | float addspeed = wishspeed - newspeed; 991 | 992 | if (addspeed > 0.f) 993 | { 994 | VectorNormalizeFast(wishvel); 995 | float accelspeed = sv_accelerate.GetVar()->GetFloat() * wishspeed * Interfaces::Globals->curtime * player->GetSurfaceFriction(); 996 | 997 | if (accelspeed > addspeed) 998 | accelspeed = addspeed; 999 | 1000 | mv->m_vecVelocity_.x += (accelspeed * wishvel.x); 1001 | mv->m_vecVelocity_.y += (accelspeed * wishvel.y); 1002 | mv->m_vecVelocity_.z += (accelspeed * wishvel.z); 1003 | 1004 | mv->m_outWishVel.x += (accelspeed * wishvel.x); 1005 | mv->m_outWishVel.y += (accelspeed * wishvel.x); 1006 | mv->m_outWishVel.z += (accelspeed * wishvel.x); 1007 | } 1008 | } 1009 | 1010 | // *(ent + 0x11C) base velocity 1011 | mv->m_vecVelocity_ += player->GetBaseVelocity(); 1012 | 1013 | Vector dest; 1014 | VectorMA(mv->_m_vecAbsOrigin, Interfaces::Globals->curtime, mv->m_vecVelocity_, dest); 1015 | 1016 | trace_t tr; 1017 | TracePlayerBBox(mv->_m_vecAbsOrigin, dest, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 1018 | 1019 | if (tr.fraction != 1.f) 1020 | { 1021 | if (player->GetGroundEntity() != nullptr) 1022 | { 1023 | StepMove(dest, tr); 1024 | goto jmp; 1025 | } 1026 | 1027 | TryPlayerMove(); 1028 | goto jmp; 1029 | } 1030 | else 1031 | { 1032 | Vector start = dest; 1033 | 1034 | if (player->GetAllowAutoMovement()) 1035 | start.z += player->GetStepSize() + 1.f; 1036 | 1037 | TracePlayerBBox(start, dest, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 1038 | 1039 | if (tr.startsolid && !tr.allsolid) 1040 | { 1041 | float stepDist = tr.endpos.z - mv->_m_vecAbsOrigin.z; 1042 | mv->m_outStepHeight += stepDist; 1043 | 1044 | mv->_m_vecAbsOrigin = tr.endpos; 1045 | 1046 | goto jmp; 1047 | } 1048 | 1049 | TryPlayerMove(); 1050 | } 1051 | 1052 | jmp: 1053 | mv->m_vecVelocity_ -= player->GetBaseVelocity(); 1054 | } 1055 | 1056 | void CGameMovement::SlimeMove() 1057 | { 1058 | Vector forward, right, up; 1059 | AngleVectors(mv->m_vecViewAngles, &forward, &right, &up); 1060 | 1061 | Vector wishvel; 1062 | 1063 | wishvel.x = (forward.x * mv->m_flForwardMove) + (right.x * mv->m_flSideMove); 1064 | wishvel.y = forward.y * (mv->m_flForwardMove) + (right.y * mv->m_flSideMove); 1065 | wishvel.z = forward.z * (mv->m_flForwardMove) + (right.z * mv->m_flSideMove) - 5.0f; 1066 | 1067 | if (mv->m_nButtons & IN_JUMP) 1068 | wishvel.z += mv->m_flClientMaxSpeed; 1069 | 1070 | float wishspeed = wishvel.Length(); 1071 | 1072 | if (wishspeed > mv->_m_flMaxSpeed) 1073 | { 1074 | wishspeed = mv->_m_flMaxSpeed; 1075 | VectorScale(wishvel, mv->_m_flMaxSpeed / wishspeed, wishvel); 1076 | } 1077 | 1078 | float speed = mv->m_vecVelocity_.Length(); 1079 | 1080 | float newspeed = 0.f; 1081 | 1082 | if (speed != 0.f) 1083 | { 1084 | // m_surfaceFriction = 0x3210; 1085 | newspeed = speed - Interfaces::Globals->curtime * speed * sv_friction.GetVar()->GetFloat() * player->GetSurfaceFriction(); 1086 | 1087 | if (newspeed < 0.1f) 1088 | newspeed = 0.0f; 1089 | 1090 | VectorScale(mv->m_vecVelocity_, newspeed / speed, mv->m_vecVelocity_); 1091 | } 1092 | else 1093 | { 1094 | newspeed = 0.f; 1095 | } 1096 | 1097 | if (wishspeed >= 0.1f) 1098 | { 1099 | float addspeed = wishspeed - newspeed; 1100 | 1101 | if (addspeed > 0.f) 1102 | { 1103 | VectorNormalizeFast(wishvel); 1104 | float accelspeed = sv_accelerate.GetVar()->GetFloat() * wishspeed * Interfaces::Globals->curtime * player->GetSurfaceFriction(); 1105 | 1106 | if (accelspeed > addspeed) 1107 | accelspeed = addspeed; 1108 | 1109 | mv->m_vecVelocity_.x += (accelspeed * wishvel.x); 1110 | mv->m_vecVelocity_.y += (accelspeed * wishvel.y); 1111 | mv->m_vecVelocity_.z += (accelspeed * wishvel.z); 1112 | 1113 | mv->m_outWishVel.x += (accelspeed * wishvel.x); 1114 | mv->m_outWishVel.y += (accelspeed * wishvel.x); 1115 | mv->m_outWishVel.z += (accelspeed * wishvel.x); 1116 | } 1117 | } 1118 | 1119 | // *(ent + 0x11C) base velocity 1120 | mv->m_vecVelocity_ += player->GetBaseVelocity(); 1121 | 1122 | float maxvelspeed, minvelspeed; 1123 | 1124 | if (player->GetUnknownEntity(0) == 0) 1125 | { 1126 | if (player->GetWaterLevel() < WL_Waist) 1127 | { 1128 | maxvelspeed = 120.0f; 1129 | minvelspeed = -50.0f; 1130 | } 1131 | else 1132 | { 1133 | maxvelspeed = 60.0f; 1134 | minvelspeed = -25.0f; 1135 | } 1136 | if (minvelspeed <= mv->m_vecVelocity_.z) 1137 | minvelspeed = fminf(mv->m_vecVelocity_.z, 5.0f); 1138 | } 1139 | else 1140 | { 1141 | if (player->GetWaterLevel() < WL_Waist) 1142 | { 1143 | minvelspeed = -100.0f; 1144 | maxvelspeed = 80.0f; 1145 | if (mv->m_vecVelocity_.z >= 100.0f) 1146 | minvelspeed = fminf(mv->m_vecVelocity_.z, 0.0f); 1147 | } 1148 | else 1149 | { 1150 | minvelspeed = -50.0f; 1151 | maxvelspeed = 30.0f; 1152 | if (mv->m_vecVelocity_.z >= -50.0f) 1153 | minvelspeed = fminf(mv->m_vecVelocity_.z, 0.0f); 1154 | } 1155 | } 1156 | mv->m_vecVelocity_.z = minvelspeed; 1157 | 1158 | if (mv->m_vecVelocity_.Length() > maxvelspeed) 1159 | { 1160 | VectorNormalize(mv->m_vecVelocity_); 1161 | mv->m_vecVelocity_ *= maxvelspeed; 1162 | } 1163 | 1164 | Vector dest; 1165 | VectorMA(mv->_m_vecAbsOrigin, Interfaces::Globals->curtime, mv->m_vecVelocity_, dest); 1166 | 1167 | trace_t tr; 1168 | TracePlayerBBox(mv->_m_vecAbsOrigin, dest, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 1169 | 1170 | if (tr.fraction != 1.f) 1171 | { 1172 | if (player->GetGroundEntity() != nullptr) 1173 | { 1174 | StepMove(dest, tr); 1175 | mv->m_vecVelocity_ -= player->GetBaseVelocity(); 1176 | return; 1177 | } 1178 | 1179 | TryPlayerMove(); 1180 | 1181 | mv->m_vecVelocity_ -= player->GetBaseVelocity(); 1182 | return; 1183 | } 1184 | else 1185 | { 1186 | Vector start = dest; 1187 | 1188 | if (player->GetAllowAutoMovement()) 1189 | start.z += player->GetStepSize() + 1.f; 1190 | 1191 | TracePlayerBBox(start, dest, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 1192 | 1193 | if (tr.startsolid && !tr.allsolid) 1194 | { 1195 | float stepDist = tr.endpos.z - mv->_m_vecAbsOrigin.z; 1196 | mv->m_outStepHeight += stepDist; 1197 | 1198 | mv->_m_vecAbsOrigin = tr.endpos; 1199 | 1200 | mv->m_vecVelocity_ -= player->GetBaseVelocity(); 1201 | return; 1202 | } 1203 | 1204 | TryPlayerMove(); 1205 | } 1206 | 1207 | mv->m_vecVelocity_ -= player->GetBaseVelocity(); 1208 | } 1209 | 1210 | void CGameMovement::WaterJump() 1211 | { 1212 | if (player->GetWaterJumpTime() > 10000.f) 1213 | player->SetWaterJumpTime(10000.f); 1214 | 1215 | if (player->GetWaterJumpTime() != 0.f) 1216 | { 1217 | player->SetWaterJumpTime(player->GetWaterJumpTime() - Interfaces::Globals->frametime * 10000.f); 1218 | 1219 | if (player->GetWaterJumpTime() <= 0.f || player->GetWaterLevel() == 0) 1220 | { 1221 | player->SetWaterJumpTime(0.f); 1222 | player->RemoveFlag(FL_WATERJUMP); 1223 | } 1224 | 1225 | mv->m_vecVelocity_.x = player->GetWaterJumpVel().x; 1226 | mv->m_vecVelocity_.y = player->GetWaterJumpVel().y; 1227 | } 1228 | } 1229 | 1230 | void CGameMovement::Friction() 1231 | { 1232 | if (player->GetWaterJumpTime() == 0.f) 1233 | { 1234 | float speed = mv->m_vecVelocity_.Length(); 1235 | 1236 | if (speed >= 0.1f) 1237 | { 1238 | float drop = 0.f; 1239 | 1240 | if (player->GetGroundEntity() != nullptr) 1241 | { 1242 | float friction = player->GetSurfaceFriction() * sv_friction.GetVar()->GetFloat(); 1243 | float stopspeed = sv_stopspeed.GetVar()->GetFloat(); 1244 | float control = speed < stopspeed ? stopspeed : speed; 1245 | 1246 | drop = (control * friction) * Interfaces::Globals->frametime; 1247 | } 1248 | 1249 | float newspeed = fmaxf(speed - drop, 0.f); 1250 | 1251 | if (newspeed != speed) 1252 | { 1253 | newspeed /= speed; 1254 | mv->m_vecVelocity_ *= newspeed; 1255 | } 1256 | 1257 | mv->m_outWishVel -= (mv->m_vecVelocity_ * (1.f - newspeed)); 1258 | } 1259 | } 1260 | } 1261 | 1262 | void CGameMovement::AirAccelerate(Vector& wishdir, float wishspeed, float accel) 1263 | { 1264 | if (!player->GetDeadFlag() && player->GetWaterJumpTime() == 0.f) 1265 | { 1266 | float v3 = fminf(wishspeed, 30.f) - mv->m_vecVelocity_.Dot(wishdir); 1267 | 1268 | if (v3 > 0.f) 1269 | { 1270 | float v7 = fminf(wishspeed * accel * Interfaces::Globals->frametime * player->GetSurfaceFriction(), v3); 1271 | 1272 | mv->m_vecVelocity_ += wishdir * v7; 1273 | mv->m_outWishVel += wishdir * v7; 1274 | } 1275 | } 1276 | } 1277 | 1278 | 1279 | //This function is not fully rebuilt because Valve changed this function many times shortly after dangerzone came out and I didn't feel like finishing it 1280 | void CCSGameMovement::AirMove() 1281 | { 1282 | CGameMovement::AirMove(); 1283 | 1284 | auto cplayer = m_pCSPlayer; 1285 | if (cplayer->IsAutoMounting()) 1286 | cplayer->SetIsAutoMounting(0); 1287 | 1288 | int ledgehelper = sv_ledge_mantle_helper.GetVar()->GetInt(); 1289 | if (ledgehelper <= 0) 1290 | return; 1291 | 1292 | bool debug = sv_ledge_mantle_helper_debug.GetVar()->GetBool(); 1293 | 1294 | Vector vForward; 1295 | cplayer->EyeVectors(&vForward); 1296 | 1297 | float v107; 1298 | float v108; 1299 | 1300 | float len = vForward.Length2D(); 1301 | if (len == 0.0f) 1302 | { 1303 | v108 = 0.0f; 1304 | v107 = 0.0f; 1305 | } 1306 | else 1307 | { 1308 | v107 = (1.0f / len) * vForward.x; 1309 | v108 = (1.0f / len) * vForward.y; 1310 | } 1311 | Vector boxmin = { -12.0f, -12.0f, 0.0f }; 1312 | Vector boxmax = { 12.0f, 12.0f, 3.0f }; 1313 | Vector boxmin2 = { -10.0f, -10.0f, 0.0f }; 1314 | Vector boxmax2 = { 10.0f, 10.0f, 24.0f }; 1315 | 1316 | if (mv->m_flForwardMove <= 0.0f || !(mv->m_nButtons & IN_DUCK)) 1317 | return; 1318 | 1319 | Vector vel = mv->m_vecVelocity_; 1320 | 1321 | float speed = vel.Length(); 1322 | 1323 | float speedclamp = fmaxf(speed * 0.12f, 12.0f); 1324 | 1325 | Vector *origin = cplayer->GetAbsOrigin(); 1326 | 1327 | trace_t tr; 1328 | UTIL_TraceLine(*origin, *origin + Vector(0.0f, 0.0f, -14.0f), 0x2000B, cplayer, COLLISION_GROUP_PLAYER_MOVEMENT, &tr); 1329 | 1330 | 1331 | Vector end; 1332 | end.x = (v107 * speedclamp) + origin->x; 1333 | end.y = (v108 * speedclamp) + origin->y; 1334 | end.z = (speedclamp * 0.0f) + origin->z; 1335 | 1336 | trace_t tr2; 1337 | UTIL_TraceHull(*origin, end, boxmin2, boxmax2, PlayerSolidMask(), cplayer, COLLISION_GROUP_PLAYER_MOVEMENT, tr2); 1338 | 1339 | if (debug) 1340 | { 1341 | if (tr2.fraction == 1.0f && Interfaces::DebugOverlay) 1342 | Interfaces::DebugOverlay->AddBoxOverlay(tr2.endpos, boxmin2, boxmax2, angZero, 255, 0, 80, 255, 6.0f); 1343 | 1344 | if (tr.fraction != 1.0f) 1345 | { 1346 | Vector endpos = *cplayer->GetAbsOrigin(); 1347 | endpos.z -= 14.0f; 1348 | if (Interfaces::ClientEntList->GetBaseEntity(Interfaces::EngineClient->GetLocalPlayer()) && Interfaces::DebugOverlay) 1349 | Interfaces::DebugOverlay->AddLineOverlay(*cplayer->GetAbsOrigin(), endpos, 255, 0, 80, 1, 6.0f); 1350 | } 1351 | } 1352 | if (tr.fraction != 1.0f) 1353 | return; 1354 | if (tr2.fraction >= 1.0f) 1355 | return; 1356 | 1357 | Vector pos1 = *cplayer->GetAbsOrigin(); 1358 | pos1.z += 2.0f; 1359 | 1360 | Vector pos2 = pos2; 1361 | float v110 = v107 + 20.0f; 1362 | pos2.x += (v107 * (v107 + 20.0f)); 1363 | pos2.y += (v108 * (v107 + 20.0f)); 1364 | pos2.z += ((v107 + 20.0f) * 0.0f); 1365 | 1366 | ledgehelper = sv_ledge_mantle_helper.GetVar()->GetFloat(); 1367 | 1368 | if (ledgehelper == 3) 1369 | { 1370 | float zclamp = fminf(vForward.z, 0.44f); 1371 | Vector eyepos; 1372 | cplayer->EyePosition(eyepos); 1373 | 1374 | pos1.x = eyepos.x; 1375 | pos1.y = eyepos.y; 1376 | 1377 | eyepos.z -= 4.0f; 1378 | pos2.x = (v110 * speedclamp) + eyepos.x; 1379 | pos2.y = (v110 * vForward.y) + eyepos.y; 1380 | pos2.z = eyepos.z + (zclamp * v110); 1381 | 1382 | pos1.z = eyepos.z; 1383 | } 1384 | 1385 | CTraceFilterForPlayerHeadCollision filter; 1386 | filter.m_pPassEnt1 = (IHandleEntity*)cplayer; 1387 | filter.m_pSkip = filter.m_pPassEnt1; 1388 | filter.m_iCollisionGroup = COLLISION_GROUP_PLAYER_MOVEMENT; 1389 | filter.m_Unknown = 0; 1390 | 1391 | trace_t tr3; 1392 | UTIL_TraceHull(pos1, pos2, boxmin, boxmax, PlayerSolidMask(), (ITraceFilter*)&filter, tr3); 1393 | 1394 | if (debug) 1395 | { 1396 | if (tr3.fraction != 1.0f) 1397 | { 1398 | if (Interfaces::DebugOverlay) 1399 | Interfaces::DebugOverlay->AddBoxOverlay(tr3.endpos, boxmin, boxmax, angZero, 255, 0, 0, 128, 6.0f); 1400 | return; 1401 | } 1402 | if (Interfaces::DebugOverlay) 1403 | Interfaces::DebugOverlay->AddBoxOverlay(tr3.endpos, boxmin, boxmax, angZero, 0, 255, 0, 255, 6.0f); 1404 | } 1405 | else if (tr3.fraction != 1.0f) 1406 | { 1407 | return; 1408 | } 1409 | 1410 | float v47 = (tr2.fraction * v107) + 1.5f; 1411 | trace_t tr4; 1412 | 1413 | Vector startnew; 1414 | startnew.z = pos1.z; 1415 | startnew.x = tr2.endpos.x + (v107 * v47); 1416 | startnew.y = tr2.endpos.y + (v108 * v47); 1417 | Vector endnew; 1418 | endnew.x = startnew.x; 1419 | endnew.y = startnew.y; 1420 | endnew.z = pos1.z - 64.0f; 1421 | 1422 | UTIL_TraceHull(startnew, endnew, boxmin, boxmax, PlayerSolidMask(), (ITraceFilter*)&filter, tr4); 1423 | if (tr4.DidHit()) 1424 | { 1425 | Vector newend2; 1426 | newend2 = tr4.endpos; 1427 | newend2.z += 3.0f; 1428 | 1429 | CViewVectors* vectors = GetGamerules()->GetViewVectors(); 1430 | trace_t tr5; 1431 | UTIL_TraceHull(tr4.endpos, newend2, vectors->m_vHullMin, vectors->m_vHullMax, PlayerSolidMask(), (ITraceFilter*)&filter, tr5); 1432 | 1433 | bool v100; 1434 | 1435 | if (tr5.startsolid || tr5.allsolid || (v100 = true, tr5.fraction != 1.0f)) 1436 | v100 = false; 1437 | 1438 | Vector newend3 = tr4.endpos; 1439 | newend3.z += 3.0f; 1440 | trace_t tr6; 1441 | 1442 | UTIL_TraceHull(tr4.endpos, newend3, vectors->m_vDuckHullMin, vectors->m_vDuckHullMax, PlayerSolidMask(), (ITraceFilter*)&filter, tr6); 1443 | 1444 | if (tr6.startsolid || tr6.allsolid || tr6.fraction != 1.0f) 1445 | { 1446 | Vector end4; 1447 | //end4.x = tr4.endpos.x + (tr.endpos.x) 1448 | 1449 | //FIXME: FINISH ME 1450 | } 1451 | } 1452 | } 1453 | 1454 | void CGameMovement::AirMove() 1455 | { 1456 | Vector forward, right, up; 1457 | 1458 | AngleVectors(mv->m_vecViewAngles, &forward, &right, &up); 1459 | 1460 | float sidemove = mv->m_flSideMove; 1461 | float forwardmove = mv->m_flForwardMove; 1462 | 1463 | forward.z = 0.f; 1464 | right.z = 0.f; 1465 | 1466 | VectorNormalizeFast(forward); 1467 | VectorNormalizeFast(right); 1468 | 1469 | Vector wishVel = { 1470 | forward.x * forwardmove + right.x * sidemove, 1471 | forward.y * forwardmove + right.y * sidemove, 1472 | 0.f 1473 | }; 1474 | 1475 | Vector wishdir = wishVel; 1476 | float wishspeed = VectorNormalize(wishdir); 1477 | 1478 | if (wishspeed != 0.f && wishspeed > mv->_m_flMaxSpeed) 1479 | { 1480 | wishspeed = mv->_m_flMaxSpeed; 1481 | } 1482 | 1483 | float airaccelerate; 1484 | float airaccelerate_parachute; 1485 | 1486 | CBaseEntity *movingplayer = GetMovingPlayer(); 1487 | if (!movingplayer || !movingplayer->IsPlayer() || movingplayer->GetMaxFallVelocity() == 0.0f) 1488 | { 1489 | airaccelerate = sv_airaccelerate.GetVar()->GetFloat(); 1490 | } 1491 | else 1492 | { 1493 | if (!movingplayer->IsSpawnRappelling()) 1494 | { 1495 | if (sv_air_pushaway_dist.GetVar()->GetFloat()) 1496 | { 1497 | movingplayer = GetMovingPlayer(); 1498 | if (movingplayer->GetAliveVMT()) 1499 | { 1500 | Vector someVector = vecZero; 1501 | Vector destVector = vecZero; 1502 | for (int i = 1; i <= MAX_PLAYERS; i++) //VALVE BUG: this is set to 0 and < MAX_PLAYERS which is wrong!! 1503 | { 1504 | CBaseEntity* playerindex = Interfaces::ClientEntList->GetBaseEntity(i); //UTIL_PlayerFromIndex is the original function 1505 | if (playerindex && playerindex->IsPlayer() && movingplayer != playerindex && playerindex->GetAliveVMT() && playerindex->GetMaxFallVelocity() != 0.0f) 1506 | { 1507 | Vector movingplayerorigin = *playerindex->GetAbsOrigin(); 1508 | Vector vecDelta = movingplayerorigin - *movingplayer->GetAbsOrigin(); 1509 | float dist = vecDelta.Length(); 1510 | float pushawaydist = sv_air_pushaway_dist.GetVar()->GetFloat(); 1511 | if (pushawaydist > dist) 1512 | { 1513 | float maxspd = mv->_m_flMaxSpeed; 1514 | if (pushawaydist == 32.0f) 1515 | { 1516 | if (dist - pushawaydist >= 0.0f) 1517 | maxspd = 0.0f; 1518 | } 1519 | else 1520 | { 1521 | float v41 = (dist - 32.0f) / (pushawaydist - 32.0f); 1522 | v41 = clamp(v41, 0.0f, 1.0f); 1523 | maxspd *= (1.0f - v41); 1524 | } 1525 | 1526 | Vector normalized = movingplayerorigin; 1527 | VectorNormalizeFast(normalized); 1528 | destVector = someVector; 1529 | Vector newpos = normalized * maxspd; 1530 | 1531 | destVector = someVector + newpos; 1532 | someVector += newpos; 1533 | 1534 | continue; 1535 | } 1536 | } 1537 | destVector = someVector; 1538 | } 1539 | 1540 | if (destVector.LengthSqr() != 0.0f) 1541 | { 1542 | Vector destcpy = destVector; 1543 | VectorNormalizeFast(destcpy); 1544 | wishspeed = destcpy.Length(); 1545 | } 1546 | } 1547 | } 1548 | airaccelerate = sv_airaccelerate_parachute.GetVar()->GetFloat(); 1549 | //if couldn't find sv_airaccelerate_parachute, use sv_airaccelerate 1550 | } 1551 | else 1552 | { 1553 | airaccelerate = sv_airaccelerate_rappel.GetVar()->GetFloat(); 1554 | } 1555 | } 1556 | 1557 | AirAccelerate(wishdir, wishspeed, airaccelerate); 1558 | 1559 | mv->m_vecVelocity_ += player->GetBaseVelocity(); 1560 | 1561 | TryPlayerMove(); 1562 | 1563 | mv->m_vecVelocity_ -= player->GetBaseVelocity(); 1564 | } 1565 | 1566 | bool CGameMovement::CanAccelerate() 1567 | { 1568 | return (!player->GetDeadFlag() && player->GetWaterJumpTime() == 0.f); 1569 | } 1570 | 1571 | //dangerzone correct 1572 | bool CCSGameMovement::CanAccelerate() 1573 | { 1574 | if (m_pCSPlayer->GetPlayerState()) 1575 | return player->IsObserver(); 1576 | else 1577 | return (player->GetWaterJumpTime() == 0.f); 1578 | } 1579 | 1580 | void CGameMovement::Accelerate(Vector& wishdir, float wishspeed, float accel) 1581 | { 1582 | if (CanAccelerate()) 1583 | { 1584 | float v6 = wishspeed - mv->m_vecVelocity_.Dot(wishdir); 1585 | 1586 | if (v6 > 0.f) 1587 | { 1588 | float v7 = fminf(Interfaces::Globals->frametime * accel * fmaxf(wishspeed, 250.f) * player->GetSurfaceFriction(), v6); 1589 | 1590 | mv->m_vecVelocity_ += wishdir * v7; 1591 | } 1592 | } 1593 | } 1594 | 1595 | //dangerzone correct, NOT CORRECT AFTER APRIL 30, 2019 UPDATE 1596 | void CCSGameMovement::Accelerate(Vector& wishdir, float wishspeed, float accel) 1597 | { 1598 | if (!CanAccelerate()) 1599 | return; 1600 | 1601 | float v7 = mv->m_vecVelocity_.Dot(wishdir); 1602 | float v60 = wishspeed - v7; 1603 | 1604 | if (v60 <= 0.f) 1605 | return; 1606 | 1607 | float v57 = fmaxf(v7, 0.f); 1608 | bool bDucking = true; 1609 | 1610 | if (!(mv->m_nButtons & IN_DUCK)) 1611 | { 1612 | if (!player->GetDucking() && !(player->GetFlags() & FL_DUCKING)) 1613 | bDucking = false; 1614 | } 1615 | 1616 | bool bUnknown2 = true; 1617 | 1618 | if (!(mv->m_nButtons & IN_SPEED) || bDucking) 1619 | bUnknown2 = false; 1620 | 1621 | float backupfinalwishspeed; 1622 | float finalwishspeed = fmaxf(wishspeed, 250.f); 1623 | float backupfinalwishspeed_new = finalwishspeed; 1624 | float finalwishspeed2; 1625 | 1626 | CBaseEntity* move_player = player; 1627 | if (!player || !player->IsPlayer()) 1628 | move_player = nullptr; 1629 | 1630 | CBaseCombatWeapon* weapon = player->GetWeapon(); 1631 | 1632 | bool bShouldSlowSpeedDown = false; 1633 | bool bUnknown = false; 1634 | float abs_final_wish_speed; 1635 | 1636 | if (sv_accelerate_use_weapon_speed.GetVar()->GetBool() && weapon != nullptr) 1637 | { 1638 | float flWpnMoveModifier = weapon->GetMaxSpeed(); 1639 | float flClampedWpnMoveModifier; 1640 | float flBackupWpnMoveModifier; 1641 | 1642 | if (weapon->GetZoomLevelVMT() <= 0 || weapon->GetNumZoomLevels() <= 1) 1643 | bShouldSlowSpeedDown = false; 1644 | else 1645 | { 1646 | flBackupWpnMoveModifier = weapon->GetMaxSpeed() * _CS_PLAYER_SPEED_WALK_MODIFIER; 1647 | if (110.0f > flBackupWpnMoveModifier) 1648 | { 1649 | bShouldSlowSpeedDown = true; 1650 | } 1651 | else 1652 | { 1653 | bShouldSlowSpeedDown = false; 1654 | } 1655 | } 1656 | 1657 | flWpnMoveModifier = weapon->GetMaxSpeed() * _CS_PLAYER_MAXSPEED_MODIFIER; 1658 | 1659 | flClampedWpnMoveModifier = fminf(flWpnMoveModifier, 1.0f); 1660 | 1661 | if (!bDucking && !bUnknown2 || bShouldSlowSpeedDown) 1662 | finalwishspeed *= flClampedWpnMoveModifier; 1663 | 1664 | //decrypts(0) 1665 | static ConVar* sv_weapon_encumbrance_scale = Interfaces::Cvar->FindVar(XorStr("sv_weapon_encumbrance_scale")); 1666 | //encrypts(0) 1667 | if (sv_weapon_encumbrance_scale->GetFloat() != 0.0f && move_player) 1668 | { 1669 | float enc = move_player->GetEncumberance(); 1670 | flBackupWpnMoveModifier = enc; 1671 | if (flClampedWpnMoveModifier > enc) 1672 | { 1673 | bUnknown = true; 1674 | //decrypts(0) 1675 | static ConVar* sv_weapon_encumbrance_scale = Interfaces::Cvar->FindVar(XorStr("sv_weapon_encumbrance_scale")); 1676 | //encrypts(0) 1677 | flClampedWpnMoveModifier += ((flBackupWpnMoveModifier - flClampedWpnMoveModifier) * sv_weapon_encumbrance_scale->GetFloat()); 1678 | } 1679 | abs_final_wish_speed = fmaxf(flClampedWpnMoveModifier, _CS_PLAYER_SPEED_DUCK_MODIFIER) * backupfinalwishspeed_new; 1680 | } 1681 | else 1682 | { 1683 | abs_final_wish_speed = flClampedWpnMoveModifier * backupfinalwishspeed_new; 1684 | } 1685 | } 1686 | else 1687 | { 1688 | abs_final_wish_speed = finalwishspeed; 1689 | } 1690 | 1691 | if (bDucking) 1692 | { 1693 | if (!bShouldSlowSpeedDown) 1694 | finalwishspeed *= _CS_PLAYER_SPEED_DUCK_MODIFIER; 1695 | abs_final_wish_speed *= _CS_PLAYER_SPEED_DUCK_MODIFIER; 1696 | } 1697 | 1698 | if (bUnknown2) 1699 | { 1700 | if (!m_pCSPlayer->HasHeavyArmor() && !m_pCSPlayer->IsCarryingHostage() && !bShouldSlowSpeedDown) 1701 | finalwishspeed *= _CS_PLAYER_SPEED_WALK_MODIFIER; 1702 | 1703 | abs_final_wish_speed *= _CS_PLAYER_SPEED_WALK_MODIFIER; 1704 | } 1705 | 1706 | float surfacefriction = player->GetSurfaceFriction(); 1707 | float v26 = ((Interfaces::Globals->frametime * accel) * finalwishspeed) * surfacefriction; 1708 | 1709 | if (bUnknown && v57 > (abs_final_wish_speed - v26)) 1710 | { 1711 | float v27 = 1.0f 1712 | - (fmaxf(v57 - (abs_final_wish_speed - v26), 0.0f) 1713 | / fmaxf(abs_final_wish_speed - (abs_final_wish_speed - v26), 0.0f)); 1714 | 1715 | if (v27 >= 0.0f) 1716 | accel = fminf(v27, 1.0f) * accel; 1717 | else 1718 | accel *= 0.0f; 1719 | } 1720 | 1721 | if (bUnknown2 && v57 > (abs_final_wish_speed - 5.0f)) 1722 | { 1723 | float v28 = fmaxf(v57 - (abs_final_wish_speed - 5.0f), 0.0f) 1724 | / fmaxf(abs_final_wish_speed - (float)(abs_final_wish_speed - 5.0f), 0.0f); 1725 | if ((1.0f - v28) >= 0.0f) 1726 | accel = fminf(1.0f - v28, 1.0f) * accel; 1727 | else 1728 | accel = 0.0f * accel; 1729 | } 1730 | 1731 | float v30 = fminf(((Interfaces::Globals->frametime * accel) * finalwishspeed) * surfacefriction, v60); 1732 | 1733 | if (move_player) 1734 | { 1735 | float boostdelta = move_player->GetHealthShotBoostExpirationTime() - Interfaces::Globals->curtime; 1736 | if (boostdelta >= 0.0f && fminf(boostdelta, 1.0f) > 0.0f) 1737 | { 1738 | //decrypts(0) 1739 | static ConVar* healthshot_healthboost_speed_multiplier = Interfaces::Cvar->FindVar(XorStr("healthshot_healthboost_speed_multiplier")); 1740 | //encrypts(0) 1741 | if (boostdelta >= 0.0f) 1742 | boostdelta = fminf(boostdelta, 1.0f); 1743 | v30 = v30 * (((healthshot_healthboost_speed_multiplier->GetFloat() - 1.0f) * boostdelta) + 1.0f); 1744 | } 1745 | } 1746 | 1747 | //float v24 = fminf(Interfaces::Globals->frametime * accel * backupfinalwishspeed * player->GetSurfaceFriction(), v46); 1748 | 1749 | mv->m_vecVelocity_ += wishdir * v30; 1750 | 1751 | // movss xmm0, dword ptr [ecx+0A2C0h] 1752 | if (m_pCSPlayer->GetGroundAccelLinearFracLastTime() != Interfaces::Globals->curtime) 1753 | { 1754 | m_pCSPlayer->SetGroundAccelLinearFracLastTime(Interfaces::Globals->curtime); 1755 | } 1756 | 1757 | if (mv->m_vecOldVelocity.x > -0.0099999998f && mv->m_vecOldVelocity.x < 0.0099999998f) 1758 | { 1759 | if (mv->m_vecOldVelocity.y > -0.0099999998f && mv->m_vecOldVelocity.y < 0.0099999998f) 1760 | { 1761 | if (mv->m_vecOldVelocity.z > -0.0099999998f && mv->m_vecOldVelocity.z < 0.0099999998f) 1762 | { 1763 | mv->m_vecOldVelocity = mv->m_vecVelocity_; 1764 | mv->somefloat = Interfaces::Globals->curtime; 1765 | return; 1766 | } 1767 | } 1768 | } 1769 | 1770 | // subss xmm0, dword ptr [edx+58h] 1771 | float v37 = Interfaces::Globals->curtime - mv->somefloat; 1772 | 1773 | if (v37 > 0.35f) 1774 | { 1775 | mv->m_vecOldVelocity = mv->m_vecVelocity_; 1776 | mv->somefloat = Interfaces::Globals->curtime; 1777 | return; 1778 | } 1779 | 1780 | Vector2D& velocity = mv->m_vecVelocity_.AsVector2D(); 1781 | Vector2D oldvelocity = mv->m_vecOldVelocity.AsVector2D(); 1782 | velocity.NormalizeInPlace(); 1783 | oldvelocity.NormalizeInPlace(); 1784 | 1785 | float velocitylengths = oldvelocity.y * velocity.y + oldvelocity.x * velocity.x; 1786 | 1787 | if (velocitylengths > 0.8f) 1788 | { 1789 | if (mv->m_vecVelocity_.Length2DSqr() <= mv->m_vecOldVelocity.Length2DSqr()) 1790 | return; 1791 | 1792 | mv->m_vecOldVelocity = mv->m_vecVelocity_; 1793 | mv->somefloat = Interfaces::Globals->curtime; 1794 | return; 1795 | } 1796 | 1797 | if (velocitylengths < -0.8f && mv->m_vecOldVelocity.Length2D() < 225.f && mv->m_vecOldVelocity.Length2D() > 115.f && mv->m_vecVelocity_.Length2D() > 115.f) 1798 | { 1799 | player->EyeVectors(&oldvelocity.AsVector(), 0, 0); //Basically just does AngleVectors unless in vehicle 1800 | float velocitylenghts2 = (oldvelocity.y * velocity.y) + (oldvelocity.x * velocity.x); 1801 | 1802 | if (velocitylenghts2 > -0.3f && velocitylenghts2 < 0.3f) 1803 | { 1804 | if (m_pCSPlayer->GetWeapon()) 1805 | { 1806 | mv->m_vecOldVelocity = mv->m_vecVelocity_; 1807 | mv->somefloat = Interfaces::Globals->curtime; 1808 | } 1809 | } 1810 | } 1811 | } 1812 | 1813 | //dangerzone correct 1814 | void CCSGameMovement::WalkMove() 1815 | { 1816 | if (m_pCSPlayer->IsAutoMounting()) 1817 | m_pCSPlayer->SetIsAutoMounting(0); 1818 | CGameMovement::WalkMove(); 1819 | } 1820 | 1821 | //dangerzone correct 1822 | void CGameMovement::WalkMove() 1823 | { 1824 | Vector forward, right, up; 1825 | AngleVectors(mv->m_vecViewAngles, &forward, &right, &up); 1826 | 1827 | auto ground = player->GetGroundEntity(); 1828 | 1829 | if (forward[2] != 0) 1830 | { 1831 | forward[2] = 0; 1832 | VectorNormalizeFast(forward); 1833 | } 1834 | 1835 | if (right[2] != 0) 1836 | { 1837 | right[2] = 0; 1838 | VectorNormalizeFast(right); 1839 | } 1840 | 1841 | float forwardmove = mv->m_flForwardMove; 1842 | float sidemove = mv->m_flSideMove; 1843 | 1844 | Vector wishVel = { 1845 | forward.x * forwardmove + right.x * sidemove, 1846 | forward.y * forwardmove + right.y * sidemove, 1847 | 0.f 1848 | }; 1849 | 1850 | Vector wishdir = wishVel; 1851 | float wishspeed = VectorNormalize(wishdir); 1852 | 1853 | if (wishspeed != 0.f && wishspeed > mv->_m_flMaxSpeed) 1854 | { 1855 | VectorScale(wishVel, mv->_m_flMaxSpeed / wishspeed, wishVel); 1856 | wishspeed = mv->_m_flMaxSpeed; 1857 | } 1858 | 1859 | mv->m_vecVelocity_.z = 0.f; 1860 | 1861 | Accelerate(wishdir, wishspeed, sv_accelerate.GetVar()->GetFloat()); 1862 | 1863 | mv->m_vecVelocity_.z = 0.f; 1864 | 1865 | float speed = mv->_m_flMaxSpeed; 1866 | 1867 | if (mv->m_vecVelocity_.LengthSqr() > speed * speed) 1868 | { 1869 | float v24 = speed / mv->m_vecVelocity_.Length(); 1870 | 1871 | mv->m_vecVelocity_ *= v24; 1872 | } 1873 | 1874 | mv->m_vecVelocity_ += player->GetBaseVelocity(); 1875 | 1876 | if (mv->m_vecVelocity_.Length() < 1.0f) 1877 | { 1878 | mv->m_vecVelocity_.x = 0.0f; 1879 | mv->m_vecVelocity_.y = 0.0f; 1880 | mv->m_vecVelocity_.z = 0.0f; 1881 | 1882 | mv->m_vecVelocity_ -= player->GetBaseVelocity(); 1883 | return; 1884 | } 1885 | 1886 | Vector temp = { 1887 | mv->m_vecVelocity_.x * Interfaces::Globals->frametime + mv->_m_vecAbsOrigin.x, 1888 | mv->m_vecVelocity_.y * Interfaces::Globals->frametime + mv->_m_vecAbsOrigin.y, 1889 | mv->_m_vecAbsOrigin.z 1890 | }; 1891 | 1892 | trace_t tr; 1893 | TracePlayerBBox(mv->_m_vecAbsOrigin, temp, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 1894 | 1895 | mv->m_outWishVel += wishdir * wishspeed; 1896 | 1897 | if (tr.fraction == 1.f) 1898 | { 1899 | mv->_m_vecAbsOrigin = tr.endpos; 1900 | } 1901 | else 1902 | { 1903 | // if ( (ground == -1 || (v38 = &dword_14A8286C[4 * ground], v38[1] != ground >> 16) || !*v38) 1904 | // && (v39 = *(gamemovement_1 + 4), !*(v39 + 0x25A)) 1905 | // || (v39 = *(gamemovement_1 + 4), *(v39 + 0x31FC) != 0.0) ) 1906 | if ((ground == nullptr && player->GetWaterLevel() == 0) || player->GetWaterJumpTime() != 0.f) 1907 | { 1908 | mv->m_vecVelocity_ -= player->GetBaseVelocity(); 1909 | return; 1910 | } 1911 | 1912 | StepMove(temp, tr); 1913 | } 1914 | 1915 | mv->m_vecVelocity_ -= player->GetBaseVelocity(); 1916 | 1917 | StayOnGround(); 1918 | } 1919 | 1920 | void CGameMovement::StayOnGround() 1921 | { 1922 | Vector start = { 1923 | mv->_m_vecAbsOrigin.x, 1924 | mv->_m_vecAbsOrigin.y, 1925 | mv->_m_vecAbsOrigin.z + 2.f 1926 | }; 1927 | 1928 | Vector end = { 1929 | mv->_m_vecAbsOrigin.x, 1930 | mv->_m_vecAbsOrigin.y, 1931 | mv->_m_vecAbsOrigin.z - player->GetStepSize() 1932 | }; 1933 | 1934 | trace_t tr; 1935 | TracePlayerBBox(mv->_m_vecAbsOrigin, start, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 1936 | 1937 | Vector temp = tr.endpos; 1938 | 1939 | TracePlayerBBox(temp, end, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 1940 | 1941 | if (tr.fraction > 0.f && tr.fraction < 1.f && !tr.startsolid && tr.plane.normal.z >= 0.7f) 1942 | { 1943 | float unk = fabs(mv->_m_vecAbsOrigin.z - tr.endpos.z); 1944 | 1945 | if (unk > 0.015625f) 1946 | mv->_m_vecAbsOrigin = tr.endpos; 1947 | } 1948 | } 1949 | 1950 | //dangerzone correct 1951 | void CGameMovement::FullWalkMove() 1952 | { 1953 | if (!CheckWater()) 1954 | StartGravity(); 1955 | 1956 | if (player->GetWaterJumpTime() != 0.f) 1957 | { 1958 | WaterJump(); 1959 | TryPlayerMove(); 1960 | CheckWater(); 1961 | return; 1962 | } 1963 | 1964 | if (player->GetWaterLevel() >= WL_Feet) 1965 | { 1966 | auto type = player->GetWaterType(); 1967 | if (type & CONTENTS_SLIME) //what 1968 | { 1969 | SlimeMove(); 1970 | CategorizePosition(); 1971 | if (player->GetGroundEntity() != nullptr) 1972 | mv->m_vecVelocity_.z = 0.f; 1973 | goto FinishedSlime; 1974 | } 1975 | } 1976 | 1977 | if (player->GetWaterLevel() < WL_Waist) 1978 | { 1979 | if (mv->m_nButtons & IN_JUMP) 1980 | CheckJumpButton(); 1981 | else 1982 | mv->m_nOldButtons &= ~IN_JUMP; 1983 | 1984 | if (player->GetGroundEntity() != nullptr) 1985 | { 1986 | mv->m_vecVelocity_.z = 0.f; 1987 | player->SetFallVelocity(0.f); 1988 | Friction(); 1989 | } 1990 | 1991 | CheckVelocity(); 1992 | 1993 | if (player->GetGroundEntity() != nullptr) 1994 | { 1995 | WalkMove(); 1996 | player->SetHasWalkMovedSinceLastJump(true); 1997 | //*(bool*)(player + 0x3208) = 1; // TODO: Some sort of boolean ? 1998 | } 1999 | else 2000 | AirMove(); 2001 | 2002 | CategorizePosition(); 2003 | CheckVelocity(); 2004 | 2005 | if (!CheckWater()) 2006 | FinishGravity(); 2007 | 2008 | if (player->GetGroundEntity() != nullptr) 2009 | mv->m_vecVelocity_.z = 0.f; 2010 | 2011 | CheckFalling(); 2012 | } 2013 | else 2014 | { 2015 | if (player->GetWaterLevel() == 2) 2016 | CheckWaterJump(); 2017 | 2018 | if (mv->m_vecVelocity_.z < 0.f) 2019 | { 2020 | if (player->GetWaterJumpTime() != 0.f) 2021 | player->SetWaterJumpTime(0.f); 2022 | } 2023 | 2024 | if (mv->m_nButtons & IN_JUMP) 2025 | CheckJumpButton(); 2026 | else 2027 | mv->m_nOldButtons &= ~IN_JUMP; 2028 | 2029 | WaterMove(); 2030 | 2031 | CategorizePosition(); 2032 | 2033 | if (player->GetGroundEntity() != nullptr) 2034 | mv->m_vecVelocity_.z = 0.f; 2035 | } 2036 | FinishedSlime: 2037 | if (m_nOldWaterLevel != 0.f && player->GetWaterLevel() != 0) 2038 | return; 2039 | else if (player->GetWaterLevel() == 0) 2040 | return; 2041 | 2042 | if (player->GetAbsVelocity()->Length() > 135.f) 2043 | { 2044 | //decrypts(0) 2045 | (*Interfaces::MoveHelperClient)->StartSound(mv->_m_vecAbsOrigin, XorStr("Player.Swim")); 2046 | //encrypts(0) 2047 | } 2048 | } 2049 | 2050 | void CGameMovement::OnJump(float stamina) 2051 | { 2052 | } 2053 | 2054 | //dangerzone correct, NOT CORRECT AFTER 4/30/19 2055 | void CCSGameMovement::OnJump(float stamina) 2056 | { 2057 | float newStamina = 0.f; 2058 | 2059 | float v6 = (sv_staminajumpcost.GetVar()->GetFloat() * stamina) + m_pCSPlayer->GetStamina(); 2060 | 2061 | if (v6 >= 0.f) 2062 | newStamina = fminf(sv_staminamax.GetVar()->GetFloat(), v6); 2063 | 2064 | if (m_pCSPlayer->GetStamina() != newStamina) 2065 | m_pCSPlayer->SetStamina(newStamina); 2066 | 2067 | m_pCSPlayer->OnJump(stamina); 2068 | } 2069 | 2070 | void CGameMovement::OnLand(float flFallVelocity) 2071 | { 2072 | } 2073 | 2074 | //dangerzone correct 2075 | void CCSGameMovement::OnLand(float stamina) 2076 | { 2077 | float newStamina = 0.f; 2078 | 2079 | float v6 = (sv_staminalandcost.GetVar()->GetFloat() * stamina) + m_pCSPlayer->GetStamina(); 2080 | 2081 | if (v6 >= 0.f) 2082 | newStamina = fminf(sv_staminamax.GetVar()->GetFloat(), v6); 2083 | 2084 | if (m_pCSPlayer->GetStamina() != newStamina) 2085 | m_pCSPlayer->SetStamina(newStamina); 2086 | 2087 | // C_CSPlayer::OnLand 2088 | m_pCSPlayer->OnLand(stamina); 2089 | //sub_103A9AC0(m_pCSPlayer, stamina); 2090 | } 2091 | 2092 | bool CGameMovement::CheckInterval(IntervalType_t type) 2093 | { 2094 | int tickInterval = GetCheckInterval(type); 2095 | 2096 | return (player->CurrentCommandNumber() + player->entindex()) % tickInterval == 0; 2097 | } 2098 | 2099 | int CGameMovement::GetCheckInterval(IntervalType_t type) 2100 | { 2101 | int tickInterval = 1; 2102 | 2103 | switch (type) 2104 | { 2105 | case IntervalType_t::GROUND: 2106 | { 2107 | tickInterval = static_cast(0.3f / Interfaces::Globals->interval_per_tick); 2108 | break; 2109 | } 2110 | 2111 | case IntervalType_t::STUCK: 2112 | { 2113 | if (player->GetStuckLast() != 0) 2114 | tickInterval = 1; 2115 | else if (Interfaces::Globals->maxClients == 1) 2116 | tickInterval = static_cast(0.2f / Interfaces::Globals->interval_per_tick); 2117 | else 2118 | tickInterval = static_cast(1.f / Interfaces::Globals->interval_per_tick); 2119 | break; 2120 | } 2121 | 2122 | case IntervalType_t::LADDER: 2123 | { 2124 | tickInterval = 2; 2125 | break; 2126 | } 2127 | 2128 | case IntervalType_t::LADDER_WEDGE: 2129 | { 2130 | tickInterval = static_cast(0.5f / Interfaces::Globals->interval_per_tick); 2131 | break; 2132 | } 2133 | 2134 | default: 2135 | break; 2136 | } 2137 | 2138 | return tickInterval; 2139 | } 2140 | 2141 | //dangerzone correct 2142 | void CGameMovement::StartGravity() 2143 | { 2144 | // (float)*(DWORD*)(player + 0xDC); 2145 | float grav = player->GetGravity(); 2146 | 2147 | if (grav == 0.0f) 2148 | grav = 1.0f; 2149 | 2150 | Vector basevel = player->GetBaseVelocity(); 2151 | 2152 | mv->m_vecVelocity_.z -= ((sv_gravity.GetVar()->GetFloat() * grav) * 0.5f) * Interfaces::Globals->frametime; 2153 | mv->m_vecVelocity_.z += basevel.z * Interfaces::Globals->frametime; 2154 | 2155 | basevel.y = basevel.x; 2156 | player->SetBaseVelocity(basevel); 2157 | 2158 | CheckVelocity(); 2159 | } 2160 | 2161 | void CGameMovement::FinishGravity() 2162 | { 2163 | if (player->GetWaterJumpTime() == 0.f) 2164 | { 2165 | float grav = player->GetGravity(); 2166 | if (grav == 0.0f) 2167 | grav = 1.0f; 2168 | 2169 | mv->m_vecVelocity_.z -= sv_gravity.GetVar()->GetFloat() * grav * Interfaces::Globals->frametime * 0.5f; 2170 | CheckVelocity(); 2171 | } 2172 | } 2173 | 2174 | void CGameMovement::AddGravity() 2175 | { 2176 | if (player->GetWaterJumpTime() == 0.f) 2177 | { 2178 | float grav = player->GetGravity(); 2179 | 2180 | if (grav == 0.f) 2181 | grav = 1.f; 2182 | 2183 | Vector basevel = player->GetBaseVelocity(); 2184 | 2185 | mv->m_vecVelocity_.z -= sv_gravity.GetVar()->GetFloat() * grav * Interfaces::Globals->frametime; 2186 | mv->m_vecVelocity_.z += basevel.z * Interfaces::Globals->frametime; 2187 | 2188 | basevel.z = 0.f; 2189 | player->SetBaseVelocity(basevel); 2190 | 2191 | CheckVelocity(); 2192 | } 2193 | } 2194 | 2195 | bool CGameMovement::CheckJumpButton() 2196 | { 2197 | if (player->GetDeadFlag()) 2198 | { 2199 | mv->m_nOldButtons |= IN_JUMP; 2200 | return false; 2201 | } 2202 | 2203 | if (player->GetWaterJumpTime() != 0.0f) 2204 | { 2205 | player->SetWaterJumpTime(player->GetWaterJumpTime() - Interfaces::Globals->frametime); 2206 | 2207 | if (player->GetWaterJumpTime() < 0.0f) 2208 | player->SetWaterJumpTime(0.0f); 2209 | 2210 | return false; 2211 | } 2212 | 2213 | if (player->GetWaterLevel() >= 2) 2214 | { 2215 | SetGroundEntity(nullptr); 2216 | 2217 | #if 1 2218 | if (player->GetWaterType() == CONTENTS_WATER) 2219 | mv->m_vecVelocity_.z = 100.0f; 2220 | else if (player->GetWaterType() == CONTENTS_SLIME) 2221 | mv->m_vecVelocity_.z = 80.0f; 2222 | #else 2223 | // v7 = 32 * (*(basePlayer_1 + 0xE8) & 1) | 0x10; 2224 | auto v7 = 32 * (player->m_nWaterType & 1) | 0x10; 2225 | 2226 | if (player->m_nWaterType & 2) 2227 | v7 = 32 * (player->m_nWaterType & 1); 2228 | 2229 | if (v7 == 32) 2230 | mv->m_vecVelocity_.z = 100.0f; 2231 | else 2232 | { 2233 | auto v8 = 32 * (player->m_nWaterType & 1) | 0x10; 2234 | 2235 | if (player->m_nWaterType & 2) 2236 | v8 = 32 * (player->m_nWaterType & 1); 2237 | 2238 | if (v8 == 16) 2239 | mv->m_vecVelocity_.z = 80.f; 2240 | } 2241 | #endif 2242 | 2243 | // if ( *(v9 + 0x3200) <= 0.0 ) 2244 | if (player->GetSwimSoundTime() <= 0.0f) 2245 | { 2246 | player->SetSwimSoundTime(1000.f); 2247 | //decrypts(0) 2248 | (*Interfaces::MoveHelperClient)->StartSound(mv->_m_vecAbsOrigin, XorStr("Player.Swim")); 2249 | //encrypts(0) 2250 | return false; 2251 | } 2252 | 2253 | return false; 2254 | } 2255 | 2256 | // unknown player + 0x3208 2257 | player->SetHasWalkMovedSinceLastJump(false); 2258 | 2259 | if (player->GetGroundEntity() == nullptr) 2260 | { 2261 | mv->m_nOldButtons |= IN_JUMP; 2262 | return false; 2263 | } 2264 | 2265 | // unknown player + 0x31B4 2266 | if (player->GetSlowMovement() || mv->m_nOldButtons & IN_JUMP || (player->GetDucking() && player->GetFlags() & FL_DUCKING) || player->GetDuckJumpTimeMsecs() > 0) 2267 | { 2268 | return false; 2269 | } 2270 | 2271 | SetGroundEntity(nullptr); 2272 | 2273 | // (*(**(gameMovement + 4) + 0x548))(*(gameMovement + 8) + 0xAC, *(*(gameMovement + 4) + 0x35A0), 0x3F800000, 1); 2274 | player->PlayStepSound(mv->_m_vecAbsOrigin, player->GetSurfaceData(), 1.f, true, false); 2275 | 2276 | // (*(*g_pMoveHelper + 40))(2) 2277 | (*Interfaces::MoveHelperClient)->PlayerSetAnimation(PLAYER_JUMP); 2278 | 2279 | float groundFactor; 2280 | if (player->GetSurfaceData()) 2281 | // v16 = *(v15 + 0x54); 2282 | groundFactor = player->GetSurfaceData()->game.jumpFactor; 2283 | else 2284 | groundFactor = 1.f; 2285 | 2286 | float v18; 2287 | if (player->GetDucking() || player->GetFlags() & FL_DUCKING) 2288 | v18 = groundFactor * 268.32816f; 2289 | else 2290 | v18 = mv->m_vecVelocity_.z + (groundFactor * 268.32816f); 2291 | 2292 | mv->m_vecVelocity_.z = v18; 2293 | 2294 | FinishGravity(); 2295 | 2296 | mv->m_outJumpVel.z += mv->m_vecVelocity_.z - v18; 2297 | mv->m_outStepHeight += 0.15f; 2298 | 2299 | // this is a nullsub(mv->m_outJumpVel) /shrug 2300 | // (*(*gameMovement + 0x7C))(gameMovement, *(*(gameMovement + 8) + 0x8C)); 2301 | OnJump(mv->m_outJumpVel.z); 2302 | 2303 | if (Interfaces::Globals->maxClients == 1) 2304 | { 2305 | // player + 0x3000 2306 | player->SetJumpTime(510.f); 2307 | player->SetInDuckJump(true); 2308 | } 2309 | 2310 | mv->m_nOldButtons |= IN_JUMP; 2311 | return true; 2312 | } 2313 | 2314 | //dangerzone correct 2315 | bool CCSGameMovement::CheckJumpButton() 2316 | { 2317 | if (m_pCSPlayer->GetDeadFlag() && !m_pCSPlayer->IsPlayerGhost()) 2318 | { 2319 | mv->m_nOldButtons |= IN_JUMP; 2320 | return false; 2321 | } 2322 | 2323 | if (m_pCSPlayer->GetWaterJumpTime() == 0.f) 2324 | { 2325 | // if ( (*(*m_pCSPlayer + 0x5CC))() && (*(*m_pCSPlayer + 0x5D0))() ) 2326 | //if (m_pCSPlayer->IsTaunting() && m_pCSPlayer->IsInThirdPersonTaunt()) //they removed this in the operation update on 11/18/2019 2327 | // return false; 2328 | 2329 | if (m_pCSPlayer->GetWaterLevel() < 2) 2330 | { 2331 | bool is_standing_on_player = false; 2332 | bool ground_ent_is_in_air = false; 2333 | 2334 | auto groundEnt = m_pCSPlayer->GetGroundEntity(); 2335 | 2336 | // if ( groundEnt && (*(*(groundEnt + 8) + 0x28))(groundEnt + 8) && (*(*groundEntCopy + 0x260))(groundEntCopy) ) 2337 | if (groundEnt != nullptr && groundEnt->entindex() != 0 && groundEnt->IsPlayer()) 2338 | { 2339 | is_standing_on_player = true; 2340 | auto groundGroundEnt = groundEnt->GetGroundEntity(); 2341 | ground_ent_is_in_air = !groundGroundEnt; 2342 | } 2343 | 2344 | //0x3208 2345 | player->SetHasWalkMovedSinceLastJump(false); 2346 | 2347 | if (m_pCSPlayer->GetGroundEntity() == nullptr) 2348 | { 2349 | mv->m_nOldButtons |= IN_JUMP; 2350 | return false; 2351 | } 2352 | 2353 | if (mv->m_nOldButtons & IN_JUMP && !sv_autobunnyhopping.GetVar()->GetBool()) 2354 | return false; 2355 | 2356 | if (!sv_enablebunnyhopping.GetVar()->GetBool() && !m_pCSPlayer->IsPlayerGhost()) 2357 | PreventBunnyJumping(); 2358 | 2359 | SetGroundEntity(nullptr); 2360 | 2361 | float flJumpFactor = 1.f; 2362 | 2363 | if (sqrtf(((mv->m_vecVelocity_.x * mv->m_vecVelocity_.x) + (mv->m_vecVelocity_.y * mv->m_vecVelocity_.y)) + (mv->m_vecVelocity_.z * mv->m_vecVelocity_.z)) > 126.0 || m_pCSPlayer->HasHeavyArmor() && !IsPlayingGuardian()) 2364 | { 2365 | // (*(*m_pCSPlayer + 0x548))(&mv->_m_vecAbsOrigin, player->m_surfacedata, 0x3F800000, 1); 2366 | m_pCSPlayer->PlayStepSound(mv->_m_vecAbsOrigin, player->GetSurfaceData(), 1.f, true, false); 2367 | } 2368 | 2369 | if (!m_pCSPlayer->IsPlayerGhost()) 2370 | { 2371 | m_pCSPlayer->PlayClientUnknownSound(mv->_m_vecAbsOrigin, player->GetSurfaceData()); 2372 | 2373 | // (*(*m_pCSPlayer + 0x5C8))(); 2374 | m_pCSPlayer->PlayClientJumpSound(); 2375 | } 2376 | 2377 | //if(!*(bool*)(m_pCSPlayer + 0x3951)) 2378 | if (!m_pCSPlayer->UsesServerSideJumpAnimation()) 2379 | { 2380 | // (*(**(v21 + 0x3870) + 24))(8, 0); 2381 | m_pCSPlayer->DoAnimationEvent((PlayerAnimEvent_t)8, 0); 2382 | } 2383 | 2384 | if (player->GetSurfaceData() != nullptr) 2385 | // movss xmm0, dword ptr [eax+54h] // game.jumpFactor + 4 2386 | flJumpFactor = player->GetSurfaceData()->game.jumpFactor; 2387 | 2388 | if (player == nullptr || player->IsBot() && !(mv->m_nButtons & IN_JUMP)) 2389 | { 2390 | // mov byte ptr [eax+0A300h], 1 2391 | //m_pCSPlayer->m_duckUntilOnGround = true; 2392 | m_pCSPlayer->SetDuckUntilOnGround(true); 2393 | CCSGameMovement::FinishDuck(); 2394 | } 2395 | 2396 | float startz = mv->m_vecVelocity_.z; 2397 | 2398 | if (ground_ent_is_in_air) 2399 | mv->m_vecVelocity_.z = 0.f; 2400 | else 2401 | { 2402 | if (m_pCSPlayer->GetDuckUntilOnGround() || m_pCSPlayer->GetDucking() || m_pCSPlayer->GetFlags() & FL_DUCKING || is_standing_on_player) 2403 | { 2404 | mv->m_vecVelocity_.z = sv_jump_impulse.GetVar()->GetFloat() * flJumpFactor; 2405 | } 2406 | else 2407 | { 2408 | mv->m_vecVelocity_.z += sv_jump_impulse.GetVar()->GetFloat() * flJumpFactor; 2409 | } 2410 | } 2411 | 2412 | float v26 = 0.0f; 2413 | 2414 | if (m_pCSPlayer->GetStamina() > 0.0f) 2415 | { 2416 | float v28 = 1.0f - m_pCSPlayer->GetStamina() * 0.01f; 2417 | if (v28 >= 0.0f) 2418 | v26 = fmin(v28, 1.0f); 2419 | 2420 | mv->m_vecVelocity_.z *= v26; 2421 | } 2422 | 2423 | FinishGravity(); 2424 | 2425 | mv->m_outWishVel.z += (mv->m_vecVelocity_.z - startz); 2426 | mv->m_outStepHeight += 0.1f; 2427 | OnJump(mv->m_outWishVel.z); 2428 | mv->m_nOldButtons |= IN_JUMP; 2429 | return true; 2430 | } 2431 | else 2432 | { 2433 | SetGroundEntity(nullptr); 2434 | 2435 | #if 1 2436 | if (player->GetWaterType() == CONTENTS_WATER) // We move up a certain amount 2437 | mv->m_vecVelocity_[2] = 100; 2438 | else if (player->GetWaterType() == CONTENTS_SLIME) 2439 | mv->m_vecVelocity_[2] = 80; 2440 | #else 2441 | int v11 = 32 * (m_pCSPlayer->m_nWaterType & 1) | 0x10; 2442 | 2443 | if (!(m_pCSPlayer->m_nWaterType & 2)) 2444 | v11 = 32 * (m_pCSPlayer->m_nWaterType & 1); 2445 | 2446 | if (v11 == 32) 2447 | mv->m_vecVelocity_.z = 100.f; 2448 | else 2449 | { 2450 | int v12 = 32 * (m_pCSPlayer->m_nWaterType & 1) | 0x10; 2451 | 2452 | if (!(m_pCSPlayer->m_nWaterType & 2)) 2453 | v12 = 32 * (m_pCSPlayer->m_nWaterType & 1); 2454 | 2455 | if (v12 == 16) 2456 | mv->m_vecVelocity_.z = 80.f; 2457 | } 2458 | #endif 2459 | 2460 | if (m_pCSPlayer->GetSwimSoundTime() > 0.f) 2461 | return false; 2462 | 2463 | m_pCSPlayer->SetSwimSoundTime(1000.f); 2464 | //decrypts(0) 2465 | (*Interfaces::MoveHelperClient)->StartSound(mv->_m_vecAbsOrigin, XorStr("Player.Swim")); 2466 | //encrypts(0) 2467 | return false; 2468 | } 2469 | } 2470 | else 2471 | { 2472 | m_pCSPlayer->SetWaterJumpTime(m_pCSPlayer->GetWaterJumpTime() - Interfaces::Globals->frametime); 2473 | 2474 | if (m_pCSPlayer->GetWaterJumpTime() < 0.f) 2475 | m_pCSPlayer->SetWaterJumpTime(0.f); 2476 | 2477 | return false; 2478 | } 2479 | 2480 | return false; 2481 | } 2482 | 2483 | void CGameMovement::FullTossMove() 2484 | { 2485 | CheckWater(); 2486 | 2487 | if (mv->m_flForwardMove != 0.0f || mv->m_flSideMove != 0.0f || mv->m_flUpMove != 0.0f) 2488 | { 2489 | Vector forward, right, up; 2490 | AngleVectors(mv->m_vecViewAngles, &forward, &right, &up); 2491 | 2492 | float forwardmove = mv->m_flForwardMove; 2493 | float sidemove = mv->m_flSideMove; 2494 | 2495 | VectorNormalizeFast(forward); 2496 | VectorNormalizeFast(right); 2497 | 2498 | Vector wishVel = { 2499 | forward.x * forwardmove + right.x * sidemove, 2500 | forward.y * forwardmove + right.y * sidemove, 2501 | forward.z * forwardmove + right.z * sidemove 2502 | }; 2503 | 2504 | wishVel.z += mv->m_flUpMove; 2505 | 2506 | Vector wishdir = wishVel; 2507 | float wishspeed = VectorNormalize(wishdir); 2508 | 2509 | if (wishspeed > mv->_m_flMaxSpeed) 2510 | { 2511 | VectorScale(wishVel, mv->_m_flMaxSpeed / wishspeed, wishVel); 2512 | wishspeed = mv->_m_flMaxSpeed; 2513 | } 2514 | 2515 | Accelerate(wishdir, wishspeed, sv_accelerate.GetVar()->GetFloat()); 2516 | } 2517 | 2518 | if (mv->m_vecVelocity_.z > 0.f) 2519 | SetGroundEntity(nullptr); 2520 | 2521 | if (player->GetGroundEntity() != nullptr || player->GetBaseVelocity() != Vector(0, 0, 0) || mv->m_vecVelocity_ != Vector(0, 0, 0)) 2522 | { 2523 | CheckVelocity(); 2524 | 2525 | if (player->GetMoveType() == MOVETYPE_FLYGRAVITY) 2526 | AddGravity(); 2527 | 2528 | mv->m_vecVelocity_ += player->GetBaseVelocity(); 2529 | 2530 | CheckVelocity(); 2531 | 2532 | Vector temp; 2533 | VectorScale(mv->m_vecVelocity_, Interfaces::Globals->frametime, temp); 2534 | 2535 | mv->m_vecVelocity_ -= player->GetBaseVelocity(); 2536 | 2537 | Vector end; 2538 | trace_t tr; 2539 | TracePlayerBBox(mv->_m_vecAbsOrigin, end, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 2540 | 2541 | if (tr.fraction < 1.f && !tr.allsolid) 2542 | (*Interfaces::MoveHelperClient)->AddToTouched(tr, mv->m_vecVelocity_); 2543 | 2544 | if (tr.allsolid) 2545 | { 2546 | SetGroundEntity(&tr); 2547 | 2548 | mv->m_vecVelocity_.x = 0.f; 2549 | mv->m_vecVelocity_.y = 0.f; 2550 | mv->m_vecVelocity_.z = 0.f; 2551 | } 2552 | else 2553 | { 2554 | if (tr.fraction != 1.f) 2555 | { 2556 | PerformFlyCollisionResolution(tr, temp); 2557 | CheckWater(); 2558 | } 2559 | } 2560 | } 2561 | } 2562 | 2563 | void CGameMovement::FullLadderMove() 2564 | { 2565 | CheckWater(); 2566 | 2567 | if (mv->m_nButtons & IN_JUMP) 2568 | CheckJumpButton(); 2569 | else 2570 | mv->m_nOldButtons &= ~IN_JUMP; 2571 | 2572 | mv->m_vecVelocity_ += player->GetBaseVelocity(); 2573 | 2574 | TryPlayerMove(); 2575 | 2576 | mv->m_vecVelocity_ -= player->GetBaseVelocity(); 2577 | } 2578 | 2579 | int CGameMovement::TryPlayerMove(Vector* firstDest /*= nullptr*/, trace_t* firstTrace /*= nullptr */) 2580 | { 2581 | Vector originalVelocity = mv->m_vecVelocity_; 2582 | Vector primalVelocity = mv->m_vecVelocity_; 2583 | Vector unknownVelocity = mv->m_vecVelocity_; 2584 | trace_t pm; 2585 | 2586 | float allFraction = 0.0f; 2587 | float fVol = 1.0f; 2588 | 2589 | int bumpcount = 0; 2590 | int blocked = 0; 2591 | int numplanes = 0; 2592 | int oldnumplanes = 0; 2593 | int numbumps = 4; 2594 | 2595 | Vector planes[5]; 2596 | 2597 | float frametime = Interfaces::Globals->frametime; 2598 | 2599 | while (1) 2600 | { 2601 | if (mv->m_vecVelocity_.Length() == 0.0f) 2602 | break; 2603 | 2604 | // Assume we can move all the way from the current origin to the 2605 | // end point 2606 | Vector end = mv->_m_vecAbsOrigin + (mv->m_vecVelocity_ * frametime); 2607 | 2608 | // See if we can make it from origin to end point. 2609 | 2610 | // If their velocity Z is 0, then we can avoid an extra trace here during WalkMove. 2611 | if (firstDest && (end == *firstDest)) 2612 | { 2613 | // looks recursive, we call this with the firstTrace tho 2614 | //sub_1017C3E0(firstTrace); 2615 | pm = *firstTrace; 2616 | } 2617 | else 2618 | { 2619 | TracePlayerBBox(mv->_m_vecAbsOrigin, end, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, pm); 2620 | fVol = 1.f; 2621 | numplanes = oldnumplanes; 2622 | } 2623 | 2624 | if (pm.fraction > 0.0f && pm.fraction < 0.0001f) //0.000099999997f 2625 | { 2626 | pm.fraction = 0.0f; 2627 | } 2628 | 2629 | allFraction += pm.fraction; 2630 | 2631 | // If we started in a solid object, or we were in solid space 2632 | // the whole way, zero out our velocity and return that we 2633 | // are blocked by floor and wall. 2634 | if (pm.allsolid) 2635 | { 2636 | mv->m_vecVelocity_.Zero(); 2637 | return 4; 2638 | } 2639 | 2640 | // If we moved some portion of the total distance, then 2641 | // copy the end position into the pmove.origin and 2642 | // zero the plane counter. 2643 | if (pm.fraction > 0.0f) 2644 | { 2645 | if (pm.fraction == 1.0f) 2646 | { 2647 | // There's a precision issue with terrain tracing that can cause a swept box to successfully trace 2648 | // when the end position is stuck in the triangle. Re-run the test with an uswept box to catch that 2649 | // case until the bug is fixed. 2650 | // If we detect getting stuck, don't allow the movement 2651 | trace_t stuck; 2652 | TracePlayerBBox(pm.endpos, pm.endpos, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, stuck); 2653 | fVol = 1.f; 2654 | 2655 | if (stuck.allsolid || stuck.fraction != 1.f) 2656 | { 2657 | mv->m_vecVelocity_.Zero(); 2658 | primalVelocity.x = unknownVelocity.x; 2659 | primalVelocity.y = unknownVelocity.y; 2660 | break; 2661 | } 2662 | } 2663 | 2664 | // actually covered some distance 2665 | numplanes = 0; 2666 | mv->_m_vecAbsOrigin = pm.endpos; 2667 | originalVelocity = mv->m_vecVelocity_; 2668 | } 2669 | 2670 | // If we covered the entire distance, we are done 2671 | // and can return. 2672 | if (pm.fraction == 1.f) 2673 | { 2674 | primalVelocity.x = unknownVelocity.x; 2675 | primalVelocity.y = unknownVelocity.y; 2676 | break; 2677 | } 2678 | 2679 | // Save entity that blocked us (since fraction was < 1.0) 2680 | // for contact 2681 | // Add it if it's not already in the list!!! 2682 | (*Interfaces::MoveHelperClient)->AddToTouched(pm, mv->m_vecVelocity_); 2683 | 2684 | // If the plane we hit has a high z component in the normal, then 2685 | // it's probably a floor 2686 | if (pm.plane.normal.z > 0.7f) 2687 | { 2688 | blocked |= 1; // floor 2689 | } 2690 | 2691 | // If the plane has a zero z component in the normal, then it's a 2692 | // step or wall 2693 | if (fabsf(pm.plane.normal.z) < 0.0001f) //0.000099999997f 2694 | { 2695 | pm.plane.normal.z = 0.0f; 2696 | blocked |= 2; // step / wall 2697 | } 2698 | 2699 | // Reduce amount of m_flFrameTime left by total time left * fraction 2700 | // that we covered. 2701 | frametime -= (pm.fraction * frametime); 2702 | 2703 | // Did we run out of planes to clip against? 2704 | if (numplanes >= 5) 2705 | { 2706 | // this shouldn't really happen 2707 | // Stop our movement if so. 2708 | fVol = 1.f; 2709 | 2710 | mv->m_vecVelocity_.Zero(); 2711 | primalVelocity.x = unknownVelocity.x; 2712 | primalVelocity.y = unknownVelocity.y; 2713 | 2714 | break; 2715 | } 2716 | 2717 | // Set up next clipping plane 2718 | planes[numplanes++] = pm.plane.normal; 2719 | oldnumplanes = numplanes; 2720 | 2721 | Vector newVelocity; 2722 | // modify original_velocity so it parallels all of the clip planes 2723 | // 2724 | 2725 | // reflect player velocity 2726 | // Only give this a try for first impact plane because you can get yourself stuck in an acute corner by jumping in place 2727 | // and pressing forward and nobody was really using this bounce/reflection feature anyway... 2728 | 2729 | if (numplanes == 1) 2730 | { 2731 | if (player->GetMoveType() == MOVETYPE_WALK && player->GetGroundEntity() == nullptr) 2732 | { 2733 | if (planes[0].z <= 0.7f) 2734 | { 2735 | ClipVelocity(originalVelocity, planes[0], newVelocity, (1.f - player->GetSurfaceFriction() * sv_bounce.GetVar()->GetFloat()) + 1.f); 2736 | } 2737 | else 2738 | { 2739 | // floor or slope 2740 | ClipVelocity(originalVelocity, planes[0], newVelocity, 1.f); 2741 | } 2742 | 2743 | primalVelocity.x = unknownVelocity.x; 2744 | primalVelocity.y = unknownVelocity.y; 2745 | mv->m_vecVelocity_ = newVelocity; 2746 | originalVelocity = newVelocity; 2747 | 2748 | fVol = 1.0f; 2749 | 2750 | if (++bumpcount >= numbumps) 2751 | break; 2752 | 2753 | continue; 2754 | } 2755 | } 2756 | 2757 | int i, j; 2758 | for (i = 0; i < numplanes; i++) 2759 | { 2760 | ClipVelocity(originalVelocity, planes[i], mv->m_vecVelocity_, 1); 2761 | 2762 | for (j = 0; j < numplanes; j++) 2763 | { 2764 | if (j != i) 2765 | { 2766 | // Are we now moving against this plane? 2767 | if (mv->m_vecVelocity_.Dot(planes[j]) < 0) 2768 | break; // not ok 2769 | } 2770 | } 2771 | if (j == numplanes) // Didn't have to clip, so we're ok 2772 | break; 2773 | } 2774 | 2775 | // Did we go all the way through plane set 2776 | if (i == numplanes) 2777 | { 2778 | // go along the crease 2779 | if (numplanes != 2) 2780 | { 2781 | fVol = 1.f; 2782 | 2783 | mv->m_vecVelocity_.x = 0.f; 2784 | mv->m_vecVelocity_.y = 0.f; 2785 | mv->m_vecVelocity_.z = 0.f; 2786 | 2787 | primalVelocity.x = unknownVelocity.x; 2788 | primalVelocity.y = unknownVelocity.y; 2789 | 2790 | break; 2791 | } 2792 | 2793 | Vector dir; 2794 | CrossProduct(planes[0], planes[1], dir); 2795 | dir.NormalizeInPlace(); 2796 | 2797 | float d = dir.Dot(mv->m_vecVelocity_); 2798 | VectorScale(dir, d, mv->m_vecVelocity_); 2799 | } 2800 | else 2801 | { 2802 | // go along this plane 2803 | // pmove.velocity is set in clipping call, no need to set again. 2804 | } 2805 | 2806 | primalVelocity.x = unknownVelocity.x; 2807 | primalVelocity.y = unknownVelocity.y; 2808 | 2809 | // 2810 | // if original velocity is against the original velocity, stop dead 2811 | // to avoid tiny occilations in sloping corners 2812 | // 2813 | float d = mv->m_vecVelocity_.Dot(unknownVelocity); 2814 | if (d <= 0.0f) 2815 | { 2816 | fVol = 1.0f; 2817 | mv->m_vecVelocity_.Zero(); 2818 | break; 2819 | } 2820 | 2821 | fVol = 1.0f; 2822 | if (++bumpcount >= numbumps) 2823 | break; 2824 | } 2825 | 2826 | if (allFraction == 0.f) 2827 | { 2828 | mv->m_vecVelocity_.Zero(); 2829 | } 2830 | 2831 | auto fLateralStoppingAmount = primalVelocity.Length2D() - mv->m_vecVelocity_.Length2D(); 2832 | 2833 | if (fLateralStoppingAmount <= 1160.f) 2834 | { 2835 | if (fLateralStoppingAmount <= 580.f) 2836 | return blocked; 2837 | 2838 | fVol = 0.85f; 2839 | } 2840 | 2841 | PlayerRoughLandingEffects(fVol); 2842 | return blocked; 2843 | } 2844 | 2845 | bool CGameMovement::LadderMove() 2846 | { 2847 | if (player->GetMoveType() == MOVETYPE_NOCLIP || !GameHasLadders()) 2848 | return false; 2849 | 2850 | Vector wishdir; 2851 | 2852 | if (player->GetMoveType() == MOVETYPE_LADDER) 2853 | { 2854 | // movss xmm2, dword ptr [eax+3214h]; 2855 | wishdir = -player->GetVecLadderNormal(); 2856 | } 2857 | else 2858 | { 2859 | float forwardmove = mv->m_flForwardMove; 2860 | float sidemove = mv->m_flSideMove; 2861 | 2862 | if (forwardmove == 0.f && sidemove == 0.0f) 2863 | return false; 2864 | 2865 | wishdir = (m_vecRight * sidemove) + (m_vecForward * forwardmove); 2866 | VectorNormalizeFast(wishdir); 2867 | } 2868 | 2869 | Vector end; 2870 | trace_t tr; 2871 | 2872 | VectorMA(mv->_m_vecAbsOrigin, LadderDistance(), wishdir, end); 2873 | TracePlayerBBox(mv->_m_vecAbsOrigin, end, LadderMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 2874 | 2875 | if (tr.fraction == 1.f || !OnLadder(tr)) 2876 | { 2877 | //0x3208 2878 | if (player->HasWalkMovedSinceLastJump()) 2879 | { 2880 | if (player->GetMoveType() != MOVETYPE_LADDER) 2881 | { 2882 | if (player->GetGroundEntity() == nullptr) 2883 | { 2884 | if (mv->m_vecVelocity_.z <= 0.f && mv->m_vecVelocity_.z > -50.f 2885 | && fabs(mv->m_vecVelocity_.x) > 0.f 2886 | && fabs(mv->m_vecVelocity_.y) > 0.f) 2887 | { 2888 | Vector start = mv->_m_vecAbsOrigin; 2889 | start.z -= 6.0f; 2890 | 2891 | Vector normalized = mv->m_vecVelocity_; 2892 | VectorNormalizeFast(normalized); 2893 | normalized *= 24.f; 2894 | 2895 | Vector end = mv->_m_vecAbsOrigin - normalized; 2896 | TracePlayerBBox(start, end, LadderMask() & 0xFFFEFFFF, COLLISION_GROUP_PLAYER_MOVEMENT, tr); 2897 | 2898 | if (tr.fraction == 1.f && OnLadder(tr) && tr.plane.normal.z != 1.f) 2899 | { 2900 | player->SetMoveType(MOVETYPE_LADDER); 2901 | player->SetMoveCollide(MOVECOLLIDE_DEFAULT); 2902 | 2903 | Vector ladderNormal = player->GetVecLadderNormal(); 2904 | 2905 | if (tr.plane.normal != ladderNormal) 2906 | { 2907 | player->SetVecLadderNormal(tr.plane.normal); 2908 | } 2909 | 2910 | mv->m_vecVelocity_.x = 0.f; 2911 | mv->m_vecVelocity_.y = 0.f; 2912 | mv->m_vecVelocity_.z = 0.f; 2913 | 2914 | TracePlayerBBox(start, end, LadderMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 2915 | 2916 | mv->_m_vecAbsOrigin = tr.endpos; 2917 | 2918 | if (player->GetMoveType() != MOVETYPE_LADDER) 2919 | // *(float*)(player + 0x3204) 2920 | player->SetTimeNotOnLadder(Interfaces::Globals->curtime + 0.2f); 2921 | 2922 | player->SetMoveType(MOVETYPE_LADDER); 2923 | player->SetMoveCollide(MOVECOLLIDE_DEFAULT); 2924 | 2925 | if (tr.plane.normal != player->GetVecLadderNormal()) 2926 | { 2927 | player->SetVecLadderNormal(tr.plane.normal); 2928 | } 2929 | 2930 | Vector floor = mv->_m_vecAbsOrigin; 2931 | floor.z += (GetPlayerMins().z - 1.f); 2932 | 2933 | bool onFloor = Interfaces::EngineTrace->GetPointContents(floor) == CONTENTS_SOLID || player->GetGroundEntity() != nullptr; 2934 | 2935 | player->SetGravity(0.f); 2936 | 2937 | float climbSpeed = ClimbSpeed(); 2938 | 2939 | float forwardspeed = 0.f; 2940 | float rightspeed = 0.f; 2941 | 2942 | if (mv->m_nButtons & IN_BACK) 2943 | forwardspeed += -climbSpeed; 2944 | if (mv->m_nButtons & IN_FORWARD) 2945 | forwardspeed += climbSpeed; 2946 | if (mv->m_nButtons & IN_MOVELEFT) 2947 | rightspeed += -climbSpeed; 2948 | if (mv->m_nButtons & IN_MOVERIGHT) 2949 | rightspeed += climbSpeed; 2950 | 2951 | if (mv->m_nButtons & IN_JUMP) 2952 | { 2953 | if (Interfaces::Globals->curtime >= player->GetTimeNotOnLadder()) 2954 | { 2955 | player->SetMoveType(MOVETYPE_WALK); 2956 | player->SetMoveCollide(MOVECOLLIDE_DEFAULT); 2957 | 2958 | mv->m_vecVelocity_ = tr.plane.normal * 270.f; 2959 | return true; 2960 | } 2961 | } 2962 | else 2963 | { 2964 | if (forwardspeed == 0.f && rightspeed == 0.f) 2965 | { 2966 | mv->m_vecVelocity_.x = 0.f; 2967 | mv->m_vecVelocity_.y = 0.f; 2968 | mv->m_vecVelocity_.z = 0.f; 2969 | return true; 2970 | } 2971 | 2972 | // Fuck trying to do actual math functions, it's psuedocode with comments if you're curious 2973 | float v56 = tr.plane.normal.x; 2974 | float v57 = m_vecForward.z * forwardspeed; 2975 | float v58 = (rightspeed * m_vecRight.x) + (m_vecForward.x * forwardspeed); 2976 | float v59 = m_vecForward.y * forwardspeed; 2977 | float v60 = tr.plane.normal.z; 2978 | float v61 = v58; 2979 | float v62 = (m_vecRight.y * rightspeed) + v59; 2980 | float v63 = (m_vecRight.z * rightspeed) + v57; 2981 | float v64 = (tr.plane.normal.z * 0.f) - tr.plane.normal.y; 2982 | float v65 = tr.plane.normal.y; 2983 | float v66 = tr.plane.normal.x - (tr.plane.normal.z * 0.f); 2984 | float v67 = (tr.plane.normal.y * 0.f) - (tr.plane.normal.x * 0.f); 2985 | float v68 = 1.f / sqrtf((v66 * v66) + (v64 * v64) + (v67 * v67)) + 0.00000011920929f; 2986 | float v93 = v66 * v68; // normalized something 2987 | float v100 = v67 * v68; // normalized something 2988 | float v106 = v64 * v68; // normalized something 2989 | float normal = ((v65 * v62) + (v56 * v61) + (v60 * v63)); // dot product 2990 | float v102 = v63 - (v60 * normal); 2991 | float v104 = v61 - (v56 * normal); 2992 | float v97 = v62 - (v65 * normal); 2993 | float v111 = (v65 * (v67 * v68)) - (v60 * (v66 * v68)); 2994 | float v112 = (v60 * (v64 * v68)) - (v56 * (v67 * v68)); 2995 | float v89 = (v56 * (v66 * v68)) - (v65 * (v64 * v68)); 2996 | float v103 = ((v97 * v112) + (v104 * v111)) + (v102 * v89); 2997 | float v110 = ((v97 * (v66 * v68)) + (v104 * (v64 * v68))) + (v102 * (v67 * v68)); 2998 | float v69 = ((v97 * (v66 * v68)) + (v104 * (v64 * v68))) + (v102 * (v67 * v68)); 2999 | float v70 = ((v64 * v68) * v69) + (v56 * normal); 3000 | float v71 = ((v66 * v68) * v69) + (v65 * normal); 3001 | float v72 = (v100 * v69) + (v60 * normal); 3002 | float v73 = 1.f / (sqrtf(((v71 * v71) + (v70 * v70)) + (v72 * v72)) + 0.00000011920929f); 3003 | float v74 = v71 * v73; // normalized something 3004 | float v75 = v72 * v73; // normalized something 3005 | float v76 = v56 * (v70 * v73); // normalized something 3006 | float v77 = ((v65 * v74) + v76) + (tr.plane.normal.z * v75); 3007 | float v98 = ((v65 * v74) + v76) + (tr.plane.normal.z * v75); 3008 | 3009 | float v80, v78, v79, v81, v82; 3010 | if (sv_ladder_angle.GetVar()->GetFloat() <= v77) 3011 | { 3012 | v80 = v111; 3013 | v78 = v112; 3014 | v79 = v89; 3015 | v81 = v97; 3016 | v82 = v102; 3017 | } 3018 | else 3019 | { 3020 | v78 = v112; 3021 | v79 = v89; 3022 | v80 = v111; 3023 | v81 = (v112 * v103) + ((v93 * sv_ladder_dampen.GetVar()->GetFloat()) * v110); 3024 | v82 = (v89 * v103) + ((v100 * sv_ladder_dampen.GetVar()->GetFloat()) * v110); 3025 | v104 = (v111 * v103) + ((v106 * sv_ladder_dampen.GetVar()->GetFloat()) * v110); 3026 | } 3027 | 3028 | mv->m_vecVelocity_.x = (v80 * -normal) + v104; 3029 | mv->m_vecVelocity_.x = (v78 * -normal) + v81; 3030 | mv->m_vecVelocity_.z = (v79 * -normal) + v82; 3031 | 3032 | if (sv_ladder_scale_speed.GetVar()->GetFloat() > 0.f) 3033 | { 3034 | mv->m_vecVelocity_ *= sv_ladder_scale_speed.GetVar()->GetFloat(); 3035 | } 3036 | 3037 | if (onFloor && normal > 0.f) 3038 | { 3039 | mv->m_vecVelocity_ += (tr.plane.normal * 200.f); 3040 | } 3041 | } 3042 | } 3043 | } 3044 | } 3045 | } 3046 | } 3047 | } 3048 | 3049 | return true; 3050 | } 3051 | 3052 | //dangerzone correct 3053 | bool CCSGameMovement::LadderMove() 3054 | { 3055 | bool onLadder = CGameMovement::LadderMove(); 3056 | 3057 | if (onLadder) 3058 | { 3059 | if (m_pCSPlayer != nullptr) 3060 | // sub_103A9C60(v3, &v1->mv->_m_vecAbsOrigin.x, &v3->m_vecLadderNormal.x); 3061 | m_pCSPlayer->SurpressLadderChecks(&mv->_m_vecAbsOrigin, &m_pCSPlayer->GetVecLadderNormal()); 3062 | } 3063 | 3064 | return onLadder; 3065 | } 3066 | 3067 | bool CGameMovement::OnLadder(trace_t& pm) 3068 | { 3069 | if (!(pm.contents & CONTENTS_LADDER)) 3070 | { 3071 | IPhysicsSurfaceProps* props = (*Interfaces::MoveHelperClient)->GetSurfaceProps(); 3072 | 3073 | if (props == nullptr) 3074 | return false; 3075 | 3076 | surfacedata_t* surfaceData = props->GetSurfaceData(pm.surface.surfaceProps); 3077 | if (!surfaceData || !surfaceData->game.climbable) 3078 | return false; 3079 | } 3080 | 3081 | return true; 3082 | } 3083 | 3084 | //dangerzone correct 3085 | bool CCSGameMovement::OnLadder(trace_t& trace) 3086 | { 3087 | if (trace.plane.normal.z != 1.f) 3088 | { 3089 | if (trace.contents & CONTENTS_LADDER) 3090 | { 3091 | auto physProps = (*Interfaces::MoveHelperClient)->GetSurfaceProps(); 3092 | 3093 | if (physProps != nullptr) 3094 | { 3095 | auto surfaceData = physProps->GetSurfaceData(trace.surface.surfaceProps); 3096 | 3097 | if (surfaceData != nullptr) 3098 | { 3099 | if (surfaceData->game.climbable) 3100 | return true; 3101 | } 3102 | } 3103 | } 3104 | } 3105 | 3106 | return false; 3107 | } 3108 | 3109 | float CGameMovement::LadderDistance() 3110 | { 3111 | return 2.f; 3112 | } 3113 | 3114 | float CCSGameMovement::LadderDistance() 3115 | { 3116 | if (player->GetMoveType() == MOVETYPE_LADDER) 3117 | return 10.f; 3118 | 3119 | return 2.f; 3120 | } 3121 | 3122 | unsigned int CGameMovement::LadderMask() 3123 | { 3124 | return 0x201400B; 3125 | } 3126 | 3127 | float CGameMovement::ClimbSpeed() 3128 | { 3129 | return 200.f; 3130 | } 3131 | 3132 | float CCSGameMovement::ClimbSpeed() const 3133 | { 3134 | if (mv->m_nButtons & (IN_SPEED | IN_DUCK)) 3135 | return 68.f; 3136 | 3137 | return 200.f; 3138 | } 3139 | 3140 | float CGameMovement::LadderLateralMultiplier() 3141 | { 3142 | return 1.f; 3143 | } 3144 | 3145 | const int nanmask = 255 << 23; 3146 | #define IS_NAN(x) (((*(int*)&x) & nanmask) == nanmask) 3147 | 3148 | void CGameMovement::CheckVelocity(void) 3149 | { 3150 | int i; 3151 | 3152 | // 3153 | // bound velocity 3154 | // 3155 | 3156 | Vector org = mv->GetAbsOrigin(); 3157 | 3158 | for (i = 0; i < 3; i++) 3159 | { 3160 | // See if it's bogus. 3161 | if (IS_NAN(mv->m_vecVelocity_[i])) 3162 | { 3163 | //DevMsg(1, "PM Got a NaN velocity %s\n", DescribeAxis(i)); 3164 | mv->m_vecVelocity_[i] = 0; 3165 | } 3166 | 3167 | if (IS_NAN(org[i])) 3168 | { 3169 | //printf(1, "PM Got a NaN origin on %s\n", DescribeAxis(i)); 3170 | org[i] = 0; 3171 | mv->SetAbsOrigin(org); 3172 | } 3173 | 3174 | // Bound it. 3175 | if (mv->m_vecVelocity_[i] > sv_maxvelocity.GetVar()->GetFloat()) 3176 | { 3177 | //DevMsg(1, "PM Got a velocity too high on %s\n", DescribeAxis(i)); 3178 | mv->m_vecVelocity_[i] = sv_maxvelocity.GetVar()->GetFloat(); 3179 | } 3180 | else if (mv->m_vecVelocity_[i] < -sv_maxvelocity.GetVar()->GetFloat()) 3181 | { 3182 | //DevMsg(1, "PM Got a velocity too low on %s\n", DescribeAxis(i)); 3183 | mv->m_vecVelocity_[i] = -sv_maxvelocity.GetVar()->GetFloat(); 3184 | } 3185 | } 3186 | } 3187 | 3188 | float CCSGameMovement::LadderLateralMultiplier() const 3189 | { 3190 | if (mv->m_nButtons & IN_DUCK) 3191 | return 1.f; 3192 | 3193 | return 0.5f; 3194 | } 3195 | 3196 | void CGameMovement::ResetGetWaterContentsForPointCache() 3197 | { 3198 | for (int slot = 0; slot < MAX_PC_CACHE_SLOTS; ++slot) 3199 | { 3200 | for (int i = 0; i < MAX_PLAYERS; ++i) 3201 | { 3202 | m_CachedGetPointContents[i][slot] = -9999; 3203 | } 3204 | } 3205 | } 3206 | 3207 | int CGameMovement::GetWaterContentsForPointCached(const Vector& point, int slot) 3208 | { 3209 | int idx = player->entindex() - 1; 3210 | 3211 | if (m_CachedGetPointContents[idx][slot] == -9999 || point.DistToSqr(m_CachedGetPointContentsPoint[idx][slot]) > 1) 3212 | { 3213 | m_CachedGetPointContents[idx][slot] = Interfaces::EngineTrace->GetPointContents(point, MASK_WATER); 3214 | m_CachedGetPointContentsPoint[idx][slot] = point; 3215 | } 3216 | 3217 | return m_CachedGetPointContents[idx][slot]; 3218 | } 3219 | 3220 | void CGameMovement::PushEntity(Vector& push, trace_t* pTrace) 3221 | { 3222 | Vector end; 3223 | 3224 | VectorAdd(mv->GetAbsOrigin(), push, end); 3225 | TracePlayerBBox(mv->GetAbsOrigin(), end, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, *pTrace); 3226 | mv->SetAbsOrigin(pTrace->endpos); 3227 | 3228 | // So we can run impact function afterwards. 3229 | // If 3230 | if (pTrace->fraction < 1.0 && !pTrace->allsolid) 3231 | { 3232 | (*Interfaces::MoveHelperClient)->AddToTouched(*pTrace, mv->m_vecVelocity_); 3233 | } 3234 | } 3235 | 3236 | int CGameMovement::ClipVelocity(Vector& in, Vector& normal, Vector& out, float overbounce) 3237 | { 3238 | int blocked = 0; 3239 | float angle = normal.z; 3240 | 3241 | if (angle > 0.f) 3242 | blocked |= 1; 3243 | if (angle == 0.f) 3244 | blocked |= 2; 3245 | 3246 | float backoff = DotProduct(in, normal) * overbounce; 3247 | 3248 | for (int i = 0; i < 3; ++i) 3249 | { 3250 | float change = normal[i] * backoff; 3251 | out[i] = in[i] - change; 3252 | } 3253 | 3254 | float adjust = DotProduct(out, normal); 3255 | 3256 | if (adjust < 0.f) 3257 | { 3258 | if (adjust >= -0.03125f) 3259 | adjust = -0.03125f; 3260 | 3261 | out -= normal * adjust; 3262 | } 3263 | 3264 | return blocked; 3265 | } 3266 | 3267 | //dangerzone correct 3268 | bool CGameMovement::CheckWater() 3269 | { 3270 | Vector point; 3271 | GetWaterCheckPosition(1, &point); 3272 | 3273 | player->SetWaterLevel(0); 3274 | player->SetWaterTypeDirect(0); 3275 | 3276 | int cont = GetWaterContentsForPointCached(point, 0); 3277 | 3278 | if (cont & MASK_WATER) 3279 | { 3280 | player->SetWaterType(cont); 3281 | 3282 | GetWaterCheckPosition(2, &point); 3283 | cont = GetWaterContentsForPointCached(point, 1); 3284 | if (cont & MASK_WATER) 3285 | { 3286 | player->SetWaterLevel(2); 3287 | 3288 | GetWaterCheckPosition(3, &point); 3289 | cont = GetWaterContentsForPointCached(point, 2); 3290 | 3291 | if (cont & MASK_WATER) 3292 | player->SetWaterLevel(3); 3293 | } 3294 | } 3295 | 3296 | if (m_nOldWaterLevel == 0.f && player->GetWaterLevel() != 0) 3297 | // *(float*)(gamemovement + 0x10) 3298 | m_flWaterEntryTime = Interfaces::Globals->curtime; 3299 | 3300 | return player->GetWaterLevel() > 1; 3301 | } 3302 | 3303 | void CGameMovement::GetWaterCheckPosition(int waterLevel, Vector* pos) 3304 | { 3305 | pos->x = mv->_m_vecAbsOrigin.x + (GetPlayerMins().x + GetPlayerMaxs().x) * 0.5f; 3306 | pos->y = mv->_m_vecAbsOrigin.y + (GetPlayerMins().y + GetPlayerMaxs().y) * 0.5f; 3307 | 3308 | if (waterLevel == WL_Waist) 3309 | { 3310 | pos->z = mv->_m_vecAbsOrigin.z + (GetPlayerMins().z + GetPlayerMaxs().z) * 0.5f; 3311 | } 3312 | else 3313 | { 3314 | if (waterLevel == WL_Eyes) 3315 | pos->z = mv->_m_vecAbsOrigin.z + player->GetViewOffset().z; 3316 | else 3317 | pos->z = mv->_m_vecAbsOrigin.z + GetPlayerMins().z + 1.f; 3318 | } 3319 | } 3320 | 3321 | void CGameMovement::CategorizePosition() 3322 | { 3323 | player->SetSurfaceFriction(1.f); 3324 | 3325 | CheckWater(); 3326 | 3327 | if (player->IsObserver()) 3328 | return; 3329 | 3330 | Vector point = mv->_m_vecAbsOrigin; 3331 | point.z -= 2.0f; 3332 | 3333 | bool bMovingUp = (mv->m_vecVelocity_.z > 0.f); 3334 | bool bMovingUpRapidly = (mv->m_vecVelocity_.z > 140.f); 3335 | 3336 | if (bMovingUpRapidly) 3337 | { 3338 | if (player->GetGroundEntity() != nullptr) 3339 | { 3340 | bMovingUpRapidly = (player->GetGroundEntity()->GetAbsVelocity()->z > 140.f); 3341 | } 3342 | } 3343 | 3344 | bool bMoveToEndPos = false; 3345 | 3346 | if (player->GetMoveType() == MOVETYPE_WALK) 3347 | { 3348 | if (player->GetGroundEntity() != nullptr) 3349 | { 3350 | bMoveToEndPos = true; 3351 | point.z -= player->GetStepSize(); 3352 | } 3353 | } 3354 | 3355 | if (bMovingUpRapidly || (bMovingUp && player->GetMoveType() == MOVETYPE_LADDER)) 3356 | { 3357 | SetGroundEntity(nullptr); 3358 | } 3359 | else 3360 | { 3361 | trace_t tr; 3362 | TracePlayerBBox(mv->_m_vecAbsOrigin, point, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 3363 | 3364 | bool v10 = (TraceIsOnGroundOrPlayer(&tr) == 0); 3365 | 3366 | if (!v10) 3367 | goto jmp; 3368 | 3369 | ITraceFilter* filter = LockTraceFilter(COLLISION_GROUP_PLAYER_MOVEMENT); 3370 | TracePlayerBBoxForGround(mv->_m_vecAbsOrigin, point, GetPlayerMins(), GetPlayerMaxs(), mv->m_nPlayerHandle.Get(), PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 3371 | UnlockTraceFilter(filter); 3372 | 3373 | v10 = (TraceIsOnGroundOrPlayer(&tr) == 0); 3374 | 3375 | if (v10) 3376 | { 3377 | SetGroundEntity(nullptr); 3378 | if (mv->m_vecVelocity_.z > 0.f) 3379 | { 3380 | if (player->GetMoveType() != MOVETYPE_NOCLIP) 3381 | player->SetSurfaceFriction(0.25f); 3382 | } 3383 | } 3384 | else 3385 | { 3386 | jmp: 3387 | SetGroundEntity(&tr); 3388 | if (bMoveToEndPos && !tr.startsolid && tr.fraction > 0.f && tr.fraction < 1.f) 3389 | mv->_m_vecAbsOrigin = tr.endpos; 3390 | } 3391 | } 3392 | } 3393 | 3394 | //----------------------------------------------------------------------------- 3395 | // Figures out how the constraint should slow us down 3396 | //----------------------------------------------------------------------------- 3397 | float CGameMovement::ComputeConstraintSpeedFactor(void) 3398 | { 3399 | // If we have a constraint, slow down because of that too. 3400 | if (!mv || mv->m_flConstraintRadius == 0.0f) 3401 | return 1.0f; 3402 | 3403 | float flDistSq = mv->GetAbsOrigin().DistToSqr(mv->m_vecConstraintCenter); 3404 | 3405 | float flOuterRadiusSq = mv->m_flConstraintRadius * mv->m_flConstraintRadius; 3406 | float flInnerRadiusSq = mv->m_flConstraintRadius - mv->m_flConstraintWidth; 3407 | flInnerRadiusSq *= flInnerRadiusSq; 3408 | 3409 | // Only slow us down if we're inside the constraint ring 3410 | if ((flDistSq <= flInnerRadiusSq) || (flDistSq >= flOuterRadiusSq)) 3411 | return 1.0f; 3412 | 3413 | // Only slow us down if we're running away from the center 3414 | Vector vecDesired; 3415 | VectorMultiply(m_vecForward, mv->m_flForwardMove, vecDesired); 3416 | VectorMA(vecDesired, mv->m_flSideMove, m_vecRight, vecDesired); 3417 | VectorMA(vecDesired, mv->m_flUpMove, m_vecUp, vecDesired); 3418 | 3419 | Vector vecDelta; 3420 | VectorSubtract(mv->GetAbsOrigin(), mv->m_vecConstraintCenter, vecDelta); 3421 | VectorNormalizeFast(vecDelta); 3422 | VectorNormalizeFast(vecDesired); 3423 | if (DotProduct(vecDelta, vecDesired) < 0.0f) 3424 | return 1.0f; 3425 | 3426 | float flFrac = (sqrt(flDistSq) - (mv->m_flConstraintRadius - mv->m_flConstraintWidth)) / mv->m_flConstraintWidth; 3427 | 3428 | float flSpeedFactor = Lerp(flFrac, 1.0f, mv->m_flConstraintSpeedFactor); 3429 | return flSpeedFactor; 3430 | } 3431 | 3432 | void CGameMovement::CheckParameters() 3433 | { 3434 | if (player->GetMoveType() != MOVETYPE_ISOMETRIC && player->GetMoveType() != MOVETYPE_NOCLIP && player->GetMoveType() != MOVETYPE_OBSERVER) 3435 | { 3436 | float speed = (mv->m_flForwardMove * mv->m_flForwardMove) + (mv->m_flSideMove * mv->m_flSideMove) + (mv->m_flUpMove * mv->m_flUpMove); 3437 | 3438 | if (mv->m_flClientMaxSpeed != 0.f) 3439 | mv->_m_flMaxSpeed = fminf(mv->_m_flMaxSpeed, mv->m_flClientMaxSpeed); 3440 | 3441 | float flSpeedFactor = 1.f; 3442 | 3443 | if (player->GetSurfaceData() != nullptr) 3444 | { 3445 | flSpeedFactor = player->GetSurfaceData()->game.maxSpeedFactor; 3446 | } 3447 | 3448 | float flConstraintSpeedFactor = ComputeConstraintSpeedFactor(); 3449 | 3450 | mv->_m_flMaxSpeed *= flSpeedFactor; 3451 | 3452 | if (speed != 0.f) 3453 | { 3454 | if (speed > (mv->_m_flMaxSpeed * mv->_m_flMaxSpeed)) 3455 | { 3456 | float ratio = mv->_m_flMaxSpeed / sqrt(speed); 3457 | 3458 | mv->m_flForwardMove *= ratio; 3459 | mv->m_flSideMove *= ratio; 3460 | mv->m_flUpMove *= ratio; 3461 | } 3462 | } 3463 | } 3464 | 3465 | if (player->GetFlags() & 0x50 || player->GetHealth() <= 0) 3466 | { 3467 | mv->m_flForwardMove = 0.f; 3468 | mv->m_flSideMove = 0.f; 3469 | mv->m_flUpMove = 0.f; 3470 | } 3471 | 3472 | DecayViewPunchAngle(); 3473 | 3474 | if (player->GetHealth() <= 0) 3475 | { 3476 | mv->m_vecAngles = mv->m_vecOldAngles; 3477 | } 3478 | else 3479 | { 3480 | QAngle vangle = mv->m_vecAngles; 3481 | vangle += player->GetPunch(); //player->m_vecPunchAngle; 3482 | 3483 | if (player->GetMoveType() == MOVETYPE_ISOMETRIC || player->GetMoveType() == MOVETYPE_NOCLIP) 3484 | { 3485 | mv->m_vecAngles.z = 0.f; 3486 | } 3487 | else 3488 | { 3489 | mv->m_vecAngles.z = CalcRoll(vangle, mv->m_vecVelocity_, sv_rollangle.GetVar()->GetFloat(), sv_rollspeed.GetVar()->GetFloat()); 3490 | } 3491 | 3492 | mv->m_vecAngles.x = vangle.x; 3493 | mv->m_vecAngles.y = vangle.y; 3494 | } 3495 | 3496 | if (player->GetHealth() <= 0) 3497 | { 3498 | // v24 = (*(*g_pGameRules + 120))(); 3499 | // (*(v23 + 680))(v2->player, v24 + 96); 3500 | player->SetViewOffset((*g_pGameRules)->GetViewVectors()->m_vDeadViewHeight); 3501 | } 3502 | 3503 | mv->m_vecAngles.y = AngleNormalize(mv->m_vecAngles.y); 3504 | } 3505 | 3506 | //dangerzone correct 3507 | void CCSGameMovement::CheckParameters() 3508 | { 3509 | auto buttons = mv->m_nButtons; 3510 | 3511 | if (mv->m_nButtons & IN_DUCK) 3512 | mv->m_nButtons |= IN_BULLRUSH; // 0x400000; 3513 | 3514 | if ((mv->m_nButtons ^ mv->m_nOldButtons) & IN_BULLRUSH) // 0x400000 3515 | { 3516 | float newduckspeed = fmaxf(player->GetDuckSpeed() - 2.f, 0.f); 3517 | 3518 | if (player->GetDuckSpeed() != newduckspeed) 3519 | player->SetDuckSpeed(newduckspeed); 3520 | } 3521 | 3522 | if (m_pCSPlayer->GetDuckUntilOnGround() && mv->m_nButtons & IN_DUCK) 3523 | m_pCSPlayer->SetDuckUntilOnGround(false); 3524 | 3525 | // !sub_10390E60(this)() 3526 | // if(m_flDuckSpeed < 1.5) || !(m_iFlags & FL_DUCKING) && curtime < (m_flDuckTime + sv_timebetweenducks)) 3527 | if (!CCSGameMovement::IsPlayerDucking()) 3528 | mv->m_nButtons &= ~IN_DUCK; 3529 | 3530 | if (m_pCSPlayer->GetDuckUntilOnGround()) 3531 | { 3532 | if (player->GetGroundEntity() == nullptr) 3533 | { 3534 | if (player->GetMoveType() != MOVETYPE_LADDER) 3535 | mv->m_nButtons |= IN_DUCK; 3536 | } 3537 | } 3538 | 3539 | if (m_pCSPlayer->GetDuckOverride()) 3540 | mv->m_nButtons |= IN_DUCK; 3541 | 3542 | auto movingForward = mv->m_nButtons & IN_FORWARD; 3543 | auto movingBackward = mv->m_nButtons & IN_BACK; 3544 | auto movingRight = mv->m_nButtons & IN_MOVERIGHT; 3545 | auto movingLeft = mv->m_nButtons & IN_MOVELEFT; 3546 | auto walking = mv->m_nButtons & IN_SPEED; 3547 | auto pressinganymovebuttons = mv->m_nButtons & (IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT | IN_RUN); //0x1618; 3548 | 3549 | auto walkstate = walking; 3550 | 3551 | bool pressingbothforwardandback; 3552 | bool pressingbothsidebuttons; 3553 | 3554 | if (!movingForward) 3555 | pressingbothforwardandback = false; 3556 | else 3557 | pressingbothforwardandback = movingBackward; 3558 | 3559 | // same as above 3560 | //if (!movingForward || (pressingbothforwardandback = true, !movingBackward)) 3561 | // pressingbothforwardandback = false; 3562 | 3563 | if (!movingRight) 3564 | pressingbothsidebuttons = false; 3565 | else 3566 | pressingbothsidebuttons = movingLeft; 3567 | 3568 | // same as above 3569 | //if (!movingRight || (pressingbothsidebuttons = true, !movingLeft)) 3570 | // pressingbothsidebuttons = false; 3571 | 3572 | if (mv->m_nButtons & IN_DUCK || player->GetDucking() || player->GetFlags() & FL_DUCKING) 3573 | { 3574 | walkstate = false; 3575 | } 3576 | else if (walking) 3577 | { 3578 | float adjustedmaxspeed = mv->_m_flMaxSpeed * _CS_PLAYER_SPEED_WALK_MODIFIER; 3579 | Vector velocity = m_pCSPlayer->GetVelocity(); 3580 | 3581 | if ((adjustedmaxspeed + 25.f) > velocity.Length()) 3582 | { 3583 | mv->_m_flMaxSpeed = adjustedmaxspeed; 3584 | 3585 | if (!m_pCSPlayer->GetIsWalking()) 3586 | m_pCSPlayer->SetIsWalking(true); 3587 | } 3588 | 3589 | goto jmp_35; 3590 | } 3591 | 3592 | if (m_pCSPlayer->GetIsWalking()) 3593 | m_pCSPlayer->SetIsWalking(false); 3594 | 3595 | jmp_35: 3596 | 3597 | if (player->GetMoveType() != MOVETYPE_ISOMETRIC && player->GetMoveType() != MOVETYPE_NOCLIP && player->GetMoveType() != MOVETYPE_OBSERVER) 3598 | { 3599 | float sidemove = mv->m_flSideMove; 3600 | float forwardmove = mv->m_flForwardMove; 3601 | float upmove = mv->m_flUpMove; 3602 | 3603 | float v27 = (sidemove * sidemove) + (forwardmove * forwardmove) + (upmove * upmove); 3604 | float speedFactor = 1.f; 3605 | 3606 | if (player->GetSurfaceData() != nullptr) 3607 | { 3608 | speedFactor = player->GetSurfaceData()->game.maxSpeedFactor; 3609 | } 3610 | 3611 | float flConstraintSpeedFactor = ComputeConstraintSpeedFactor(); 3612 | if (flConstraintSpeedFactor < speedFactor) 3613 | speedFactor = flConstraintSpeedFactor; 3614 | 3615 | if (m_pCSPlayer->GetFlags() & FL_ONGROUND) 3616 | { 3617 | speedFactor *= m_pCSPlayer->GetVelocityModifier(); 3618 | } 3619 | 3620 | CBaseCombatWeapon* activeWeap = m_pCSPlayer->GetWeapon(); //m_pCSPlayer->GetActiveWeapon(); 3621 | //FIXME: dynamic_cast here from C_BaseCombatWeapon to C_WeaponCSBase 3622 | 3623 | if (activeWeap != nullptr && mv->m_nButtons & IN_ATTACK && !activeWeap->IsReloading() && activeWeap->GetClipOne() > 0) 3624 | { 3625 | //(*(*combatweapon + 0x6E0))(combatweapon); // Calls C_BaseCombatWeapon's 440th index 3626 | speedFactor *= activeWeap->GetMaxSpeed2(); 3627 | } 3628 | 3629 | mv->_m_flMaxSpeed *= speedFactor; 3630 | 3631 | if (m_pCSPlayer->GetStamina() > 0.f) 3632 | { 3633 | float v35 = 1.f - m_pCSPlayer->GetStamina() * 0.01f; 3634 | float v36 = 0.f; 3635 | 3636 | if (v35 >= 0.f) 3637 | v36 = fmin(v35, 1.f); 3638 | 3639 | float v37 = v36; 3640 | mv->_m_flMaxSpeed *= (v37 * v37); 3641 | } 3642 | 3643 | if (v27 != 0.f && v27 > (mv->_m_flMaxSpeed * mv->_m_flMaxSpeed)) 3644 | { 3645 | float ratio = mv->_m_flMaxSpeed / sqrt(v27); 3646 | 3647 | mv->m_flForwardMove *= ratio; 3648 | mv->m_flSideMove *= ratio; 3649 | mv->m_flUpMove *= ratio; 3650 | } 3651 | } 3652 | 3653 | // (*(*player + 0x474))() != 6 ) 3654 | if ((player->GetFlags() & 0x50 || player->GetHealth() <= 0) && player->GetObserverMode() != OBS_MODE_ROAMING) 3655 | { 3656 | mv->m_flForwardMove = 0.f; 3657 | mv->m_flSideMove = 0.f; 3658 | mv->m_flUpMove = 0.f; 3659 | } 3660 | 3661 | DecayViewPunchAngle(); 3662 | DecayAimPunchAngle(); 3663 | 3664 | if (player->GetHealth() <= 0) 3665 | { 3666 | mv->m_vecAngles = mv->m_vecOldAngles; 3667 | } 3668 | else 3669 | { 3670 | QAngle angles = mv->m_vecAngles + player->GetPunch(); 3671 | 3672 | if (player->GetMoveType() == MOVETYPE_ISOMETRIC || player->GetMoveType() == MOVETYPE_NOCLIP) 3673 | { 3674 | mv->m_vecAngles.z = 0.f; 3675 | } 3676 | else 3677 | { 3678 | mv->m_vecAngles.z = CalcRoll(angles, mv->m_vecVelocity_, sv_rollangle.GetVar()->GetFloat(), sv_rollspeed.GetVar()->GetFloat()); 3679 | } 3680 | 3681 | mv->m_vecAngles = angles; 3682 | } 3683 | 3684 | if (player->GetHealth() <= 0 && player->GetObserverMode() == OBS_MODE_DEATHCAM) 3685 | { 3686 | player->SetViewOffset((*g_pGameRules)->GetViewVectors()->m_vDeadViewHeight); 3687 | } 3688 | 3689 | mv->m_vecAngles.y = AngleNormalize(mv->m_vecAngles.y); 3690 | 3691 | if (player->GetObserverMode() == OBS_MODE_NONE) 3692 | { 3693 | if (player->GetMoveType() != MOVETYPE_LADDER) 3694 | { 3695 | int nLevels = 0; 3696 | CBaseEntity* pCurGround = player->GetGroundEntity(); 3697 | while (pCurGround && pCurGround->IsPlayer() && nLevels < 1000) 3698 | { 3699 | pCurGround = pCurGround->GetGroundEntity(); 3700 | ++nLevels; 3701 | 3702 | #ifdef _DEBUG 3703 | if (nLevels == 1000) 3704 | printf("BUG: CCSGameMovement::CheckParameters - too many stacking levels.\n"); 3705 | #endif 3706 | 3707 | if (nLevels > 1) 3708 | { 3709 | mv->m_flForwardMove = mv->_m_flMaxSpeed * 3.f; 3710 | mv->m_flSideMove = 0.f; 3711 | mv->m_nButtons = 0; 3712 | mv->m_nImpulseCommand = 0; 3713 | } 3714 | } 3715 | } 3716 | } 3717 | 3718 | if (m_pCSPlayer->GetMoveState() > 0) 3719 | m_pCSPlayer->SetMoveState(0); 3720 | 3721 | #if 1 3722 | if (pressinganymovebuttons) 3723 | { 3724 | if (pressingbothforwardandback) 3725 | { 3726 | if (pressingbothsidebuttons) 3727 | { 3728 | //can't move if pressing all the move keys 3729 | if (m_pCSPlayer->GetMoveState() > 0) 3730 | m_pCSPlayer->SetMoveState(0); 3731 | } 3732 | else if (movingRight || movingLeft) 3733 | { 3734 | if (m_pCSPlayer->GetMoveState() != 2) 3735 | m_pCSPlayer->SetMoveState(2); 3736 | } 3737 | else 3738 | { 3739 | if (m_pCSPlayer->GetMoveState() > 0) 3740 | m_pCSPlayer->SetMoveState(0); 3741 | } 3742 | } 3743 | else 3744 | { 3745 | if (!pressingbothsidebuttons || movingForward) 3746 | { 3747 | if (m_pCSPlayer->GetMoveState() != 2) 3748 | m_pCSPlayer->SetMoveState(2); 3749 | } 3750 | else if (!movingBackward) 3751 | { 3752 | if (m_pCSPlayer->GetMoveState() > 0) 3753 | m_pCSPlayer->SetMoveState(0); 3754 | } 3755 | else 3756 | { 3757 | if (m_pCSPlayer->GetMoveState() != 2) 3758 | m_pCSPlayer->SetMoveState(2); 3759 | } 3760 | } 3761 | } 3762 | #else 3763 | bool v64 = false; 3764 | if (pressinganymovebuttons) 3765 | { 3766 | if (pressingbothforwardandback) 3767 | { 3768 | if (pressingbothsidebuttons) 3769 | goto jmp_103; 3770 | if (movingRight) 3771 | goto jmp_111; 3772 | 3773 | v64 = (movingLeft == 0); 3774 | } 3775 | else 3776 | { 3777 | if (!pressingbothsidebuttons || movingForward) 3778 | { 3779 | jmp_111: 3780 | if (m_pCSPlayer->GetMoveState() != 2) 3781 | m_pCSPlayer->SetMoveState(2); 3782 | goto jmp_113; 3783 | } 3784 | 3785 | v64 = (movingBackward == 0); 3786 | } 3787 | 3788 | if (v64) 3789 | { 3790 | jmp_103: 3791 | if (m_pCSPlayer->GetMoveState() > 0) 3792 | m_pCSPlayer->SetMoveState(0); 3793 | 3794 | goto jmp_113; 3795 | } 3796 | 3797 | goto jmp_111; 3798 | } 3799 | #endif 3800 | 3801 | jmp_113: 3802 | 3803 | if (m_pCSPlayer->GetMoveState() == 2 && walkstate && m_pCSPlayer->GetMoveState() != 1) 3804 | m_pCSPlayer->SetMoveState(1); 3805 | } 3806 | 3807 | void CGameMovement::ReduceTimers() 3808 | { 3809 | if (player->GetDuckTimeMsecs() > 0) 3810 | { 3811 | player->SetDuckTimeMsecs((float)player->GetDuckTimeMsecs() - (Interfaces::Globals->frametime * 1000.f)); 3812 | 3813 | if (player->GetDuckTimeMsecs() < 0) 3814 | player->SetDuckTimeMsecs(0); 3815 | } 3816 | 3817 | if (player->GetDuckJumpTimeMsecs() > 0) 3818 | { 3819 | player->SetDuckJumpTimeMsecs((float)player->GetDuckJumpTimeMsecs() - (Interfaces::Globals->frametime * 1000.f)); 3820 | 3821 | if (player->GetDuckJumpTimeMsecs() < 0) 3822 | player->SetDuckJumpTimeMsecs(0); 3823 | } 3824 | 3825 | if (player->GetJumpTimeMsecs() > 0) 3826 | { 3827 | player->SetJumpTimeMsecs((float)player->GetJumpTimeMsecs() - (Interfaces::Globals->frametime * 1000.f)); 3828 | 3829 | if (player->GetJumpTimeMsecs() < 0) 3830 | player->SetJumpTimeMsecs(0); 3831 | } 3832 | 3833 | if (player->GetSwimSoundTime() > 0.f) 3834 | { 3835 | player->SetSwimSoundTime(player->GetSwimSoundTime() - (Interfaces::Globals->frametime * 1000.f)); 3836 | 3837 | if (player->GetSwimSoundTime() < 0.f) 3838 | player->SetSwimSoundTime(0.f); 3839 | } 3840 | } 3841 | 3842 | void CCSGameMovement::ReduceTimers() 3843 | { 3844 | if (m_pCSPlayer->GetStamina() > 0.f) 3845 | { 3846 | float v4 = Interfaces::Globals->frametime * sv_staminarecoveryrate.GetVar()->GetFloat(); 3847 | 3848 | if (m_pCSPlayer->GetStamina() != (m_pCSPlayer->GetStamina() - v4)) 3849 | m_pCSPlayer->SetStamina(m_pCSPlayer->GetStamina() - v4); 3850 | 3851 | if (m_pCSPlayer->GetStamina() < 0.f) 3852 | m_pCSPlayer->SetStamina(0.f); 3853 | } 3854 | 3855 | CGameMovement::ReduceTimers(); 3856 | } 3857 | 3858 | void CGameMovement::CheckFalling() 3859 | { 3860 | if (player->GetGroundEntity() != nullptr) 3861 | { 3862 | float fallvel = player->GetFallVelocity(); 3863 | if (fallvel > 0.f) 3864 | { 3865 | if (player->GetHealth() > 0 && fallvel >= 350.f) 3866 | { 3867 | bool bAlive = true; 3868 | float fVol = 0.5f; 3869 | 3870 | if (player->GetWaterLevel() == 0) 3871 | { 3872 | auto groundEnt = player->GetGroundEntity(); 3873 | 3874 | if (groundEnt->GetAbsVelocity()->z < 0.f) 3875 | { 3876 | auto playerGroundEnt = player->GetGroundEntity(); 3877 | player->SetFallVelocity(player->GetFallVelocity() + playerGroundEnt->GetAbsVelocity()->z); 3878 | player->SetFallVelocity(fmaxf(player->GetFallVelocity(), 0.1f)); 3879 | } 3880 | 3881 | fallvel = player->GetFallVelocity(); 3882 | 3883 | if (fallvel <= 580.f) 3884 | { 3885 | if (fallvel <= 290.f) 3886 | { 3887 | if (fallvel >= 200.f) 3888 | fVol = 0.5f; 3889 | else 3890 | fVol = 0.f; 3891 | } 3892 | else 3893 | { 3894 | fVol = 0.85000002f; 3895 | } 3896 | } 3897 | else 3898 | { 3899 | fVol = 1.0f; 3900 | LocalPlayer.CalledPlayerHurt = true; 3901 | #ifdef _DEBUG 3902 | printf("HURT ME\n"); 3903 | #endif 3904 | bAlive = (*Interfaces::MoveHelperClient)->PlayerFallingDamage(); 3905 | } 3906 | } 3907 | 3908 | CGameMovement::PlayerRoughLandingEffects(fVol); 3909 | 3910 | if (bAlive) 3911 | (*Interfaces::MoveHelperClient)->PlayerSetAnimation(PLAYER_WALK); 3912 | } 3913 | 3914 | if (player->GetFallVelocity() > 16.f && player->GetFallVelocity() <= 1024.f) 3915 | { 3916 | QAngle punchangle; 3917 | player->GetPunchVMT(punchangle); 3918 | 3919 | punchangle.x = player->GetFallVelocity() * 0.001f; 3920 | if (punchangle.x < 0.75f) 3921 | punchangle.x = 0.75f; 3922 | 3923 | player->SetPunchVMT(punchangle); 3924 | } 3925 | OnLand(player->GetFallVelocity()); 3926 | player->SetFallVelocity(0.f); 3927 | } 3928 | } 3929 | } 3930 | 3931 | void CGameMovement::PlayerRoughLandingEffects(float fVol) 3932 | { 3933 | if (fVol > 0.f) 3934 | { 3935 | // mov dword ptr [eax+320Ch], 400.0 3936 | player->SetStepSoundTime(400.0f); 3937 | 3938 | player->PlayStepSound(mv->_m_vecAbsOrigin, player->GetSurfaceData(), fmaxf(fVol, 0.1f), false, false); 3939 | 3940 | float TargetZPunch = (player->GetFallVelocity() - 580.f) * 0.013f; 3941 | 3942 | QAngle punch = player->GetPunch(); 3943 | 3944 | if (punch.z != TargetZPunch) 3945 | { 3946 | player->GetLocalData()->NetworkStateChanged(player->GetPunchAdr()); 3947 | punch.z = TargetZPunch; 3948 | player->SetPunch(punch); 3949 | } 3950 | 3951 | punch = player->GetPunch(); 3952 | 3953 | if (punch.x > 8.f && punch.x != 8.f) 3954 | { 3955 | player->GetLocalData()->NetworkStateChanged(player->GetPunchAdr()); 3956 | punch.x = 8.0f; 3957 | player->SetPunch(punch); 3958 | } 3959 | } 3960 | } 3961 | 3962 | //dangerzone correct 3963 | void CGameMovement::Duck() 3964 | { 3965 | int buttonsChanged = (mv->m_nOldButtons ^ mv->m_nButtons); 3966 | int buttonsPressed = (buttonsChanged & mv->m_nButtons); 3967 | int buttonsReleased = (buttonsChanged & mv->m_nOldButtons); 3968 | 3969 | CBaseEntity* groundEntityPtr = player->GetGroundEntity(); 3970 | 3971 | int v10 = (player->GetFlags() >> 1) & 1; 3972 | int v39 = player->GetDuckJumpTimeMsecs(); 3973 | 3974 | if (mv->m_nButtons & IN_DUCK) 3975 | mv->m_nOldButtons |= IN_DUCK; 3976 | else 3977 | mv->m_nOldButtons &= ~IN_DUCK; 3978 | 3979 | if (player->GetHealth() <= 0) 3980 | return; 3981 | 3982 | HandleDuckingSpeedCrop(); 3983 | 3984 | if (!(mv->m_nButtons & IN_DUCK)) 3985 | { 3986 | if (!player->GetDucking() && !v10 && player->GetJumpTimeMsecs() <= 0) 3987 | { 3988 | if (player->GetHealth() > 0 && !player->IsObserver() && !player->IsInAVehicle() && player->GetDuckJumpTimeMsecs() == 0) 3989 | { 3990 | if (fabs(player->GetViewOffset().z - GetPlayerViewOffset(false).z) > 0.1f) 3991 | SetDuckedEyeOffset(0.f); 3992 | } 3993 | } 3994 | 3995 | return; 3996 | } 3997 | 3998 | if (mv->m_nButtons & IN_DUCK || player->GetJumpTimeMsecs() > 0) 3999 | { 4000 | if (buttonsPressed & IN_DUCK && !v10 && player->GetJumpTimeMsecs() <= 0 && player->GetDuckJumpTimeMsecs() <= 0) 4001 | { 4002 | player->SetDuckTimeMsecs(1000); 4003 | player->SetDucking(TRUE); 4004 | } 4005 | 4006 | if (!player->GetDucking()) 4007 | goto jmp_70; 4008 | 4009 | if (player->GetJumpTimeMsecs() > 0) 4010 | { 4011 | jmp_71: 4012 | if (v10) 4013 | { 4014 | if (!(mv->m_nButtons & IN_DUCK)) 4015 | { 4016 | trace_t tr; 4017 | if (CanUnduckJump(tr)) 4018 | { 4019 | FinishUnduckJump(tr); 4020 | player->SetDuckJumpTimeMsecs(((((1.f - tr.fraction) * tr.fraction) * 200.f) + 800.f)); 4021 | } 4022 | } 4023 | } 4024 | else 4025 | { 4026 | StartUnduckJump(); 4027 | } 4028 | 4029 | return; 4030 | } 4031 | 4032 | if (player->GetDuckJumpTimeMsecs() > 0) 4033 | { 4034 | jmp_70: 4035 | if (player->GetJumpTimeMsecs() <= 0) 4036 | { 4037 | return; 4038 | } 4039 | 4040 | goto jmp_71; 4041 | } 4042 | 4043 | auto temp = 1000 - player->GetDuckTimeMsecs(); 4044 | if (temp >= 0 && temp > 200) 4045 | { 4046 | goto jmp_69; 4047 | } 4048 | else 4049 | { 4050 | temp = 0; 4051 | } 4052 | 4053 | if (!v10 && groundEntityPtr != nullptr) 4054 | { 4055 | float v29 = 0.f; 4056 | float v30 = (float)temp * 0.005f; 4057 | 4058 | if (v30 >= 0.f) 4059 | v29 = fminf(v30, 1.f); 4060 | 4061 | SetDuckedEyeOffset(((v29 * v29) * 3.f) - (((v29 * v29) * 2.f) * v29)); 4062 | goto jmp_70; 4063 | } 4064 | 4065 | jmp_69: 4066 | FinishDuck(); 4067 | goto jmp_70; 4068 | } 4069 | 4070 | if (player->IsInDuckJump()) 4071 | { 4072 | trace_t tr; 4073 | 4074 | if (CanUnduckJump(tr)) 4075 | { 4076 | FinishUnduckJump(tr); 4077 | 4078 | if (tr.fraction < 1.f) 4079 | player->SetDuckJumpTimeMsecs((((1.f - tr.fraction) * 200.f) + 800.f)); 4080 | } 4081 | } 4082 | 4083 | if (player->GetDuckJumpTimeMsecs() <= 0) 4084 | { 4085 | if (player->GetAllowAutoMovement() || player->GetDucking() || groundEntityPtr == nullptr) 4086 | { 4087 | if (buttonsReleased & IN_DUCK) 4088 | { 4089 | if (v10 && player->GetJumpTimeMsecs() <= 0) 4090 | { 4091 | player->SetDuckTimeMsecs(1000); 4092 | } 4093 | else if (player->GetDucking() && !player->GetDucked()) 4094 | { 4095 | float temp = (float)(1000 - player->GetDuckTimeMsecs()) * 0.005f; 4096 | float newtemp = 0.f; 4097 | if (temp >= 0.f) 4098 | newtemp = fminf(temp, 1.f); 4099 | else 4100 | newtemp = 0.f; 4101 | 4102 | player->SetDuckTimeMsecs(800 - (int)(newtemp * -200.f)); 4103 | } 4104 | } 4105 | 4106 | if (CanUnduck()) 4107 | { 4108 | if (player->GetDucking() && !player->GetDucked()) 4109 | return; 4110 | 4111 | int temp = 1000 - player->GetDuckTimeMsecs(); 4112 | 4113 | if (temp >= 0) 4114 | { 4115 | if (temp > 200) 4116 | goto jmp_50; 4117 | } 4118 | else 4119 | { 4120 | temp = 0; 4121 | } 4122 | 4123 | if (groundEntityPtr != nullptr || player->GetJumpTimeMsecs() > 0) 4124 | { 4125 | float v24 = 0.0f; 4126 | float v25 = (float)temp * 0.005f; 4127 | 4128 | if (v25 >= 0.f) 4129 | v24 = fminf(v25, 1.f); 4130 | 4131 | SetDuckedEyeOffset((((1.f - v24) * (1.f - v24)) * 3.f) - ((((1.f - v24) * (1.f - v24)) * 2.f) * (1.f - v24))); 4132 | 4133 | player->SetDucking(TRUE); 4134 | return; 4135 | } 4136 | 4137 | jmp_50: 4138 | FinishUnduck(); 4139 | return; 4140 | } 4141 | 4142 | if (player->GetDuckTimeMsecs() != 1000) 4143 | { 4144 | SetDuckedEyeOffset(1.f); 4145 | player->SetDuckTimeMsecs(1000); 4146 | player->SetDucked(TRUE); 4147 | player->SetDucking(FALSE); 4148 | player->AddFlag(FL_DUCKING); 4149 | } 4150 | } 4151 | } 4152 | } 4153 | 4154 | bool CCSGameMovement::IsPlayerDucking() 4155 | { 4156 | if (m_pCSPlayer->GetDuckSpeed() <= 1.5f || !(m_pCSPlayer->GetFlags() & FL_DUCKING) || (m_pCSPlayer->GetLastDuckTime() + sv_timebetweenducks.GetVar()->GetFloat()) > Interfaces::Globals->curtime) 4157 | return false; 4158 | return true; 4159 | } 4160 | 4161 | //dangerzone correct 4162 | bool CCSGameMovement::CanMove(CBasePlayer* ent) 4163 | { 4164 | if (ent->GetMoveType() != MOVETYPE_NONE) 4165 | { 4166 | if (ent->GetObserverMode()) 4167 | return true; 4168 | 4169 | auto state = ent->GetPlayerState(); 4170 | CBaseCombatWeapon* weap; 4171 | 4172 | if ((state == STATE_ACTIVE || state == STATE_OBSERVER_MODE) 4173 | && !ent->IsGrabbingHostage() 4174 | && !ent->IsDefusing() 4175 | && !ent->BlockingUseActionInProgress() 4176 | && (!(*g_pGameRules)->IsFreezePeriod() || ent->GetCanMoveDuringFreezePeriod()) 4177 | && (weap = ent->GetCSWeapon(ClassID::_CC4), (!weap || !weap->StartedArming()))) 4178 | { 4179 | return true; 4180 | } 4181 | } 4182 | 4183 | return false; 4184 | } 4185 | 4186 | //dangerzone correct 4187 | void CCSGameMovement::ApplyDuckRatio(float flDuckAmount) 4188 | { 4189 | if (player->GetObserverMode() != 6 && !m_bSpeedCropped) 4190 | { 4191 | if (mv->m_nButtons & IN_DUCK || player->GetDucking() || player->GetFlags() & FL_DUCKING) 4192 | { 4193 | float duckratio = ((flDuckAmount * 0.34) + 1.0f) - flDuckAmount; 4194 | mv->m_flForwardMove *= duckratio; 4195 | mv->m_flSideMove *= duckratio; 4196 | mv->m_flUpMove *= duckratio; 4197 | mv->_m_flMaxSpeed *= duckratio; 4198 | m_bSpeedCropped = true; 4199 | } 4200 | } 4201 | } 4202 | 4203 | //dangerzone correct 4204 | void CCSGameMovement::Duck() 4205 | { 4206 | bool onladder = false; 4207 | CBaseEntity* groundEntity = player->GetGroundEntity(); 4208 | 4209 | if (!groundEntity) 4210 | { 4211 | if (player->GetMoveType() == MOVETYPE_LADDER) 4212 | onladder = true; 4213 | } 4214 | 4215 | if (mv->m_nButtons & IN_DUCK) 4216 | mv->m_nOldButtons |= IN_DUCK; 4217 | else 4218 | mv->m_nOldButtons &= ~IN_DUCK; 4219 | 4220 | if (player->GetHealth() <= 0 && !(player->GetObserverMode())) 4221 | { 4222 | if (player->GetDuckOverride()) 4223 | player->SetDuckOverride(false); 4224 | 4225 | if (!(player->GetFlags() & FL_DUCKING)) 4226 | { 4227 | FinishDuck(); 4228 | return; 4229 | } 4230 | } 4231 | 4232 | float newduckspeed = 0.f; 4233 | 4234 | if (!m_pCSPlayer->GetDuckUntilOnGround()) 4235 | { 4236 | float duckspeed = player->GetDuckSpeed(); 4237 | float v32 = Interfaces::Globals->frametime * 3.f; 4238 | 4239 | if ((8.f - duckspeed) <= v32) 4240 | { 4241 | if (-v32 <= (8.f - duckspeed)) 4242 | newduckspeed = 8.f; 4243 | else 4244 | newduckspeed = duckspeed - v32; 4245 | } 4246 | else 4247 | { 4248 | newduckspeed = v32 + duckspeed; 4249 | } 4250 | 4251 | if (player->GetDuckSpeed() != newduckspeed) 4252 | player->SetDuckSpeed(newduckspeed); 4253 | 4254 | if (player->GetDuckSpeed() < 8.f) 4255 | { 4256 | float duckamount = player->GetDuckAmount(); 4257 | 4258 | if (duckamount > 0.f && duckamount < 1.f) 4259 | goto jmp_37; 4260 | 4261 | // Calls C_BasePlayer's 10th func 4262 | Vector* absorigin = player->GetAbsOrigin(); 4263 | 4264 | // probably some sort of velocity lol 4265 | Vector2D duckingorigin = player->GetDuckingOrigin(); 4266 | Vector duckingorigin2 = { duckingorigin.x, duckingorigin.y, 0 }; 4267 | 4268 | if ((duckingorigin2 - *absorigin).Length2DSqr() > 4096.f) 4269 | { 4270 | float v51; 4271 | float v50 = Interfaces::Globals->frametime * 6.0f; 4272 | 4273 | if ((8.0f - player->GetDuckSpeed()) <= v50) 4274 | { 4275 | if (-v50 <= (8.0f - player->GetDuckSpeed())) 4276 | v51 = 8.0f; 4277 | else 4278 | v51 = player->GetDuckSpeed() - v50; 4279 | } 4280 | else 4281 | { 4282 | v51 = player->GetDuckSpeed() + v50; 4283 | } 4284 | 4285 | if (player->GetDuckSpeed() != v51) 4286 | player->SetDuckSpeed(v51); 4287 | 4288 | goto jmp_37; 4289 | } 4290 | } 4291 | else 4292 | { 4293 | // Calls C_BasePlayer's 10th func 4294 | Vector* absorigin = player->GetAbsOrigin(); 4295 | 4296 | player->SetDuckingOrigin(*absorigin); 4297 | } 4298 | 4299 | jmp_37: 4300 | float v60; 4301 | if (mv->m_nButtons & IN_DUCK) 4302 | { 4303 | if (player->GetDuckAmount() < 1.f) 4304 | player->SetDucking(TRUE); 4305 | 4306 | if (player->GetDucking()) 4307 | { 4308 | float v57 = player->GetDuckSpeed() * 0.8f; 4309 | 4310 | if (player->IsDefusing()) 4311 | v57 *= 0.4f; 4312 | 4313 | float v59 = Interfaces::Globals->frametime * v57; 4314 | 4315 | if ((1.0f - player->GetDuckAmount()) <= v59) 4316 | { 4317 | if (-v59 <= (1.0f - player->GetDuckAmount())) 4318 | v60 = 1.0f; 4319 | else 4320 | v60 = player->GetDuckAmount() - v59; 4321 | } 4322 | else 4323 | { 4324 | v60 = player->GetDuckAmount() + v59; 4325 | } 4326 | 4327 | if (player->GetDuckAmount() != v60) 4328 | player->SetDuckAmount(v60); 4329 | 4330 | if (player->GetDuckAmount() < 1.0f && groundEntity != nullptr) 4331 | SetDuckedEyeOffset(player->GetDuckAmount()); 4332 | else 4333 | FinishDuck(); 4334 | 4335 | if (player->GetDuckAmount() >= 0.1f && !(player->GetFlags() & FL_ANIMDUCKING)) 4336 | player->AddFlag(FL_ANIMDUCKING); 4337 | } 4338 | } 4339 | else 4340 | { 4341 | if (player->GetDuckAmount() > 0.0f) 4342 | player->SetDucking(TRUE); 4343 | 4344 | if (player->GetDucking() && player->GetAllowAutoMovement() || groundEntity == nullptr) 4345 | { 4346 | bool v39 = CanUnduck(); 4347 | 4348 | if (v39) 4349 | { 4350 | float adjust = fmaxf(player->GetDuckSpeed(), 1.5f); 4351 | 4352 | if (player->IsDefusing()) 4353 | adjust *= 0.4f; 4354 | 4355 | float v44 = Interfaces::Globals->frametime * adjust; 4356 | float v45; 4357 | 4358 | if (-player->GetDuckAmount() <= v44) 4359 | { 4360 | if (-v44 <= -player->GetDuckAmount()) 4361 | v45 = 0.0f; 4362 | else 4363 | v45 = player->GetDuckAmount() - v44; 4364 | } 4365 | else 4366 | { 4367 | v45 = player->GetDuckAmount() + v44; 4368 | } 4369 | 4370 | if (player->GetDuckAmount() != v45) 4371 | player->SetDuckAmount(v45); 4372 | 4373 | player->SetDucked(FALSE); 4374 | 4375 | if (player->GetDuckAmount() > 0.0f && groundEntity != nullptr) 4376 | SetDuckedEyeOffset(player->GetDuckAmount()); 4377 | else 4378 | FinishUnduck(); 4379 | 4380 | if (player->GetDuckAmount() <= 0.75f && (player->GetFlags() & (FL_ANIMDUCKING | FL_DUCKING))) 4381 | player->RemoveFlag(FL_ANIMDUCKING | FL_DUCKING); 4382 | } 4383 | else 4384 | { 4385 | float v84 = 1.0f; 4386 | 4387 | if (player->GetDuckAmount() != 1.0f) 4388 | player->SetDuckAmount(1.0f); 4389 | 4390 | player->SetDucked(TRUE); 4391 | player->SetDucking(FALSE); 4392 | player->AddFlag(FL_ANIMDUCKING | FL_DUCKING); // |= 6 4393 | SetDuckedEyeOffset(player->GetDuckAmount()); 4394 | } 4395 | } 4396 | } 4397 | 4398 | if (player->GetDuckAmount() <= 0.0f && player->GetFlags() & FL_ANIMDUCKING) 4399 | player->RemoveFlag(FL_ANIMDUCKING); 4400 | 4401 | // bool : return (Interfaces::EngineClient->IsHLTV() || Interfaces::EngineClient->IsPlayingDemo()) && (*(*engineclient + 904))() <= 13546; 4402 | if ((Interfaces::EngineClient->IsHLTV() || Interfaces::EngineClient->IsPlayingDemo()) && Interfaces::EngineClient->GetEngineBuildNumber() <= 13546) 4403 | { 4404 | if (player->GetDuckTimeMsecs() >= 0) 4405 | player->AddFlag(FL_DUCKING | FL_ANIMDUCKING); 4406 | else 4407 | player->RemoveFlag(FL_DUCKING | FL_ANIMDUCKING); 4408 | 4409 | float v66 = 150.f - (float)player->GetDuckTimeMsecs(); 4410 | float v67 = fmaxf(v66, 0.f) * 0.0066666668f; 4411 | 4412 | if (player->GetDuckAmount() != v67) 4413 | player->SetDuckAmount(v67); 4414 | 4415 | SetDuckedEyeOffset(player->GetDuckAmount()); 4416 | } 4417 | 4418 | ApplyDuckRatio(m_pCSPlayer->GetDuckAmount()); 4419 | return; 4420 | } 4421 | 4422 | if (!(player->GetFlags() & FL_DUCKING)) 4423 | { 4424 | m_pCSPlayer->SetDuckUntilOnGround(false); 4425 | return; 4426 | } 4427 | 4428 | if (!onladder) 4429 | { 4430 | m_pCSPlayer->SetDuckUntilOnGround(false); 4431 | 4432 | if (CanUnduck()) 4433 | { 4434 | FinishDuck(); 4435 | return; 4436 | } 4437 | } 4438 | 4439 | if (mv->m_vecVelocity_.z <= 0.f) 4440 | { 4441 | trace_t tr; 4442 | 4443 | Vector newOrigin = mv->_m_vecAbsOrigin; 4444 | 4445 | Vector hullSizeNormal = (*g_pGameRules)->GetViewVectors()->m_vHullMax - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4446 | Vector hullSizeDuck = (*g_pGameRules)->GetViewVectors()->m_vDuckHullMax - (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin; 4447 | Vector delta = hullSizeNormal - hullSizeDuck; 4448 | newOrigin -= delta; 4449 | 4450 | Vector groundCheck = newOrigin; 4451 | groundCheck.z -= player->GetStepSize(); 4452 | 4453 | UTIL_TraceHull(newOrigin, groundCheck, (*g_pGameRules)->GetViewVectors()->m_vHullMin, (*g_pGameRules)->GetViewVectors()->m_vHullMax, /*CGameMovement::*/ PlayerSolidMask(), player, COLLISION_GROUP_PLAYER_MOVEMENT, tr); 4454 | 4455 | if (!tr.startsolid && tr.fraction != 1.f) 4456 | { 4457 | m_pCSPlayer->SetDuckUntilOnGround(false); 4458 | 4459 | if (CanUnduck()) 4460 | { 4461 | FinishUnduck(); 4462 | return; 4463 | } 4464 | } 4465 | } 4466 | } 4467 | 4468 | void CGameMovement::HandleDuckingSpeedCrop() 4469 | { 4470 | // test byte ptr [ecx+0C3Ch], 1 4471 | if (m_bSpeedCropped & 1) 4472 | { 4473 | if (player->GetFlags() & FL_DUCKING) 4474 | { 4475 | if (player->GetGroundEntity() != nullptr) 4476 | { 4477 | mv->m_flForwardMove *= 0.33333334f; 4478 | mv->m_flSideMove *= 0.33333334f; 4479 | mv->m_flUpMove *= 0.33333334f; 4480 | m_bSpeedCropped = true; 4481 | //m_bSpeedCropped |= 1; 4482 | } 4483 | } 4484 | } 4485 | } 4486 | 4487 | void CGameMovement::FinishUnduck() 4488 | { 4489 | Vector newOrigin = mv->_m_vecAbsOrigin; 4490 | 4491 | if (player->GetGroundEntity() != nullptr) 4492 | { 4493 | for (int i = 0; i < 3; ++i) 4494 | newOrigin[i] += (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin[i] - (*g_pGameRules)->GetViewVectors()->m_vHullMin[i]; 4495 | } 4496 | else 4497 | { 4498 | Vector hullSizeNormal = (*g_pGameRules)->GetViewVectors()->m_vHullMax - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4499 | Vector hullSizeDuck = (*g_pGameRules)->GetViewVectors()->m_vDuckHullMax - (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin; 4500 | Vector delta = hullSizeNormal - hullSizeDuck; 4501 | 4502 | newOrigin -= delta; //+= -delta 4503 | } 4504 | 4505 | player->SetDucked(FALSE); 4506 | player->RemoveFlag(FL_DUCKING | FL_ANIMDUCKING); // ~6 4507 | player->SetDucking(FALSE); 4508 | player->SetInDuckJump(false); 4509 | 4510 | Vector viewOffset = GetPlayerViewOffset(false); 4511 | 4512 | player->SetViewOffset(viewOffset); 4513 | 4514 | player->SetDuckTimeMsecs(0); 4515 | 4516 | mv->_m_vecAbsOrigin = newOrigin; 4517 | 4518 | player->ResetLatched(); 4519 | 4520 | CategorizePosition(); 4521 | } 4522 | 4523 | //dangerzone correct 4524 | void CCSGameMovement::FinishUnduck() 4525 | { 4526 | Vector newOrigin = mv->_m_vecAbsOrigin; 4527 | 4528 | if (player->GetGroundEntity() != nullptr || player->GetMoveType() == MOVETYPE_LADDER) 4529 | { 4530 | newOrigin += (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4531 | } 4532 | else 4533 | { 4534 | Vector hullSizeNormal = (*g_pGameRules)->GetViewVectors()->m_vHullMax - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4535 | Vector hullSizeDuck = (*g_pGameRules)->GetViewVectors()->m_vDuckHullMax - (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin; 4536 | Vector delta = (hullSizeNormal - hullSizeDuck) * -0.5f; 4537 | 4538 | newOrigin += delta; 4539 | } 4540 | 4541 | player->RemoveFlag(FL_DUCKING | FL_ANIMDUCKING); 4542 | player->SetDucked(FALSE); 4543 | player->SetDucking(FALSE); 4544 | player->SetDuckTimeMsecs(0); 4545 | 4546 | auto offset = GetPlayerViewOffset(false); 4547 | player->SetViewOffset(offset); 4548 | 4549 | CategorizePosition(); 4550 | 4551 | if (player->GetDuckAmount() > 0.f) 4552 | player->SetDuckAmount(0.f); 4553 | } 4554 | 4555 | void CGameMovement::FinishDuck() 4556 | { 4557 | if (!(player->GetFlags() & FL_DUCKING)) 4558 | { 4559 | player->AddFlag(FL_DUCKING); 4560 | player->SetDucking(FALSE); 4561 | player->SetDucked(TRUE); 4562 | 4563 | Vector viewOffset = GetPlayerViewOffset(true); 4564 | player->SetViewOffset(viewOffset); 4565 | 4566 | if (player->GetGroundEntity() != nullptr) 4567 | { 4568 | Vector origin = mv->_m_vecAbsOrigin; 4569 | 4570 | for (int i = 0; i < 3; ++i) 4571 | origin[i] -= ((*g_pGameRules)->GetViewVectors()->m_vDuckHullMin[i] - (*g_pGameRules)->GetViewVectors()->m_vHullMin[i]); 4572 | 4573 | mv->_m_vecAbsOrigin = origin; 4574 | } 4575 | else 4576 | { 4577 | Vector hullSizeNormal = (*g_pGameRules)->GetViewVectors()->m_vHullMax - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4578 | Vector hullSizeDuck = (*g_pGameRules)->GetViewVectors()->m_vDuckHullMax - (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin; 4579 | Vector delta = hullSizeNormal - hullSizeDuck; 4580 | 4581 | mv->_m_vecAbsOrigin += delta; 4582 | 4583 | player->ResetLatched(); 4584 | } 4585 | 4586 | FixPlayerCrouchStuck(true); 4587 | CategorizePosition(); 4588 | } 4589 | } 4590 | 4591 | //dangerzone correct 4592 | void CCSGameMovement::FinishDuck() 4593 | { 4594 | Vector newOrigin = mv->_m_vecAbsOrigin; 4595 | 4596 | if (player->GetGroundEntity() != nullptr || player->GetMoveType() == MOVETYPE_LADDER || player->GetWaterLevel() >= WL_Waist) 4597 | { 4598 | newOrigin -= (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4599 | } 4600 | else 4601 | { 4602 | Vector hullSizeNormal = (*g_pGameRules)->GetViewVectors()->m_vHullMax - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4603 | Vector hullSizeDuck = (*g_pGameRules)->GetViewVectors()->m_vDuckHullMax - (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin; 4604 | Vector delta = (hullSizeNormal - hullSizeDuck) * -0.5f; 4605 | 4606 | newOrigin += delta; 4607 | } 4608 | 4609 | mv->_m_vecAbsOrigin = newOrigin; 4610 | 4611 | auto offset = GetPlayerViewOffset(true); 4612 | 4613 | player->SetViewOffset(offset); 4614 | 4615 | player->SetDucking(FALSE); 4616 | player->SetDucked(TRUE); 4617 | player->SetLastDuckTime(Interfaces::Globals->curtime); 4618 | player->AddFlag(FL_DUCKING | FL_ANIMDUCKING); 4619 | 4620 | FixPlayerCrouchStuck(true); 4621 | CategorizePosition(); 4622 | 4623 | if (player->GetDuckAmount() != 1.0f) 4624 | player->SetDuckAmount(1.0f); 4625 | } 4626 | 4627 | bool CGameMovement::CanUnduck() 4628 | { 4629 | trace_t tr; 4630 | Vector newOrigin = mv->_m_vecAbsOrigin; 4631 | 4632 | if (player->GetGroundEntity() != nullptr) 4633 | { 4634 | for (int i = 0; i < 3; ++i) 4635 | newOrigin[i] -= ((*g_pGameRules)->GetViewVectors()->m_vDuckHullMin[i] - (*g_pGameRules)->GetViewVectors()->m_vHullMin[i]); 4636 | } 4637 | else 4638 | { 4639 | Vector hullSizeNormal = (*g_pGameRules)->GetViewVectors()->m_vHullMax - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4640 | Vector hullSizeDuck = (*g_pGameRules)->GetViewVectors()->m_vDuckHullMax - (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin; 4641 | Vector delta = hullSizeNormal - hullSizeDuck; 4642 | 4643 | newOrigin -= delta; //+= -delta; 4644 | } 4645 | 4646 | bool duckedBackup = player->GetDucked(); 4647 | player->SetDucked(FALSE); 4648 | TracePlayerBBox(mv->_m_vecAbsOrigin, newOrigin, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 4649 | player->SetDucked(duckedBackup); 4650 | 4651 | return (!tr.startsolid && tr.fraction == 1.f); 4652 | } 4653 | 4654 | //dangerzone correct 4655 | bool CCSGameMovement::CanUnduck() 4656 | { 4657 | if (m_pCSPlayer->GetDuckOverride()) 4658 | return false; 4659 | 4660 | if (player->GetMoveType() == MOVETYPE_NOCLIP) 4661 | return true; 4662 | 4663 | trace_t trace; 4664 | 4665 | Vector newOrigin = mv->_m_vecAbsOrigin; 4666 | 4667 | if (player->GetGroundEntity() != nullptr) 4668 | { 4669 | newOrigin += (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4670 | } 4671 | else 4672 | { 4673 | Vector hullSizeNormal = (*g_pGameRules)->GetViewVectors()->m_vHullMax - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4674 | Vector hullSizeDuck = (*g_pGameRules)->GetViewVectors()->m_vDuckHullMax - (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin; 4675 | Vector delta = (hullSizeNormal - hullSizeDuck) * -0.5f; 4676 | 4677 | newOrigin += delta; 4678 | } 4679 | 4680 | //dangerzone update: 4681 | CTraceFilterForPlayerHeadCollision filter; 4682 | filter.m_pPassEnt1 = (IHandleEntity*)player; 4683 | filter.m_pSkip = (IHandleEntity*)player; 4684 | filter.m_Unknown = 0; 4685 | filter.m_iCollisionGroup = COLLISION_GROUP_PLAYER_MOVEMENT; 4686 | 4687 | UTIL_TraceHull(mv->_m_vecAbsOrigin, newOrigin, (*g_pGameRules)->GetViewVectors()->m_vHullMin, (*g_pGameRules)->GetViewVectors()->m_vHullMax, PlayerSolidMask(), (ITraceFilter*)&filter, trace); 4688 | 4689 | if (trace.startsolid || trace.fraction != 1.f) 4690 | return false; 4691 | 4692 | return true; 4693 | } 4694 | 4695 | //dangerzone correct 4696 | void CGameMovement::UpdateDuckJumpEyeOffset() 4697 | { 4698 | auto duckjumptimesecs = player->GetDuckJumpTimeMsecs(); 4699 | 4700 | if (duckjumptimesecs != 0) 4701 | { 4702 | auto v3 = 1000 - duckjumptimesecs; 4703 | 4704 | if (v3 >= 0) 4705 | { 4706 | if (v3 > 200) 4707 | { 4708 | player->SetDuckJumpTimeMsecs(0); 4709 | SetDuckedEyeOffset(0.f); 4710 | return; 4711 | } 4712 | } 4713 | else 4714 | { 4715 | v3 = 0; 4716 | } 4717 | 4718 | float v4 = 0.f; 4719 | float v5 = (float)v3 * 0.0049999999f; 4720 | 4721 | if (v5 >= 0.f) 4722 | v4 = fminf(v5, 1.f); 4723 | 4724 | SetDuckedEyeOffset((((1.f - v4) * (1.f - v4)) * 3.f) - ((((1.f - v4) * (1.f - v4)) * 2.f) * (1.f - v4))); 4725 | } 4726 | } 4727 | 4728 | bool CGameMovement::CanUnduckJump(trace_t& tr) 4729 | { 4730 | Vector end = mv->_m_vecAbsOrigin; 4731 | end.z -= 36.f; 4732 | 4733 | TracePlayerBBox(mv->_m_vecAbsOrigin, end, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, tr); 4734 | 4735 | if (tr.fraction >= 1.f) 4736 | return false; 4737 | 4738 | end.z = mv->_m_vecAbsOrigin.z - (tr.fraction * 36.f); 4739 | 4740 | bool saveducked = player->GetDucked(); 4741 | 4742 | player->SetDucked(FALSE); 4743 | 4744 | trace_t trace; 4745 | TracePlayerBBox(mv->_m_vecAbsOrigin, end, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace); 4746 | 4747 | player->SetDucked(saveducked); 4748 | 4749 | if (trace.startsolid) 4750 | return false; 4751 | 4752 | return true; 4753 | } 4754 | 4755 | void CGameMovement::StartUnduckJump() 4756 | { 4757 | player->AddFlag(FL_DUCKING); 4758 | player->SetDucked(TRUE); 4759 | player->SetDucking(FALSE); 4760 | 4761 | Vector viewOffset = GetPlayerViewOffset(true); 4762 | player->SetViewOffset(viewOffset); 4763 | 4764 | Vector hullSizeNormal = (*g_pGameRules)->GetViewVectors()->m_vHullMax - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4765 | Vector hullSizeDuck = (*g_pGameRules)->GetViewVectors()->m_vDuckHullMax - (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin; 4766 | Vector delta = hullSizeNormal - hullSizeDuck; 4767 | 4768 | mv->_m_vecAbsOrigin = mv->_m_vecAbsOrigin + delta; 4769 | 4770 | FixPlayerCrouchStuck(true); 4771 | CategorizePosition(); 4772 | } 4773 | 4774 | void CGameMovement::FinishUnduckJump(trace_t& tr) 4775 | { 4776 | Vector newOrigin = mv->_m_vecAbsOrigin; 4777 | 4778 | Vector hullSizeNormal = (*g_pGameRules)->GetViewVectors()->m_vHullMax - (*g_pGameRules)->GetViewVectors()->m_vHullMin; 4779 | Vector hullSizeDuck = (*g_pGameRules)->GetViewVectors()->m_vDuckHullMax - (*g_pGameRules)->GetViewVectors()->m_vDuckHullMin; 4780 | Vector delta = hullSizeNormal - hullSizeDuck; 4781 | 4782 | float storedDeltaZ = delta.z; 4783 | delta.z *= tr.fraction; 4784 | storedDeltaZ -= delta.z; 4785 | 4786 | player->RemoveFlag(FL_DUCKING | FL_ANIMDUCKING); // ~6 4787 | player->SetDucked(FALSE); 4788 | player->SetDucking(FALSE); 4789 | player->SetInDuckJump(false); 4790 | player->SetDuckTimeMsecs(0); 4791 | player->SetDuckJumpTimeMsecs(0); 4792 | player->SetJumpTimeMsecs(0); 4793 | 4794 | Vector viewOffset = GetPlayerViewOffset(false); 4795 | viewOffset.z -= storedDeltaZ; 4796 | 4797 | player->SetViewOffset(viewOffset); 4798 | 4799 | newOrigin -= delta; 4800 | mv->_m_vecAbsOrigin = newOrigin; 4801 | 4802 | CategorizePosition(); 4803 | } 4804 | 4805 | void CGameMovement::SetDuckedEyeOffset(float duckFraction) 4806 | { 4807 | float newDuckFraction = ((duckFraction * duckFraction) * 3.f) - (((duckFraction * duckFraction) * 2.f) * duckFraction); 4808 | 4809 | Vector mins_duck = GetPlayerMins(true); 4810 | Vector mins_stand = GetPlayerMins(false); 4811 | 4812 | float fMore = (mins_duck.z - mins_stand.z); 4813 | 4814 | Vector view_duck = GetPlayerViewOffset(true); 4815 | Vector view_stand = GetPlayerViewOffset(false); 4816 | 4817 | Vector temp = player->GetViewOffset(); 4818 | temp.z = ((view_duck.z - fMore) * newDuckFraction) + ((1.f - newDuckFraction) * view_stand.z); 4819 | 4820 | player->SetViewOffset(temp); 4821 | } 4822 | 4823 | void CGameMovement::FixPlayerCrouchStuck(bool upward) 4824 | { 4825 | bool direction = (upward != 0); 4826 | 4827 | trace_t trace; 4828 | if (TestPlayerPosition(mv->_m_vecAbsOrigin, COLLISION_GROUP_PLAYER_MOVEMENT, trace) != -1) 4829 | { 4830 | Vector temp = mv->_m_vecAbsOrigin; 4831 | 4832 | for (int i = 0; i < 36; ++i) 4833 | { 4834 | Vector orig = mv->_m_vecAbsOrigin; 4835 | orig.z += direction; 4836 | mv->_m_vecAbsOrigin = orig; 4837 | 4838 | if (TestPlayerPosition(mv->_m_vecAbsOrigin, COLLISION_GROUP_PLAYER_MOVEMENT, trace) == -1) 4839 | return; 4840 | } 4841 | 4842 | mv->_m_vecAbsOrigin = temp; 4843 | } 4844 | } 4845 | 4846 | CreateStuckTableFn oCreateStuckTable; 4847 | Vector** rgv3tStuckTable; //[54]; 4848 | 4849 | int GetRandomStuckOffsets(CBasePlayer* pPlayer, Vector& offset) 4850 | { 4851 | // Last time we did a full 4852 | int idx; 4853 | idx = pPlayer->GetStuckLast(); 4854 | pPlayer->SetStuckLast(pPlayer->GetStuckLast() + 1); 4855 | 4856 | VectorCopy(*rgv3tStuckTable[idx % 54], offset); 4857 | 4858 | return (idx % 54); 4859 | } 4860 | 4861 | //----------------------------------------------------------------------------- 4862 | // Purpose: 4863 | // Input : nIndex - 4864 | // server - 4865 | //----------------------------------------------------------------------------- 4866 | void ResetStuckOffsets(CBasePlayer* pPlayer) 4867 | { 4868 | pPlayer->SetStuckLast(0); 4869 | } 4870 | 4871 | #define CHECKSTUCK_MINTIME 0.05f 4872 | //----------------------------------------------------------------------------- 4873 | // Purpose: 4874 | // Input : &input - 4875 | // Output : int 4876 | //----------------------------------------------------------------------------- 4877 | int CGameMovement::CheckStuck(void) 4878 | { 4879 | //#if defined( CLIENT_DLL ) 4880 | // Don't bother trying to jitter the player on the client, the server position will fix any true "stuck" issues and 4881 | // we send player origins with full precision anyway so getting stuck due to epsilon issues shouldn't occur... 4882 | // The potential bad effect would be interacting with NPCs with a lot of lag might feel more warpy w/o the unstuck code running 4883 | if (!cl_pred_checkstuck.GetVar()->GetBool()) 4884 | return 0; 4885 | //#endif 4886 | 4887 | Vector base; 4888 | Vector offset; 4889 | Vector test; 4890 | EntityHandle_t hitent; 4891 | int idx; 4892 | float fTime; 4893 | trace_t traceresult; 4894 | 4895 | oCreateStuckTable(); 4896 | 4897 | // player->SetStuckCharacter( NULL ); 4898 | 4899 | m_bInStuckTest = true; 4900 | hitent = TestPlayerPosition(mv->GetAbsOrigin(), COLLISION_GROUP_PLAYER_MOVEMENT, traceresult); 4901 | m_bInStuckTest = false; 4902 | if (hitent == INVALID_ENTITY_HANDLE) 4903 | { 4904 | ResetStuckOffsets(player); 4905 | return 0; 4906 | } 4907 | 4908 | // Deal with stuckness... 4909 | #if 0 4910 | #ifndef DEDICATED 4911 | if (developer.GetVar()->GetBool()) 4912 | { 4913 | bool isServer = player->IsServer(); 4914 | engine->Con_NPrintf(isServer, "%s stuck on object %i/%s", 4915 | isServer ? "server" : "client", 4916 | hitent.GetEntryIndex(), MoveHelper()->GetName(hitent)); 4917 | } 4918 | #endif 4919 | #endif 4920 | 4921 | VectorCopy(mv->GetAbsOrigin(), base); 4922 | 4923 | // 4924 | // Deal with precision error in network. 4925 | // 4926 | // World or BSP model 4927 | if (!player->IsServer()) 4928 | { 4929 | if ((*Interfaces::MoveHelperClient)->IsWorldEntity(hitent)) 4930 | { 4931 | int nReps = 0; 4932 | ResetStuckOffsets(player); 4933 | do 4934 | { 4935 | GetRandomStuckOffsets(player, offset); 4936 | VectorAdd(base, offset, test); 4937 | 4938 | if (TestPlayerPosition(test, COLLISION_GROUP_PLAYER_MOVEMENT, traceresult) == INVALID_ENTITY_HANDLE) 4939 | { 4940 | ResetStuckOffsets(player); 4941 | mv->SetAbsOrigin(test); 4942 | return 0; 4943 | } 4944 | nReps++; 4945 | } while (nReps < 54); 4946 | } 4947 | } 4948 | 4949 | // Only an issue on the client. 4950 | idx = player->IsServer() ? 0 : 1; 4951 | 4952 | static DWORD Plat_FloatTime_Adr = 0; 4953 | if (Plat_FloatTime_Adr == 0) 4954 | { 4955 | //decrypts(0) 4956 | Plat_FloatTime_Adr = (DWORD)GetProcAddress((HMODULE)Tier0Handle, XorStr("Plat_FloatTime")); 4957 | //encrypts(0) 4958 | } 4959 | 4960 | fTime = ((double(*)())Plat_FloatTime_Adr)(); 4961 | 4962 | // Too soon? 4963 | if (m_flStuckCheckTime[player->entindex()][idx] >= fTime - CHECKSTUCK_MINTIME) 4964 | { 4965 | return 1; 4966 | } 4967 | m_flStuckCheckTime[player->entindex()][idx] = fTime; 4968 | 4969 | (*Interfaces::MoveHelperClient)->AddToTouched(traceresult, mv->m_vecVelocity_); 4970 | m_bInStuckTest = true; 4971 | GetRandomStuckOffsets(player, offset); 4972 | VectorAdd(base, offset, test); 4973 | 4974 | if (TestPlayerPosition(test, COLLISION_GROUP_PLAYER_MOVEMENT, traceresult) == INVALID_ENTITY_HANDLE) 4975 | { 4976 | ResetStuckOffsets(player); 4977 | mv->SetAbsOrigin(test); 4978 | return 0; 4979 | } 4980 | m_bInStuckTest = false; 4981 | 4982 | return 1; 4983 | } 4984 | 4985 | void CGameMovement::CategorizeGroundSurface(trace_t& tr) 4986 | { 4987 | IPhysicsSurfaceProps* physProps = (*Interfaces::MoveHelperClient)->GetSurfaceProps(); 4988 | 4989 | // mov [ecx+359Ch], edx 4990 | player->SetSurfaceProps(tr.surface.surfaceProps); 4991 | 4992 | player->SetSurfaceData(physProps->GetSurfaceData(player->GetSurfaceProps())); 4993 | 4994 | physProps->GetPhysicsProperties(player->GetSurfaceProps(), 0, 0, player->GetSurfaceFrictionAdr(), 0); 4995 | 4996 | player->SetSurfaceFriction(player->GetSurfaceFriction() * 1.25f); 4997 | 4998 | if (player->GetSurfaceFriction() > 1.f) 4999 | player->SetSurfaceFriction(1.f); 5000 | 5001 | // mov [ecx+35A4h], al 5002 | player->SetTextureType(player->GetSurfaceData()->game.gamematerial); 5003 | } 5004 | 5005 | bool CGameMovement::InWater() 5006 | { 5007 | return (player->GetWaterLevel() > 1); 5008 | } 5009 | 5010 | CBaseHandle CGameMovement::TestPlayerPosition(const Vector& pos, int collisionGroup, trace_t& pm) 5011 | { 5012 | ++m_nTraceCount; 5013 | 5014 | Vector maxs = GetPlayerMaxs(); 5015 | Vector mins = GetPlayerMins(); 5016 | 5017 | Ray_t ray; 5018 | ray.Init(pos, pos, mins, maxs); 5019 | 5020 | ITraceFilter* filter = LockTraceFilter(collisionGroup); 5021 | UTIL_TraceRay(ray, PlayerSolidMask(), filter, &pm); 5022 | UnlockTraceFilter(filter); 5023 | 5024 | if ((pm.contents & PlayerSolidMask()) && pm.m_pEnt != nullptr) 5025 | { 5026 | // v11 = *(*(*v10 + 8))(); 5027 | return pm.m_pEnt->GetRefEHandle(); 5028 | } 5029 | 5030 | return (CBaseHandle)-1; 5031 | } 5032 | 5033 | void CGameMovement::SetGroundEntity(trace_t* pm) 5034 | { 5035 | CBaseEntity *newGround = nullptr, *oldGround = nullptr; 5036 | 5037 | if (pm != nullptr) 5038 | newGround = pm->m_pEnt; 5039 | else 5040 | newGround = nullptr; 5041 | 5042 | if (player->GetGroundEntity() == nullptr) 5043 | oldGround = nullptr; 5044 | else 5045 | oldGround = player->GetGroundEntity(); 5046 | 5047 | Vector baseVelocity = player->GetBaseVelocity(); 5048 | 5049 | if (oldGround) 5050 | { 5051 | if (!newGround) 5052 | { 5053 | Vector* vel = oldGround->GetAbsVelocity(); 5054 | // v13 = *(v17 + 0x94) + *&v18; 5055 | baseVelocity += *vel; 5056 | baseVelocity.z = vel->z; 5057 | } 5058 | } 5059 | else if (newGround) 5060 | { 5061 | Vector* vel = newGround->GetAbsVelocity(); 5062 | baseVelocity -= *vel; 5063 | baseVelocity.z = vel->z; 5064 | } 5065 | 5066 | player->SetBaseVelocity(baseVelocity); 5067 | player->SetGroundEntity(newGround); 5068 | 5069 | if (newGround != nullptr) 5070 | { 5071 | CategorizeGroundSurface(*pm); 5072 | player->SetWaterJumpTime(0.f); 5073 | 5074 | if (pm->DidHitWorld()) 5075 | (*Interfaces::MoveHelperClient)->AddToTouched(*pm, mv->m_vecVelocity_); 5076 | 5077 | if (player->GetMoveType() != MOVETYPE_NOCLIP) 5078 | mv->m_vecVelocity_.z = 0.f; 5079 | } 5080 | } 5081 | 5082 | void CGameMovement::StepMove(Vector& vecDestination, trace_t& trace) 5083 | { 5084 | // 5085 | // Save the move position and velocity in case we need to put it back later. 5086 | // 5087 | Vector vecPos, vecVel; 5088 | VectorCopy(mv->GetAbsOrigin(), vecPos); 5089 | VectorCopy(mv->m_vecVelocity_, vecVel); 5090 | 5091 | // 5092 | // First try walking straight to where they want to go. 5093 | // 5094 | Vector vecEndPos; 5095 | VectorCopy(vecDestination, vecEndPos); 5096 | TryPlayerMove(&vecEndPos, &trace); 5097 | 5098 | // 5099 | // mv now contains where they ended up if they tried to walk straight there. 5100 | // Save those results for use later. 5101 | // 5102 | Vector vecDownPos, vecDownVel; 5103 | VectorCopy(mv->GetAbsOrigin(), vecDownPos); 5104 | VectorCopy(mv->m_vecVelocity_, vecDownVel); 5105 | 5106 | // 5107 | // Reset original values to try some other things. 5108 | // 5109 | mv->_m_vecAbsOrigin = vecPos; 5110 | VectorCopy(vecVel, mv->m_vecVelocity_); 5111 | 5112 | // 5113 | // Move up a stair height. 5114 | // Slide forward at the same velocity but from the higher position. 5115 | // 5116 | VectorCopy(mv->GetAbsOrigin(), vecEndPos); 5117 | if (player->GetAllowAutoMovement()) 5118 | vecEndPos.z += player->GetStepSize() + 0.03125f; 5119 | 5120 | // Only step up as high as we have headroom to do so. 5121 | TracePlayerBBox(mv->_m_vecAbsOrigin, vecEndPos, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace); 5122 | 5123 | if (!trace.startsolid && !trace.allsolid) 5124 | mv->_m_vecAbsOrigin = trace.endpos; 5125 | 5126 | TryPlayerMove(); 5127 | 5128 | // 5129 | // Move down a stair (attempt to). 5130 | // Slide forward at the same velocity from the lower position. 5131 | // 5132 | vecEndPos = mv->_m_vecAbsOrigin; 5133 | 5134 | if (player->GetAllowAutoMovement()) 5135 | vecEndPos.z -= player->GetStepSize() + 0.03125f; 5136 | 5137 | TracePlayerBBox(mv->_m_vecAbsOrigin, vecEndPos, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace); 5138 | 5139 | // If we are not on the ground any more then use the original movement attempt. 5140 | if (trace.plane.normal.z < 0.7f) 5141 | { 5142 | mv->_m_vecAbsOrigin = vecDownPos; 5143 | mv->m_vecVelocity_ = vecDownVel; 5144 | 5145 | float dist = mv->_m_vecAbsOrigin.z - vecPos.z; 5146 | 5147 | if (dist > 0.f) 5148 | mv->m_outStepHeight += dist; 5149 | 5150 | return; 5151 | } 5152 | 5153 | // If the trace ended up in empty space, copy the end over to the origin. 5154 | if (!trace.startsolid && !trace.allsolid) 5155 | mv->_m_vecAbsOrigin = trace.endpos; 5156 | 5157 | // Copy this origin to up. 5158 | Vector vecUpPos = mv->_m_vecAbsOrigin; 5159 | 5160 | // decide which one went farther 5161 | float flDownDist = (vecDownPos.x - vecPos.x) * (vecDownPos.x - vecPos.x) + (vecDownPos.y - vecPos.y) * (vecDownPos.y - vecPos.y); 5162 | float flUpDist = (vecUpPos.x - vecPos.x) * (vecUpPos.x - vecPos.x) + (vecUpPos.y - vecPos.y) * (vecUpPos.y - vecPos.y); 5163 | 5164 | if (flDownDist > flUpDist) 5165 | { 5166 | mv->_m_vecAbsOrigin = vecDownPos; 5167 | mv->m_vecVelocity_ = vecDownVel; 5168 | } 5169 | else 5170 | { 5171 | // copy z value from slide move 5172 | mv->m_vecVelocity_.z = vecDownVel.z; 5173 | } 5174 | 5175 | float dist = mv->_m_vecAbsOrigin.z - vecPos.z; 5176 | 5177 | if (dist > 0.f) 5178 | mv->m_outStepHeight += dist; 5179 | } 5180 | 5181 | ITraceFilter* CGameMovement::LockTraceFilter(int collisionGroup) 5182 | { 5183 | // mov edx, s_nTraceFilterCount // s_nTraceFilterCount = 14F83F9C 5184 | // cmp edx, 8 5185 | if (*s_nTraceFilterCount >= 8) 5186 | return nullptr; 5187 | 5188 | // lea esi, s_TraceFilter[eax*4] ; // s_TraceFilter = 10AA5610 5189 | 5190 | CTraceFilterSkipTwoEntities_CSGO* filter = (CTraceFilterSkipTwoEntities_CSGO*)((DWORD)s_TraceFilter + sizeof(CTraceFilterSkipTwoEntities_CSGO) * *s_nTraceFilterCount); 5191 | *s_nTraceFilterCount = *s_nTraceFilterCount + 1; 5192 | 5193 | filter->SetPassEntity(mv->m_nPlayerHandle.Get()); 5194 | filter->SetCollisionGroup(collisionGroup); 5195 | 5196 | return (ITraceFilter*)filter; 5197 | } 5198 | 5199 | void CGameMovement::UnlockTraceFilter(ITraceFilter*& filter) 5200 | { 5201 | *s_nTraceFilterCount = *s_nTraceFilterCount - 1; 5202 | filter = NULL; 5203 | } 5204 | 5205 | bool CGameMovement::GameHasLadders() 5206 | { 5207 | return true; 5208 | } 5209 | 5210 | void CCSGameMovement::PreventBunnyJumping() 5211 | { 5212 | // eax+322Ch 5213 | float adjustedmaxspeed = player->GetMaxSpeed() * 1.1f; 5214 | 5215 | if (adjustedmaxspeed > 0.f) 5216 | { 5217 | float len = sqrtf(((mv->m_vecVelocity_.x * mv->m_vecVelocity_.x) + (mv->m_vecVelocity_.y * mv->m_vecVelocity_.y)) + (mv->m_vecVelocity_.z * mv->m_vecVelocity_.z)); 5218 | 5219 | if (adjustedmaxspeed < len) 5220 | { 5221 | float ratio = adjustedmaxspeed / len; 5222 | 5223 | mv->m_vecVelocity_ *= ratio; 5224 | } 5225 | } 5226 | } 5227 | 5228 | void CCSGameMovement::DecayAimPunchAngle() 5229 | { 5230 | // mov xmm0, qword ptr [edx+301Ch] 5231 | QAngle aimPunchAng = m_pCSPlayer->GetPunch(); 5232 | // mov xmm0, qword ptr [edx+3028h] 5233 | Vector aimPunchAngVel = m_pCSPlayer->GetPunchVel(); 5234 | 5235 | float v26 = Interfaces::Globals->interval_per_tick * weapon_recoil_decay2_lin.GetVar()->GetFloat(); 5236 | 5237 | float v5 = Interfaces::Globals->interval_per_tick; 5238 | v5 *= weapon_recoil_decay2_exp.GetVar()->GetFloat(); 5239 | 5240 | float v6 = expf(-v5); 5241 | 5242 | QAngle tmp = aimPunchAng * v6; 5243 | 5244 | float v9 = sqrtf((tmp.x * tmp.x) + (tmp.y * tmp.y) + (tmp.z * tmp.z)); 5245 | 5246 | Vector v10; 5247 | if (v9 <= v26) 5248 | { 5249 | v10.x = 0.f; 5250 | v10.y = 0.f; 5251 | v10.z = 0.f; 5252 | } 5253 | else 5254 | { 5255 | v10.x = tmp.x * (1.f - (v26 / v9)); 5256 | v10.y = tmp.y * (1.f - (v26 / v9)); 5257 | v10.z = tmp.z * (1.f - (v26 / v9)); 5258 | } 5259 | 5260 | Vector v11 = v10 + ((aimPunchAngVel * Interfaces::Globals->interval_per_tick) * 0.5f); 5261 | 5262 | float decayamount = Interfaces::Globals->interval_per_tick * weapon_recoil_vel_decay.GetVar()->GetFloat(); 5263 | decayamount = expf(-decayamount); 5264 | 5265 | Vector newpunchvel = aimPunchAngVel * decayamount; 5266 | 5267 | Vector newaimpunch = ((newpunchvel * Interfaces::Globals->interval_per_tick) * 0.5f) + v11; 5268 | 5269 | if (newaimpunch.x != aimPunchAng.x || newaimpunch.y != aimPunchAng.y || newaimpunch.z != aimPunchAng.z) 5270 | { 5271 | player->SetPunch(QAngle(newaimpunch.x, newaimpunch.y, newaimpunch.z)); 5272 | } 5273 | 5274 | if (newpunchvel.x != aimPunchAngVel.x || newpunchvel.y != aimPunchAngVel.y || newpunchvel.z != aimPunchAngVel.z) 5275 | { 5276 | player->SetPunchVel(newpunchvel); 5277 | } 5278 | } -------------------------------------------------------------------------------- /IGameMovement.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "CreateMove.h" 3 | #include "VPhysics.h" 4 | #include "CBaseHandle.h" 5 | #include "utlvectorsimple.h" 6 | #include "utlvector.h" 7 | #define MAX_CLIMB_SPEED 200 8 | 9 | //----------------------------------------------------------------------------- 10 | // An entity identifier that works in both game + client dlls 11 | //----------------------------------------------------------------------------- 12 | 13 | typedef CBaseHandle EntityHandle_t; 14 | 15 | 16 | #define INVALID_ENTITY_HANDLE INVALID_EHANDLE_INDEX 17 | #define PRINTF_FORMAT_STRING _Printf_format_string_ 18 | enum PLAYER_ANIM; 19 | 20 | #include "soundflags.h" 21 | 22 | class CMoveData 23 | { 24 | //public: 25 | // char pad_0x00[183]; 26 | public: 27 | bool m_bFirstRunOfFunctions : 1; 28 | bool m_bGameCodeMovedPlayer : 1; 29 | bool m_bNoAirControl : 1; 30 | 31 | EntityHandle_t m_nPlayerHandle; // edict index on server, client entity handle on client 32 | 33 | int m_nImpulseCommand; // Impulse command issued. 34 | QAngle m_vecViewAngles; // Command view angles (local space) 35 | QAngle m_vecAbsViewAngles; // Command view angles (world space) 36 | int m_nButtons; // Attack buttons. 37 | int m_nOldButtons; // From host_client->oldbuttons; 38 | float m_flForwardMove; 39 | float m_flSideMove; 40 | float m_flUpMove; 41 | 42 | float _m_flMaxSpeed; 43 | float m_flClientMaxSpeed; 44 | 45 | // Variables from the player edict (sv_player) or entvars on the client. 46 | // These are copied in here before calling and copied out after calling. 47 | Vector m_vecVelocity_; // edict::velocity // Current movement direction. 48 | Vector m_vecOldVelocity; 49 | float somefloat; 50 | QAngle m_vecAngles; // edict::angles 51 | QAngle m_vecOldAngles; 52 | 53 | // Output only 54 | float m_outStepHeight; // how much you climbed this move 55 | Vector m_outWishVel; // This is where you tried 56 | Vector m_outJumpVel; // This is your jump velocity 57 | 58 | // Movement constraints (radius 0 means no constraint) 59 | Vector m_vecConstraintCenter; 60 | float m_flConstraintRadius; 61 | float m_flConstraintWidth; 62 | float m_flConstraintSpeedFactor; 63 | bool m_bConstraintPastRadius; ///< If no, do no constraining past Radius. If yes, cap them to SpeedFactor past radius 64 | 65 | void SetAbsOrigin(const Vector &vec); 66 | const Vector &GetAbsOrigin() const; 67 | 68 | public: 69 | Vector _m_vecAbsOrigin; // edict::origin 70 | 71 | }; 72 | 73 | //----------------------------------------------------------------------------- 74 | // Functions the engine provides to IGameMovement to assist in its movement. 75 | //----------------------------------------------------------------------------- 76 | 77 | abstract_class IMoveHelper 78 | { 79 | public: 80 | // Call this to set the singleton 81 | static IMoveHelper* GetSingleton() { return sm_pSingleton; } 82 | 83 | // Methods associated with a particular entity 84 | virtual char const* GetName(EntityHandle_t handle) const = 0; 85 | 86 | // sets the entity being moved 87 | virtual void SetHost(CBaseEntity *host) = 0; 88 | 89 | // Adds the trace result to touch list, if contact is not already in list. 90 | virtual void ResetTouchList(void) = 0; 91 | virtual bool AddToTouched(const CGameTrace& tr, const Vector& impactvelocity) = 0; 92 | virtual void ProcessImpacts(void) = 0; 93 | 94 | // Numbered line printf 95 | virtual void Con_NPrintf(int idx, char const* fmt, ...) = 0; 96 | 97 | // These have separate server vs client impementations 98 | virtual void StartSound(const Vector& origin, int channel, char const* sample, float volume, soundlevel_t soundlevel, int fFlags, int pitch) = 0; 99 | virtual void StartSound(const Vector& origin, const char *soundname) = 0; 100 | virtual void PlaybackEventFull(int flags, int clientindex, unsigned short eventindex, float delay, Vector& origin, Vector& angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2) = 0; 101 | 102 | // Apply falling damage to m_pHostPlayer based on m_pHostPlayer->m_flFallVelocity. 103 | virtual bool PlayerFallingDamage(void) = 0; 104 | 105 | // Apply falling damage to m_pHostPlayer based on m_pHostPlayer->m_flFallVelocity. 106 | virtual void PlayerSetAnimation(PLAYER_ANIM playerAnim) = 0; 107 | 108 | virtual IPhysicsSurfaceProps *GetSurfaceProps(void) = 0; 109 | 110 | virtual bool IsWorldEntity(const CBaseHandle &handle) = 0; 111 | 112 | protected: 113 | // Inherited classes can call this to set the singleton 114 | static void SetSingleton(IMoveHelper* pMoveHelper) { sm_pSingleton = pMoveHelper; } 115 | 116 | // Clients shouldn't call delete directly 117 | virtual ~IMoveHelper() {} 118 | 119 | // The global instance 120 | static IMoveHelper* sm_pSingleton; 121 | }; 122 | 123 | class CMoveHelperClient : public IMoveHelper 124 | { 125 | public: 126 | CMoveHelperClient(void); 127 | virtual ~CMoveHelperClient(void); 128 | 129 | char const* GetName(EntityHandle_t handle) const; 130 | 131 | // touch lists 132 | virtual void ResetTouchList(void); 133 | virtual bool AddToTouched(const trace_t& tr, const Vector& impactvelocity); 134 | virtual void ProcessImpacts(void); 135 | 136 | // Numbered line printf 137 | virtual void Con_NPrintf(int idx, char const* fmt, ...); 138 | 139 | virtual bool PlayerFallingDamage(void); 140 | virtual void PlayerSetAnimation(PLAYER_ANIM eAnim); 141 | 142 | // These have separate server vs client impementations 143 | virtual void StartSound(const Vector& origin, int channel, char const* sample, float volume, soundlevel_t soundlevel, int fFlags, int pitch); 144 | virtual void StartSound(const Vector& origin, const char *soundname); 145 | virtual void PlaybackEventFull(int flags, int clientindex, unsigned short eventindex, float delay, Vector& origin, Vector& angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2); 146 | virtual IPhysicsSurfaceProps *GetSurfaceProps(void); 147 | 148 | virtual bool IsWorldEntity(const CBaseHandle &handle); 149 | 150 | void SetHost(CBaseEntity *host); 151 | 152 | private: 153 | // results, tallied on client and server, but only used by server to run SV_Impact. 154 | // we store off our velocity in the trace_t structure so that we can determine results 155 | // of shoving boxes etc. around. 156 | struct touchlist_t 157 | { 158 | Vector deltavelocity; 159 | trace_t trace; 160 | 161 | touchlist_t() {} 162 | 163 | private: 164 | touchlist_t(const touchlist_t &src); 165 | }; 166 | 167 | CUtlVector m_TouchList; 168 | 169 | CBaseEntity* m_pHost; 170 | }; 171 | 172 | //----------------------------------------------------------------------------- 173 | // Purpose: The basic player movement interface 174 | //----------------------------------------------------------------------------- 175 | 176 | class IGameMovement 177 | { 178 | public: 179 | virtual ~IGameMovement(void) {} 180 | 181 | // Process the current movement command 182 | virtual void ProcessMovement(CBasePlayer *pPlayer, CMoveData *pMove) = 0; 183 | virtual void Reset(void) = 0; 184 | virtual void StartTrackPredictionErrors(CBasePlayer *pPlayer) = 0; 185 | virtual void FinishTrackPredictionErrors(CBasePlayer *pPlayer) = 0; 186 | virtual void DiffPrint(char const *fmt, ...) = 0; 187 | 188 | // Allows other parts of the engine to find out the normal and ducked player bbox sizes 189 | virtual Vector const& GetPlayerMins(bool ducked) const = 0; 190 | virtual Vector const& GetPlayerMaxs(bool ducked) const = 0; 191 | virtual Vector const& GetPlayerViewOffset(bool ducked) const = 0; 192 | 193 | virtual bool IsMovingPlayerStuck(void) const = 0; 194 | virtual CBasePlayer *GetMovingPlayer(void) const = 0; 195 | virtual void UnblockPusher(CBasePlayer *pPlayer, CBaseEntity *pPusher) = 0; 196 | 197 | virtual void SetupMovementBounds(CMoveData *pMove) = 0; 198 | }; 199 | 200 | 201 | class CGameMovement : public IGameMovement 202 | { 203 | public: 204 | //DECLARE_CLASS_NOBASE(CGameMovement); 205 | 206 | //CGameMovement(void); 207 | //virtual ~CGameMovement(void); 208 | 209 | CGameMovement(void); 210 | virtual ~CGameMovement(void); 211 | virtual void ProcessMovement(CBasePlayer *pPlayer, CMoveData *pMove); // 1 212 | virtual void Reset();// 2 213 | virtual void StartTrackPredictionErrors(CBasePlayer* pPlayer); // 3 214 | virtual void FinishTrackPredictionErrors(CBasePlayer* pPlayer); // 4 215 | virtual void DiffPrint(char const *fmt, ...); // 5 216 | virtual const Vector& GetPlayerMins(bool ducked) const; // 6 217 | virtual const Vector& GetPlayerMaxs(bool ducked) const; // 7 218 | virtual const Vector& GetPlayerViewOffset(bool ducked) const; // 8 219 | virtual bool IsMovingPlayerStuck() const; // 9 220 | virtual CBasePlayer* GetMovingPlayer() const; // 10 221 | virtual void UnblockPusher(CBasePlayer *pPlayer, CBaseEntity *pPusher); // 11 222 | virtual void SetupMovementBounds(CMoveData* moveData); // 12 223 | virtual Vector GetPlayerMins(); // 13 224 | virtual Vector GetPlayerMaxs(); // 14 225 | virtual void TracePlayerBBox(const Vector& rayStart, const Vector& rayEnd, int fMask, int collisionGroup, trace_t& tracePtr); // 15 226 | virtual unsigned int PlayerSolidMask(bool brushOnly = false, CBasePlayer* testPlayer = nullptr); // 16 227 | virtual void PlayerMove(); // 17 228 | virtual float CalcRoll(const QAngle& angles, const Vector& velocity, float rollangle, float rollspeed); // 18 229 | virtual void DecayViewPunchAngle(); // 19 230 | virtual void CheckWaterJump(); // 20 231 | virtual void WaterMove(); // 21 232 | virtual void SlimeMove(); //22 233 | virtual void WaterJump(); // 23 234 | virtual void Friction(); // 24 235 | virtual void AirAccelerate(Vector& wishdir, float wishspeed, float accel); // 25 236 | virtual void AirMove(); // 26 237 | virtual bool CanAccelerate(); // 27 238 | virtual void Accelerate(Vector& wishdir, float wishspeed, float accel); // 28 239 | virtual void WalkMove(); // 29 240 | virtual void StayOnGround(); // 30 241 | virtual void FullWalkMove(); // 31 242 | virtual void OnJump(float stamina); // 32 243 | virtual void nullsub3(); // 33 244 | virtual void OnLand(float flFallVelocity); // 34 245 | bool CheckInterval(IntervalType_t type); 246 | virtual int GetCheckInterval(IntervalType_t type); // 35 247 | virtual void StartGravity(); // 36 248 | virtual void FinishGravity(); // 37 249 | virtual void AddGravity(); // 38 250 | virtual bool CheckJumpButton(); // 39 251 | virtual void FullTossMove(); // 40 252 | virtual void FullLadderMove(); // 41 253 | virtual int TryPlayerMove(Vector *pFirstDest = NULL, trace_t *pFirstTrace = NULL); // 42 254 | virtual bool LadderMove(); // 43 255 | virtual bool OnLadder(trace_t& pm); // 44 256 | virtual float LadderDistance(); // 45 257 | virtual unsigned int LadderMask(); // 46 258 | virtual float ClimbSpeed(); // 47 259 | virtual float LadderLateralMultiplier(); // 48 260 | void CheckVelocity(void); 261 | virtual int ClipVelocity(Vector& in, Vector& normal, Vector& out, float overbounce); // 49 262 | virtual bool CheckWater(); // 50 263 | virtual void GetWaterCheckPosition(int waterLevel, Vector* pos); // 51 264 | virtual void CategorizePosition(); // 52 265 | virtual void CheckParameters(); // 53 266 | virtual void ReduceTimers(); // 54 267 | virtual void CheckFalling(); // 55 268 | virtual void PlayerRoughLandingEffects(float fVol); // 56 269 | virtual void Duck();// 57 270 | virtual void HandleDuckingSpeedCrop(); //58 271 | virtual void FinishUnduck(); //59 272 | virtual void FinishDuck(); // 60 273 | virtual bool CanUnduck(); // 61 274 | virtual void UpdateDuckJumpEyeOffset(); // 62 275 | virtual bool CanUnduckJump(trace_t& tr); // 63 276 | virtual void StartUnduckJump(); // 64 277 | virtual void FinishUnduckJump(trace_t& tr); // 65 278 | virtual void SetDuckedEyeOffset(float duckFraction); // 66 279 | virtual void FixPlayerCrouchStuck(bool upward); // 67 280 | virtual void CategorizeGroundSurface(trace_t& tr); // 68 281 | virtual bool InWater(); // 69 282 | virtual CBaseHandle TestPlayerPosition(const Vector& pos, int collisionGroup, trace_t& pm); // 70 283 | virtual void SetGroundEntity(trace_t* pm); // 71 284 | virtual void StepMove(Vector& vecDestination, trace_t &trace); // 72 285 | virtual ITraceFilter* LockTraceFilter(int collisionGroup); // 73 286 | virtual void UnlockTraceFilter(ITraceFilter* &filter); // 74 287 | virtual bool GameHasLadders(); // 75 288 | void PerformFlyCollisionResolution(trace_t &pm, Vector &move); 289 | void PushEntity(Vector& push, trace_t *pTrace); 290 | void ResetGetWaterContentsForPointCache(); 291 | int GetWaterContentsForPointCached(const Vector &point, int slot); 292 | float ComputeConstraintSpeedFactor(void); 293 | int CheckStuck(void); 294 | void FullNoClipMove(float factor, float maxacceleration); 295 | void FullObserverMove(void); 296 | 297 | enum 298 | { 299 | // eyes, waist, feet points (since they are all deterministic 300 | MAX_PC_CACHE_SLOTS = 3, 301 | }; 302 | 303 | CBasePlayer *player; //4 304 | CMoveData *mv; //8 305 | int m_nOldWaterLevel; //12 306 | float m_flWaterEntryTime; //16 307 | int m_nOnLadder; //20 308 | Vector m_vecForward; //24 309 | Vector m_vecRight; //36 310 | Vector m_vecUp; //48 311 | int m_CachedGetPointContents[MAX_PLAYERS][MAX_PC_CACHE_SLOTS]; 312 | Vector m_CachedGetPointContentsPoint[MAX_PLAYERS][MAX_PC_CACHE_SLOTS]; 313 | BOOL m_bSpeedCropped; //3132 314 | bool m_bProcessingMovement; //3136 315 | bool m_bInStuckTest; //3137 316 | float m_flStuckCheckTime[MAX_PLAYERS + 1][2]; //3138 317 | ITraceListData *m_pTraceListData; //3660 318 | int m_nTraceCount; //3664 319 | }; 320 | 321 | class CCSGameMovement : public CGameMovement 322 | { 323 | public: 324 | CCSGameMovement(); 325 | 326 | virtual void ProcessMovement(CBasePlayer *basePlayer, CMoveData* moveData); // 1 327 | // CGameMovement::Reset // 2 328 | // CGameMovement::StartTrackPredictionErrors(); // 3 329 | // CGameMovement::FinishTrackPredictionErrors(); // 4 330 | virtual void DiffPrint(char const *fmt, ...); // 5 331 | // CGameMovement::GetPlayerMins(bool ducked) // 6 332 | // CGameMovement::GetPlayerMaxs(bool ducked) // 7 333 | // CGameMovement::GetPlayerViewOffset // 8 334 | // CGameMovement::IsMovingPlayerStuck // 9 335 | // CGameMovement::GetMovingPlayer // 10 336 | virtual void UnblockPusher(CBasePlayer *pPlayer, CBaseEntity *pPusher); // 11 337 | // CGameMovement::SetupMovementBounds // 12 338 | // CGameMovement::GetPlayerMins(); // 13 339 | // CGameMovement::GetPlayerMaxs(); // 14 340 | // CGameMovement::TracePlayerBBox(); // 15 341 | virtual unsigned int PlayerSolidMask(bool brushOnly = false, CBasePlayer* testPlayer = nullptr); // 16 342 | virtual void PlayerMove(); // 17 343 | void AutoMountMove(); 344 | // CGameMovement::CalcRoll // 18 345 | // CGameMovement::DecayViewPunchAngle // 19 346 | // CGameMovement::CheckWaterJump // 20 347 | // CGameMovement::WaterMove(); // 21 348 | // CGameMovement::SlimeMove(); //22 349 | // CGameMovement::WaterJump // 23 350 | // CGameMovement::Friction // 24 351 | // CGameMovement::AirAccelerate // 25 352 | virtual void AirMove(); // 26 // 26 353 | virtual bool CanAccelerate(); // 27 354 | virtual void Accelerate(Vector&, float, float); // 28 355 | virtual void WalkMove(); // 29 356 | // CGameMovement::StayOnGround // 30 357 | // CGameMovement::FullWalkMove // 31 358 | virtual void OnJump(float stamina); // 32 359 | virtual void nullsub3(); // 33 360 | virtual void OnLand(float flFallVelocity); // 34 361 | // CGameMovement::GetCheckInterval // 35 362 | // CGameMovement::StartGravity // 36 363 | // CGameMovement::FinishGravity // 37 364 | // CGameMovement::AddGravity //38 365 | virtual bool CheckJumpButton(); // 39 366 | // CGameMovement::FullTossMove // 40 367 | // CGameMovement::FullLadderMove // 41 368 | // CGameMovement::TryPlayerMove // 42 369 | virtual bool LadderMove(); // 43 370 | virtual bool OnLadder(trace_t& trace); // 44 371 | virtual float LadderDistance(); // 45 372 | // CGameMovement::LadderMask // 46 373 | virtual float ClimbSpeed() const; // 47 374 | virtual float LadderLateralMultiplier() const; // 48 375 | // CGameMovement::ClipVelocity // 49 376 | // CGameMovement::CheckWater // 50 377 | // CGameMovement::GetWaterCheckPosition // 51 378 | // CGameMovement::CategorizePosition // 52 379 | virtual void CheckParameters(); // 53 380 | virtual void ReduceTimers(); // 54 381 | // CGameMovement::CheckFalling // 55 382 | // CGameMovement::PlayerRoughLandingEffects // 56 383 | virtual void Duck(); // 57 384 | // CGameMovement::HandleDuckingSpeedCrop // 58 385 | virtual void FinishUnduck(); // 59 386 | virtual void FinishDuck(); // 60 387 | virtual bool CanUnduck(); // 61 388 | // CGameMovement::UpdateDuckJumpEyeOffset // 62 389 | // CGameMovement::CanUnduckJump // 63 390 | // CGameMovement::StartUnduckJump // 64 391 | // CGameMovement::FinishUnduckJump // 65 392 | // CGameMovement::SetDuckedEyeOffset // 66 393 | // CGameMovement::FixPlayerCrouchStuck // 67 394 | // CGameMovement::CategorizeGroundSurface // 68 395 | // CGameMovement::InWater // 69 396 | // CGameMovement::TestPlayerPosition // 70 397 | // CGameMovement::SetGroundEntity // 71 398 | // CGameMovement::StepMove // 72 399 | // CGameMovement::LockTraceFilter // 73 400 | // CGameMovement::UnlockTraceFilter // 74 401 | // CGameMovement::GameHasLadders // 75 402 | virtual void PreventBunnyJumping(); // 76 403 | virtual void DecayAimPunchAngle(); // 77 404 | void ApplyDuckRatio(float flDuckAmount); 405 | bool IsPlayerDucking(); 406 | bool CanMove(CBasePlayer* ent); 407 | 408 | CBasePlayer *m_pCSPlayer; //3668 409 | }; 410 | 411 | extern IGameMovement *g_pGameMovement; --------------------------------------------------------------------------------