Skip to content

Commit

Permalink
feat: add pitch handling for autostrafe keep mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Krzyhau committed Sep 8, 2024
1 parent c682a73 commit 19e7ef4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
40 changes: 31 additions & 9 deletions src/Features/Tas/TasTools/StrafeTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,21 +371,43 @@ float AutoStrafeTool::GetFastestStrafeAngle(const TasPlayerInfo &player) {

// get horizontal angle of wishdir that would achieve given velocity
// angle is relative to your current velocity direction.
float AutoStrafeTool::GetTargetStrafeAngle(const TasPlayerInfo &player, float targetSpeed) {
float AutoStrafeTool::GetTargetStrafeAngle(const TasPlayerInfo &player, float targetSpeed, float turningDir) {
Vector vel = GetGroundFrictionVelocity(player);

if (vel.Length2D() == 0) return 0;
float currentSpeed = vel.Length2D();
if (currentSpeed == 0) return 0;

Vector wishDir(0, 1);
//float maxSpeed = GetMaxSpeed(player, wishDir);
float maxAccel = GetMaxAccel(player, wishDir);
float maxAccel = GetMaxAccel(player, {0, 1});

// Assuming that it is possible to achieve a velocity of a given length,
// I'm using a law of cosines to get the right angle for acceleration.
float cosAng = (powOld(vel.Length2D(), 2) + powOld(maxAccel, 2) - powOld(targetSpeed, 2)) / (2.0f * vel.Length2D() * maxAccel);
float targetAngle = acosf(-(powOld(currentSpeed, 2) + powOld(maxAccel, 2) - powOld(targetSpeed, 2)) / (2.0f * currentSpeed * maxAccel)) * turningDir;

FOR_TAS_SCRIPT_VERSIONS_SINCE(8) {
// When we're affected by pitch, we should recalculate the angle a couple of times to ensure we can reach it.
if (params.noPitchLock && IsMovementAffectedByPitch(player)) {
float velAngle = TasUtils::GetVelocityAngles(&player).x;
float velToLocalAngleDeltaRad = DEG2RAD(player.angles.y) - DEG2RAD(velAngle);
float cosPitch = cosf(DEG2RAD(player.angles.x));

const int maxIterations = 50;
for (int i = 0; i < maxIterations; i++) {
float correctAng = targetAngle - velToLocalAngleDeltaRad;
float forwardmove = cosf(correctAng) / cosPitch;
float sidemove = -sinf(correctAng);

float scaledAccel = maxAccel / sqrtf(forwardmove * forwardmove + sidemove * sidemove);
float previousTargetAngle = targetAngle;
targetAngle = acosf(-(powf(currentSpeed, 2) + powf(scaledAccel, 2) - powf(targetSpeed, 2)) / (2.0f * currentSpeed * scaledAccel)) * turningDir;

if (fabsf(previousTargetAngle - targetAngle) < 0.00001f) {
break;
}
}
}
}

// Also, questionable trig to get the right angle lol.
return acosf(-cosAng);
return targetAngle;
}

// get horizontal angle of wishdir that would give the biggest turning angle in given tick
Expand Down Expand Up @@ -457,7 +479,7 @@ float AutoStrafeTool::GetStrafeAngle(const TasPlayerInfo &player, AutoStrafePara
}

if (passedTargetSpeed || speedDiff == 0) {
ang = GetTargetStrafeAngle(player, params.strafeSpeed.speed) * turningDir;
ang = GetTargetStrafeAngle(player, params.strafeSpeed.speed, turningDir);
}

return ang;
Expand Down
4 changes: 2 additions & 2 deletions src/Features/Tas/TasTools/StrafeTool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ enum AutoStrafeType {

enum AutoStrafeParamType {
SPECIFIED,
CURRENT
CURRENT,
};

struct AutoStrafeDirection {
Expand Down Expand Up @@ -74,7 +74,7 @@ class AutoStrafeTool : public TasToolWithParams<AutoStrafeParams> {

Vector GetVelocityAfterMove(const TasPlayerInfo &player, float forwardMove, float sideMove);
float GetFastestStrafeAngle(const TasPlayerInfo &player);
float GetTargetStrafeAngle(const TasPlayerInfo &player, float targetSpeed);
float GetTargetStrafeAngle(const TasPlayerInfo &player, float targetSpeed, float turningDir);
float GetTurningStrafeAngle(const TasPlayerInfo &player);

private:
Expand Down

0 comments on commit 19e7ef4

Please sign in to comment.