// Console commands of the carrier (DESIGN_UE.md section 9.3). M2: the kinematic debug motion that proves walking on a moving hull (R2). #include "Debug/DescentCommandUtil.h" #include "Vehicles/CarrierCarousel.h" #include "Vehicles/DescentCarrier.h" #include "Vehicles/CarrierHelm.h" #include "TheDescent.h" #include "Engine/World.h" #include "HAL/IConsoleManager.h" namespace { void CmdCarrierMotion(const TArray& Args, UWorld* World) { TArray N; ADescentCarrier* C = UDescentCarrierSubsystem::GetCarrier(World); if (!C || !Descent::Cmd::ParseNumbers(Args, 0, 7, N) || N[6] <= 0.0) { Descent::Cmd::Fail(World, TEXT("Descent.Carrier.Motion"), TEXT("usage: Descent.Carrier.Motion vxFwd vyRight vzUp yawRateDps pitchAmpDeg pitchPeriodSec seconds (m/s along the carrier own axes; stops itself after the seconds of sim time)")); return; } FCarrierDebugMotion M; M.VelocityLocalMps = FVector(N[0], N[1], N[2]); M.YawRateDps = N[3]; M.PitchAmplitudeDeg = N[4]; M.PitchPeriodSec = N[5]; M.RemainingSec = N[6]; C->SetDebugMotion(M); UE_LOG(LogDescent, Display, TEXT("Carrier.Motion: v (%.2f %.2f %.2f) m/s, yaw %.2f deg/s, pitch +-%.1f deg every %.1f s, for %.1f s"), N[0], N[1], N[2], N[3], N[4], N[5], N[6]); } void CmdCarrierStop(const TArray&, UWorld* World) { if (ADescentCarrier* C = UDescentCarrierSubsystem::GetCarrier(World)) { C->ClearDebugMotion(); } } void CmdCarrierCarousel(const TArray&, UWorld* World) { // Section 9.3: rotate one step (what the carousel console does on E). Refused while a Tender is out or the hoist moves. ADescentCarrier* C = UDescentCarrierSubsystem::GetCarrier(World); FString Why = TEXT("no carrier"); if (!C || !C->Carousel || !C->Carousel->RequestRotate(&Why)) { Descent::Cmd::Fail(World, TEXT("Descent.Carrier.Carousel"), FString::Printf(TEXT("refused: %s"), *Why)); } } /** Descent.Carrier. (section 9.3, M6). */ void CmdCarrierHelmAny(const TArray& Args, UWorld* World, int32 What) { static const TCHAR* const Names[] = { TEXT("Descent.Carrier.Helm"), TEXT("Descent.Carrier.Throttle"), TEXT("Descent.Carrier.AimDelta"), TEXT("Descent.Carrier.Ballast"), TEXT("Descent.Carrier.Strafe"), TEXT("Descent.Carrier.View"), TEXT("Descent.Carrier.Teleport"), TEXT("Descent.Carrier.SetHull"), TEXT("Descent.Carrier.Autopilot") }; static const int32 Count[] = { 1, 1, 2, 1, 1, 1, 4, 1, 1 }; ADescentCarrier* C = UDescentCarrierSubsystem::GetCarrier(World); TArray N; if (What == 8 && C && Args.Num() > 0 && Args[0].Equals(TEXT("stop"), ESearchCase::IgnoreCase)) { C->Autopilot.Stop(); return; } if (!C || !Descent::Cmd::ParseNumbers(Args, 0, Count[What], N)) { Descent::Cmd::Fail(World, Names[What], TEXT("usage: Helm <0 or 1> | Throttle v | AimDelta yawDeg pitchDeg | Ballast v | Strafe v | View n | Teleport x y z yaw | SetHull v | Autopilot <1..3 or stop>")); return; } switch (What) { case 0: C->SetHelmHeld(N[0] > 0.5); break; case 1: C->Helm.Throttle = FMath::Clamp(N[0], Descent::Tune::Helm::ThrottleMin, Descent::Tune::Helm::ThrottleMax); break; case 2: C->Helm.AddAim(N[0], N[1]); break; case 3: C->Helm.Ballast = FMath::Clamp(N[0], -1.0, 1.0); break; case 4: C->Helm.Strafe = FMath::Clamp(N[0], -1.0, 1.0); break; case 5: C->SetHelmView(FMath::RoundToInt32(N[0])); break; case 6: C->TeleportCarrier(FVector(N[0], N[1], N[2]), N[3]); break; case 7: C->Helm.Hull = FMath::Clamp(N[0], 0.0, 100.0); break; default: C->Autopilot.Start(FMath::RoundToInt32(N[0]) - 1); break; } } FAutoConsoleCommandWithWorldAndArgs GCarrierCmdHelm(TEXT("Descent.Carrier.Helm"), TEXT("Descent.Carrier.Helm <0 or 1> - hold or release the helm"), FConsoleCommandWithWorldAndArgsDelegate::CreateLambda([](const TArray& A, UWorld* W) { CmdCarrierHelmAny(A, W, 0); })); FAutoConsoleCommandWithWorldAndArgs GCarrierCmdThrottle(TEXT("Descent.Carrier.Throttle"), TEXT("Descent.Carrier.Throttle v - the lever, -0.5 .. 1"), FConsoleCommandWithWorldAndArgsDelegate::CreateLambda([](const TArray& A, UWorld* W) { CmdCarrierHelmAny(A, W, 1); })); FAutoConsoleCommandWithWorldAndArgs GCarrierCmdAim(TEXT("Descent.Carrier.AimDelta"), TEXT("Descent.Carrier.AimDelta yawDeg pitchDeg - move the aim point (the mouse)"), FConsoleCommandWithWorldAndArgsDelegate::CreateLambda([](const TArray& A, UWorld* W) { CmdCarrierHelmAny(A, W, 2); })); FAutoConsoleCommandWithWorldAndArgs GCarrierCmdBallast(TEXT("Descent.Carrier.Ballast"), TEXT("Descent.Carrier.Ballast v"), FConsoleCommandWithWorldAndArgsDelegate::CreateLambda([](const TArray& A, UWorld* W) { CmdCarrierHelmAny(A, W, 3); })); FAutoConsoleCommandWithWorldAndArgs GCarrierCmdStrafe(TEXT("Descent.Carrier.Strafe"), TEXT("Descent.Carrier.Strafe v"), FConsoleCommandWithWorldAndArgsDelegate::CreateLambda([](const TArray& A, UWorld* W) { CmdCarrierHelmAny(A, W, 4); })); FAutoConsoleCommandWithWorldAndArgs GCarrierCmdView(TEXT("Descent.Carrier.View"), TEXT("Descent.Carrier.View n - helm camera 0..4"), FConsoleCommandWithWorldAndArgsDelegate::CreateLambda([](const TArray& A, UWorld* W) { CmdCarrierHelmAny(A, W, 5); })); FAutoConsoleCommandWithWorldAndArgs GCarrierCmdTeleport(TEXT("Descent.Carrier.Teleport"), TEXT("Descent.Carrier.Teleport x y z yaw - move the carrier"), FConsoleCommandWithWorldAndArgsDelegate::CreateLambda([](const TArray& A, UWorld* W) { CmdCarrierHelmAny(A, W, 6); })); FAutoConsoleCommandWithWorldAndArgs GCarrierCmdSetHull(TEXT("Descent.Carrier.SetHull"), TEXT("Descent.Carrier.SetHull v"), FConsoleCommandWithWorldAndArgsDelegate::CreateLambda([](const TArray& A, UWorld* W) { CmdCarrierHelmAny(A, W, 7); })); FAutoConsoleCommandWithWorldAndArgs GCarrierCmdAutopilot(TEXT("Descent.Carrier.Autopilot"), TEXT("Descent.Carrier.Autopilot <1..3 or stop>"), FConsoleCommandWithWorldAndArgsDelegate::CreateLambda([](const TArray& A, UWorld* W) { CmdCarrierHelmAny(A, W, 8); })); FAutoConsoleCommandWithWorldAndArgs GCarrierCmdCarousel(TEXT("Descent.Carrier.Carousel"), TEXT("Descent.Carrier.Carousel - rotate the carousel one step (120 degrees)"), FConsoleCommandWithWorldAndArgsDelegate::CreateStatic(&CmdCarrierCarousel)); FAutoConsoleCommandWithWorldAndArgs GCarrierCmdMotion(TEXT("Descent.Carrier.Motion"), TEXT("Descent.Carrier.Motion vx vy vz yawRateDps pitchAmpDeg pitchPeriodSec seconds - move the carrier kinematically (test)"), FConsoleCommandWithWorldAndArgsDelegate::CreateStatic(&CmdCarrierMotion)); FAutoConsoleCommandWithWorldAndArgs GCarrierCmdStop(TEXT("Descent.Carrier.Stop"), TEXT("Descent.Carrier.Stop - end the debug motion"), FConsoleCommandWithWorldAndArgsDelegate::CreateStatic(&CmdCarrierStop)); }