DayZ 1.30
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено

◆ TryBuildPondHitPosition()

bool CCTLiquid::TryBuildPondHitPosition ( PlayerBase player,
vector playerPos,
out vector pondHitPosition )
inlineprotected

Client only. Server validates synced cursor position.

If looking upward/horizontal, we are probably not aiming at a pond surface.

The ray is close enough to the liquid surface.

Last chance: use closest sampled surface if it was very close.

См. определение в файле CCTLiquid.c строка 431

432 {
433 #ifdef DIAG_DEVELOPER
434 float debugBestDelta = 999999.0;
435 int debugSampleCount = 0;
436 int debugValidKnownSurfaceCount = 0;
437 string debugPondFailReason = "no pond samples";
438 #endif
439
440 pondHitPosition = vector.Zero;
441
443 if (g_Game.IsHeadlessOrDedicatedServer())
444 return false;
445
446 vector cameraPos = g_Game.GetCurrentCameraPosition();
447 vector cameraDir = g_Game.GetCurrentCameraDirection();
448
449 if (cameraPos == vector.Zero || cameraDir == vector.Zero)
450 return false;
451
452 cameraDir.Normalize();
453
455 if (cameraDir[1] > 0.15)
456 return false;
457
459 if (safeDistance <= 1.0)
460 safeDistance = m_MaxActionDistance * 0.8;
461
462 vector bestSurfacePos = vector.Zero;
463 int bestLiquidType = LIQUID_NONE;
464 float bestDelta = 999999.0;
465 vector pondSurfacePos = vector.Zero;
466
467 for (float dist = 1.0; dist <= safeDistance; dist += SYNTHETIC_POND_SAMPLE_STEP)
468 {
469 #ifdef DIAG_DEVELOPER
470 debugSampleCount++;
471 #endif
472
473 vector probePos = cameraPos + cameraDir * dist;
474
475 vector surfacePos;
476 int liquidType;
477 string surfaceType;
478
479 if (!TryGetLiquidSurfaceAt(probePos, surfacePos, liquidType, surfaceType))
480 {
481 #ifdef DIAG_DEVELOPER
482 debugPondFailReason = "TryGetLiquidSurfaceAt failed";
483 #endif
484 continue;
485 }
486
487 if (!IsAllowedPondLiquidSurface(playerPos, surfacePos, liquidType))
488 {
489 #ifdef DIAG_DEVELOPER
490 debugPondFailReason = "known pond surface invalid";
491 #endif
492 continue;
493 }
494
495 #ifdef DIAG_DEVELOPER
496 debugValidKnownSurfaceCount++;
497 #endif
498
499 float rayToSurfaceDelta = Math.AbsFloat(probePos[1] - surfacePos[1]);
500 if (rayToSurfaceDelta < bestDelta)
501 {
502 bestDelta = rayToSurfaceDelta;
503 bestSurfacePos = surfacePos;
504 bestLiquidType = liquidType;
505
506 #ifdef DIAG_DEVELOPER
507 debugBestDelta = bestDelta;
508 debugPondFailReason = "best pond surface too far from camera ray";
509 #endif
510 }
511
513 if (rayToSurfaceDelta <= SYNTHETIC_POND_SURFACE_TOLERANCE)
514 {
515 surfacePos = ApplySyntheticHitCursorStability(playerPos, surfacePos, liquidType);
516
517 if (!IsValidPondHitPosition(playerPos, surfacePos, liquidType))
518 continue;
519
520 pondSurfacePos = surfacePos;
521 pondSurfacePos[1] = pondSurfacePos[1] + LIQUID_SURFACE_RAYCAST_OFFSET;
522
523 if (!HasClearPathToLiquidSurface(player, pondSurfacePos))
524 continue;
525
526 pondHitPosition = surfacePos;
527 return true;
528 }
529 }
530
532 if (!IsNearlyZero(bestSurfacePos) && bestDelta <= SYNTHETIC_POND_FALLBACK_SURFACE_TOLERANCE)
533 {
534 bestSurfacePos = ApplySyntheticHitCursorStability(playerPos, bestSurfacePos, bestLiquidType);
535 if (IsValidPondHitPosition(playerPos, bestSurfacePos, bestLiquidType))
536 {
537 pondSurfacePos = bestSurfacePos;
538 pondSurfacePos[1] = pondSurfacePos[1] + LIQUID_SURFACE_RAYCAST_OFFSET;
539
540 if (!HasClearPathToLiquidSurface(player, pondSurfacePos))
541 return false;
542
543 pondHitPosition = bestSurfacePos;
544 return true;
545 }
546 }
547
548 #ifdef DIAG_DEVELOPER
549 DbgUI.Begin("", 50, 240);
550 if (m_DebugSyntheticCursor)
551 {
552 DbgUI.Text(string.Format("CCTLiquid TryBuildPondHitPosition failed: reason=%1 | samples=%2 | validSurfaces=%3 | bestDelta=%4 | tolerance=%5 | relaxedTolerance=%6", debugPondFailReason, debugSampleCount, debugValidKnownSurfaceCount, debugBestDelta, SYNTHETIC_POND_SURFACE_TOLERANCE, SYNTHETIC_POND_FALLBACK_SURFACE_TOLERANCE));
553 }
554 DbgUI.End();
555 #endif
556
557 return false;
558 }
DayZGame g_Game
Определения DayZGame.c:4074
bool HasClearPathToLiquidSurface(PlayerBase player, vector surfacePos)
Определения CCTLiquid.c:250
bool IsNearlyZero(vector value)
Определения CCTLiquid.c:1024
bool IsValidPondHitPosition(vector playerPos, vector hitPosition, int liquidType=LIQUID_NONE)
Определения CCTLiquid.c:560
vector ApplySyntheticHitCursorStability(vector playerPos, vector candidate, int liquidType)
Определения CCTLiquid.c:763
bool TryGetLiquidSurfaceAt(vector probePosition, out vector surfacePosition, out int liquidType, out string surfaceType)
Определения CCTLiquid.c:293
static const float SYNTHETIC_POND_FALLBACK_SURFACE_TOLERANCE
Определения CCTLiquid.c:8
static const float SYNTHETIC_CURSOR_DISTANCE_BUFFER
Определения CCTLiquid.c:9
bool IsAllowedPondLiquidSurface(vector playerPos, vector surfacePos, int liquidType)
Определения CCTLiquid.c:929
float m_MaxActionDistance
Определения CCTLiquid.c:23
static const float SYNTHETIC_POND_SAMPLE_STEP
Определения CCTLiquid.c:6
static const float LIQUID_SURFACE_RAYCAST_OFFSET
Определения CCTLiquid.c:16
static const float SYNTHETIC_POND_SURFACE_TOLERANCE
Определения CCTLiquid.c:7
proto float Normalize()
Normalizes vector. Returns length.
const int LIQUID_NONE
Определения 3_Game/DayZ/constants.c:566

Перекрестные ссылки Math::AbsFloat(), ApplySyntheticHitCursorStability(), DbgUI::Begin(), DbgUI::End(), g_Game, HasClearPathToLiquidSurface(), IsAllowedPondLiquidSurface(), IsNearlyZero(), IsValidPondHitPosition(), LIQUID_NONE, LIQUID_SURFACE_RAYCAST_OFFSET, m_MaxActionDistance, vector::Normalize(), SYNTHETIC_CURSOR_DISTANCE_BUFFER, SYNTHETIC_POND_FALLBACK_SURFACE_TOLERANCE, SYNTHETIC_POND_SAMPLE_STEP, SYNTHETIC_POND_SURFACE_TOLERANCE, DbgUI::Text(), TryGetLiquidSurfaceAt() и vector::Zero.

Используется в TryBuildSyntheticCursor().