#pragma once #include "CoreMinimal.h" /** Constants of the player on foot (DESIGN_UE.md sections 5.1, 5.2, 5.4, 5.7; v2 10_player.js). Metres, seconds, degrees. */ namespace Descent::Tune::Player { // ---- the body (5.1) ----------------------------------------------------------------------------------------- constexpr double CapsuleRadiusM = 0.34; constexpr double CapsuleHalfHeightM = 0.90; constexpr double EyeHeightM = 1.65; // above the feet constexpr float FovDeg = 72.f; constexpr double BobVerticalM = 0.045; // v2's bob, 0.045 sin(2 bob) * moving. NOT USED since 2026-10-12 (9 cm peak to peak walking, 12 running: "too shaky") constexpr double BobPerMetre = 2.2; // still the phase of the bob when the animation set has no measured footfalls // The view bob since 2026-10-12: up and down only, with the pelvis of the body's locomotion clip (so in step with the footfalls). // Amplitudes (half the peak-to-peak) at the walking and the sprinting speed; cvar descent.View.Bob scales them (0 = none, 1 = these). constexpr double ViewBobWalkCm = 0.45; constexpr double ViewBobRunCm = 0.70; constexpr double ViewBobDefault = 1.0; // The camera's fastest bob speed, cm/s, walking and sprinting: what the first calm bob had (0.27 and 0.68 cm in a 1/30 s frame). // When the footfalls come faster the amplitude gives way, so the bob never moves the view faster than this. constexpr double ViewBobWalkMaxCmS = 8.1; constexpr double ViewBobRunMaxCmS = 20.4; // ---- walking (5.2) ------------------------------------------------------------------------------------------ constexpr double WalkSpeedMps = 2.9; constexpr double SprintSpeedMps = 4.8; constexpr double CarrySpeedMps = 2.3; constexpr double VelocityDampK = 12.0; // velocity follows damp(k = 12) constexpr double AirDampK = 3.0; // control while airborne (guess; v2 had no air control) constexpr double JumpSpeedMps = 4.4; constexpr double GravityMps2 = 11.0; // v2 GRAV constexpr double StepHeightM = 0.35; constexpr double WalkableAngleDeg = 50.0; constexpr double FootstepEveryM = 1.35; // ---- looking (5.7) ------------------------------------------------------------------------------------------ constexpr double MouseDegPerPixel = 0.12; // v2 SENS = 0.0021 rad constexpr double ArrowLookDps = 90.0; constexpr double PitchLimitDeg = 85.0; // ---- moving on the carrier (3.1) ---------------------------------------------------------------------------- constexpr float StayBasedInAirHeightCm = 300.f; // ---- interaction (5.4) -------------------------------------------------------------------------------------- constexpr double DefaultInteractRangeM = 2.4; constexpr double DefaultInteractMinDot = 0.55; constexpr double InteractDistanceScore = 0.05; // score = dot - 0.05 * distance // ---- the room's light on the first-person arm (fix list after M3; see ADescentCharacter::ArmRoomFill) ---------------------- constexpr double ArmFillBackM = -0.45, ArmFillRightM = 0.10, ArmFillUpM = 0.35; // behind, beside and above the eye (camera frame: x forward) constexpr double ArmFillRadiusM = 3.0; constexpr double ArmFillOfLamp = 0.30; // of one room lamp's brightness: about what a wall 5 m from a lamp receives // ---- flashlight (7.5) --------------------------------------------------------------------------------------- constexpr float FlashlightRadiusM = 55.f; constexpr float FlashlightInnerConeDeg = 12.f; constexpr float FlashlightOuterConeDeg = 20.6f; constexpr float FlashlightIntensity = 2.0f; // unitless design value, scaled like the lamps // ---- swimming (5.3) ----------------------------------------------------------------------------------------- constexpr double SwimSpeedMps = 2.8; constexpr double SwimSprintMps = 4.2; constexpr double SwimResponseK = 2.2; // vel = lerp(vel, wish * MaxS, 1 - exp(-2.2 dt)) constexpr double SwimSinkMps2 = 0.12; constexpr double SwimSphereM = 0.45; // the sphere tested against the density field constexpr double SwimHullRadiusM = 0.6; // carrier hull push-out constexpr double SwimHeadBelowSurfaceM = 0.35; // in the shaft the head cannot rise above the pool surface - 0.35 m constexpr double SwimEnterBelowSurfaceM = 0.2; // on foot, feet this far under the pool surface: swimming starts constexpr double O2RefillHeadRangeM = 0.6; // head within this of the pool surface: O2 refills constexpr double LadderRangeM = 1.6; // E in the shaft within this of the surface and y < LadderMaxY constexpr double LadderMaxY = 5.3; constexpr double LadderSec = 1.6; constexpr double LadderExitX = -29.0, LadderExitY = 2.6, LadderExitZ = -7.5, LadderExitYawDeg = 90.0; constexpr double PoolDropX = -29.0, PoolDropY = 4.4, PoolDropFeetZ = -9.6; // Descent.Player.PoolDrop and E at the ladder sign // ---- vitals, death, respawn (5.8) --------------------------------------------------------------------------- constexpr double NutritionStartPct = 42.0; // nutrition does not drain before M8 constexpr double HungerPct = 20.0; constexpr double O2BaseSec = 45.0; constexpr double O2DrainPerSec = 1.0; constexpr double O2SprintFactor = 1.4; constexpr double O2RefillPerSec = 20.0; constexpr double O2LowSec = 10.0; constexpr double DrownHPPerSec = 9.0; constexpr double SwimHonestVoidHPPerSec = 14.0; constexpr double HealthRegenPerSec = 0.4; constexpr double DeathFadeSec = 2.0; constexpr double RespawnAfterSec = 2.6; constexpr double RespawnX = 24.0, RespawnY = -5.0, RespawnZ = -3.0; // the galley constexpr double RespawnHealth = 60.0; constexpr double DebtDrownCr = 900.0; constexpr double DebtImplodeCr = 4800.0; // ---- HUD (2.7 strata table, 2.11, 8.5) ---------------------------------------------------------------------- constexpr double BandThroatFloorM = 2040.0; // THE THROAT above, THROAT FLOOR below constexpr double BandHoneycombM = 2150.0; // THE HONEYCOMB constexpr double BandSeamM = 2700.0; // HONEYCOMB - SEAM INTRUSION constexpr double BandBelowSurveyM = 3180.0; // BELOW SURVEY constexpr double BandOpenSeaM = 1740.0; // above the rim there is no band constexpr double LidCloseAfterSec = 1.0; // a canopy or hatch opened for leaving closes again constexpr double EnterViewBlendSec = 0.3; constexpr float NearClipCm = 5.f; // section 4.6: r.SetNearClipPlane 5 (the canopy frame is close to the eye) // ---- safety nets (not in the design) ------------------------------------------------------------------------ /** Below this carrier-local z (or further than RescueRadiusM from the carrier) the character is put back on the bridge. */ constexpr double RescueBelowZM = -16.0; constexpr double RescueRadiusM = 90.0; // ---- the debug walker (Descent.Player.MoveTo, section 9.3) --------------------------------------------------- constexpr double MoveToArriveM = 0.4; constexpr double MoveToWaypointM = 0.55; constexpr double MoveToTimeoutSec = 20.0; constexpr double MoveToTurnGain = 10.0; // deg/s of turn per degree of heading error constexpr double MoveToMaxTurnDps = 300.0; }