Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Server/Components/NPCs/NPC/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,9 +499,18 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType, float moveSpeed, float stopRan
{
front = (pos - position) / distance;
auto rotation = getRotation().ToEuler();
rotation.x = 0.0f; // Discard the pitch a previous drive move may have baked in, it would skew the facing angle

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this doesn't really change much, but since this line is meant to be for vehicles/driving only, let's move it in the if code block down there you made for moveType_ == NPCMoveType_Drive.

But remember it should be rotation_.x when you do.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GTAQuat only has a glm::quat q member, so rotation_.x won't compile. also, rotation_.q.x is a quaternion component, not an euler angle.

but I think this line actually belongs in the non-drive path rather than the drive one. inside the drive block, the quaternion gets overwritten completely by the angleAxis composition, so a stale pitch there shouldn't really matter.

the case that actually needs it is when an NPC drives uphill and then gets told to walk. move() calls removeFromVehicle() itself, and sendFootSync() writes the full quaternion, so the ped keeps walking around tilted by 26.5° even on flat ground.

moving it into the if would also mean adding a matching else, which basically just means having the same line in both branches.

rotation.z = getAngleOfLine(front.x, front.y);
rotation_ = GTAQuat(rotation); // Do this directly, if you use NPC::setRotation it's going to cause recursion

if (moveType_ == NPCMoveType_Drive)
{
// Tilt the vehicle to match the slope towards the target
const float pitch = -atan2(front.z, glm::length(glm::vec2(front)));
const float yaw = glm::roll(rotation_.q); // glm is Y up, so its roll() is the rotation around our Z axis
rotation_.q = glm::angleAxis(pitch, Vector3(1.0f, 0.0f, 0.0f)) * glm::angleAxis(yaw, Vector3(0.0f, 0.0f, 1.0f));
}

// Calculate velocity to use on tick
velocity_ = front * (moveSpeed_ / 100.0f);
}
Expand Down