fix: spell facing used atan2(dy,dx) but canonical convention is atan2(-dy,dx)

The canonical yaw convention (documented in coordinates.hpp) is
atan2(-dy, dx) where X=north, Y=west. North=0, East=+PI/2.

The spell facing code used atan2(dy, dx) (no negation on dy), producing
a yaw ~77° off from the correct server orientation. The server rejected
every cast with "unit not in front" because the sent orientation pointed
in the wrong direction.

Fixed in all 3 locations: charge facing, melee facing, and general
pre-cast facing.
This commit is contained in:
Kelsi 2026-03-28 16:51:23 -07:00
parent 7f3c7379b5
commit d68bb5a831

View file

@ -267,7 +267,7 @@ void SpellHandler::castSpell(uint32_t spellId, uint64_t targetGuid) {
return;
}
// Face the target before sending the cast packet
float yaw = std::atan2(dy, dx);
float yaw = std::atan2(-dy, dx);
owner_.movementInfo.orientation = yaw;
owner_.sendMovement(Opcode::MSG_MOVE_SET_FACING);
if (owner_.chargeCallback_) {
@ -294,7 +294,7 @@ void SpellHandler::castSpell(uint32_t spellId, uint64_t targetGuid) {
owner_.addSystemChatMessage("Out of range.");
return;
}
float yaw = std::atan2(dy, dx);
float yaw = std::atan2(-dy, dx);
owner_.movementInfo.orientation = yaw;
owner_.sendMovement(Opcode::MSG_MOVE_SET_FACING);
}
@ -311,13 +311,9 @@ void SpellHandler::castSpell(uint32_t spellId, uint64_t targetGuid) {
float dy = entity->getY() - owner_.movementInfo.y;
float lenSq = dx * dx + dy * dy;
if (lenSq > 0.01f) {
float canonYaw = std::atan2(dy, dx);
float serverYaw = core::coords::canonicalToServerYaw(canonYaw);
// Canonical yaw convention: atan2(-dy, dx) where X=north, Y=west
float canonYaw = std::atan2(-dy, dx);
owner_.movementInfo.orientation = canonYaw;
LOG_WARNING("Pre-cast facing: target=(", entity->getX(), ",", entity->getY(),
") me=(", owner_.movementInfo.x, ",", owner_.movementInfo.y,
") canonYaw=", canonYaw, " serverYaw=", serverYaw,
" dx=", dx, " dy=", dy);
owner_.sendMovement(Opcode::MSG_MOVE_SET_FACING);
owner_.sendMovement(Opcode::MSG_MOVE_HEARTBEAT);
}