-
Member
FaceTo
Hi, FaceTo worked very well for a very long time, but after a recent update, FaceTo started crashing. Has anyone solved this problem?
-
Established Member
Just got back to this game (rip). Currently working on packet based, steering motion for super realistic client side movement.
Previously I was using Click to move, which I believe you are referring to. I've been exploring the packet system now, so here's how you can do it with packets instead; This is probably just downstream what the wrapping CTM face to method was effectively doing
Code:
WOTLK 3.4.1.48120 -
FaceTo - 0x0F5F4E0: (active_mover: &Mover, time: GameTime, unk: bool) // unk always true
ActiveMover Guid - 0x2C31368 - (So far always the player's guid, but probabyl changes in vehicles and stuff)
Mover is offset 0x128 into Object
Rotation is offset 0x158 into Object
write to rotation (0x158) desired rotation
call FaceTo(activeMover->mover, game_time(), true)
So far, all opcodes seem accurate in TrinityCore/Opcodes.h at wotlk_classic . TrinityCore/TrinityCore . GitHub
You can search for the constant and you'll find handler functions for sending the packets. These higher level functions are a nice convenience method.
Code:
// 0x0F5F4E0
char __fastcall PFace(int a1, int a2, char a3)
{
char v5; // bl
char packet[32]; // [rsp+30h] [rbp-108h] BYREF
char v8; // [rsp+50h] [rbp-E8h] BYREF
__int64 v9; // [rsp+E0h] [rbp-58h]
__int64 v10; // [rsp+F0h] [rbp-48h]
if ( !a3 )
return 0;
PFace::Init((__int64)packet);
v5 = SMovement::SendEvent(a1, a2, 0x3A09, (unsigned int)&v8, (__int64)packet);
if ( v10 >= 0 )
sub_140213F80(v9, (__int64)aAvwowguid, 4294967290i64, 0);
return v5;
}
Last edited by _chase; 02-28-2023 at 09:20 AM.
Reason: wrong offset sorry
-
Post Thanks / Like - 2 Thanks
-
Member
Originally Posted by
_chase
Just got back to this game (rip). Currently working on packet based, steering motion for super realistic client side movement.
Previously I was using Click to move, which I believe you are referring to. I've been exploring the packet system now, so here's how you can do it with packets instead; This is probably just downstream what the wrapping CTM face to method was effectively doing
Code:
WOTLK 3.4.1.48120 -
FaceTo - 0x0F5ED80 : (active_mover: &Mover, time: GameTime, unk: bool) // unk always true
ActiveMover Guid - 0x2C31368 - (So far always the player's guid, but probabyl changes in vehicles and stuff)
Mover is offset 0x128 into Object
Rotation is offset 0x158 into Object
write to rotation (0x158) desired rotation
call FaceTo(activeMover->mover, game_time(), true)
So far, all opcodes seem accurate in
TrinityCore/Opcodes.h at wotlk_classic . TrinityCore/TrinityCore . GitHub
You can search for the constant and you'll find handler functions for sending the packets. These higher level functions are a nice convenience method.
Code:
// 0x0F5ED80
char __fastcall PFace(int a1, int a2, char a3)
{
char v5; // bl
char packet[32]; // [rsp+30h] [rbp-108h] BYREF
char v8; // [rsp+50h] [rbp-E8h] BYREF
__int64 v9; // [rsp+E0h] [rbp-58h]
__int64 v10; // [rsp+F0h] [rbp-48h]
if ( !a3 )
return 0;
PFace::Init((__int64)packet);
v5 = SMovement::SendEvent(a1, a2, 0x3A09, (unsigned int)&v8, (__int64)packet);
if ( v10 >= 0 )
sub_140213F80(v9, (__int64)aAvwowguid, 4294967290i64, 0);
return v5;
}
WOTLK 3.4.1.48120
0x0F5ED80 The constant in this function is 0x3A10
-
Established Member
Originally Posted by
sanyle
WOTLK 3.4.1.48120
0x0F5ED80 The constant in this function is 0x3A10
Thank you! Sorry was working on the other movement packets for walking
Correct offset is 0x0F5F4E0 for opcode 0x3A09 (CMSG_MOVE_SET_FACING)
0x0F5ED80 is for opcode 0x3A10 (CMSG_MOVE_FORCE_UNROOT_ACK), was doing some tangential testing stuff...
-
Active Member
Originally Posted by
_chase
Just got back to this game (rip). Currently working on packet based, steering motion for super realistic client side movement.
Previously I was using Click to move, which I believe you are referring to. I've been exploring the packet system now, so here's how you can do it with packets instead; This is probably just downstream what the wrapping CTM face to method was effectively doing
Code:
WOTLK 3.4.1.48120 -
FaceTo - 0x0F5F4E0: (active_mover: &Mover, time: GameTime, unk: bool) // unk always true
ActiveMover Guid - 0x2C31368 - (So far always the player's guid, but probabyl changes in vehicles and stuff)
Mover is offset 0x128 into Object
Rotation is offset 0x158 into Object
write to rotation (0x158) desired rotation
call FaceTo(activeMover->mover, game_time(), true)
So far, all opcodes seem accurate in
TrinityCore/Opcodes.h at wotlk_classic . TrinityCore/TrinityCore . GitHub
You can search for the constant and you'll find handler functions for sending the packets. These higher level functions are a nice convenience method.
Code:
// 0x0F5F4E0
char __fastcall PFace(int a1, int a2, char a3)
{
char v5; // bl
char packet[32]; // [rsp+30h] [rbp-108h] BYREF
char v8; // [rsp+50h] [rbp-E8h] BYREF
__int64 v9; // [rsp+E0h] [rbp-58h]
__int64 v10; // [rsp+F0h] [rbp-48h]
if ( !a3 )
return 0;
PFace::Init((__int64)packet);
v5 = SMovement::SendEvent(a1, a2, 0x3A09, (unsigned int)&v8, (__int64)packet);
if ( v10 >= 0 )
sub_140213F80(v9, (__int64)aAvwowguid, 4294967290i64, 0);
return v5;
}
Calling that function while moving cause immediate disconnect. Maybe due to the fact that mover is null when not on any transport? Did u manage to make it work while moving?
-----Edit-----
it seems this happens due to getting out of sync with the server. I wonder why it happens only when character is moving.
Last edited by InnerSilence; 03-09-2023 at 06:28 AM.
-
Originally Posted by
InnerSilence
it seems this happens due to getting out of sync with the server. I wonder why it happens only when character is moving.
Use the correct timestamp. CMovement_C::GetCurrUpdateTime()
-
Post Thanks / Like - 1 Thanks
InnerSilence (1 members gave Thanks to Jadd for this useful post)
-
Active Member
Originally Posted by
Jadd
Use the correct timestamp. CMovement_C::GetCurrUpdateTime()
Thanks, this works, I was getting the time from a func that was used by one of the callers of this function to pass the time, but it seems that time was incorrect!
-
Member
Need i use faceto? Cuz i have crashes when trying OnTerrainClick, when my character is not faced in side of target pos.
-
Member
Hey _chase. Question about PFace
Using the current wrath bin (3.4.3.53622):
- m_activeMover is 142FE0338. its a 128 bit guid. and i can confirm that its the player guid when i call PFace.
- PFace is 141175590
- GetCurrUpdateTime is 141159BA0
PFace is called like this
Code:
call PFace(activeMover->mover, GetCurrUpdateTime(), 1)
What is activeMover and activeMover->mover? Its not m_activeMover, since that's a guid, not a struct. Is activeMover the player object? I thought so, since the player facing angle is at offset 0x158. But then what is activeMover->mover. It can't be the m_activeMover guid since SMovement::SendEvent will dereference it and access some fields in it.
I've done some guessing, none of them work.
- I've tried passing the playerobj to PFace, but then SMovement::SendEvent crashed when it accesses some field of the player obj which happens to be null.
- I tried passing playerobj->mover as the first arg to PFace. but its null, so crash.
- I don't see how m_activeMover is used here. I'm probably not seeing something obvious.
- is PFace and FaceTo different addresses?
Any help is appreciated. Thanks ahead.
--- Edit ---
Can anyone confirm if this is FaceTo in 3.4.3.53622
Code:
__int64 __fastcall sub_141700030(__int64 a1, float a2)
{
__int64 v2; // rdx
__int64 result; // rax
double v4; // xmm1_8
double v5; // xmm2_8
double v6; // xmm0_8
char v7; // bp
char v8; // r14
char v9; // r12
char v10; // r13
char v11; // bl
char v12; // di
char v13; // si
char v14; // r15
__int128 v15; // xmm0
__int128 v16; // [rsp+20h] [rbp-38h] BYREF
result = *(_QWORD *)(a1 + 54576);
if ( result == v2 )
return result;
v4 = 1.0 / (double)(int)*(_QWORD *)(a1 + 54896);
v5 = (double)(int)result * v4;
v6 = (double)(int)v2 * v4;
if ( result > 0 && v5 <= 0.2000000029802322 )
{
v7 = 1;
v8 = 1;
LABEL_10:
Last edited by thateuler; 03-08-2024 at 11:07 AM.
-
Contributor
I've always used the one at 0x142472120 (Pattern: 48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 0F 28 C1)
Code:
__int64 __fastcall sub_142472120(__int64 a1, float a2, char a3)
{
unsigned __int8 v3; // di
__int64 result; // rax
v3 = 0;
if ( fabs(a2 - *(float *)(a1 + 48)) >= 0.00000095367432 )
{
v3 = 1;
*(float *)(a1 + 48) = sub_141292DF0();
if ( ((*(_DWORD *)(a1 + 264) & 0x800) == 0 || (*(_DWORD *)(a1 + 268) & 0x400) != 0)
&& (*(_DWORD *)(a1 + 272) & 4) == 0 )
{
sub_1424739C0(a1, 0i64);
}
}
result = v3;
if ( a3 )
{
*(_DWORD *)(a1 + 264) &= 0xFFFFFFCF;
*(_DWORD *)(a1 + 272) &= ~0x40u;
}
return result;
}
Which takes the movement pointer off the CGUnit_C at 0xF0, the degrees you are going for and 1/0 for updating the movement flags
-
Post Thanks / Like - 1 Thanks
thateuler (1 members gave Thanks to scizzydo for this useful post)
-
Member
Thanks scizzydo. It works perfectly.
It seems that there's a facing angle at obj+0x158 and another at [obj+0xf0]+0x30. I have some code to draw a line between my toon and the target. its red when i'm in front of the target and green when behind. it helps make it easier to make sure i'm behind the boss when i play a melee toon. Sometimes obj+0x158 is wrong. i'll try the latter. (i'm assuming, maybe incorrectly, that npcs also have movedata at obj+0xf0.)
I'm guessing that when the server acks the move update, 0x158 is updated to the angle in f0+30.
Last edited by thateuler; 03-08-2024 at 03:44 PM.
-
Contributor
Only thing with that function is it won't immediately update the server with your facing. If you want that, like the example of facing away from a target, then calling the function to face it, cast a spell (instant for example) and turn back, then you need to call the function or send the packet that updates your movement info to the server.
However, it will change your client facing that will update the server when that certain packet is sent anyway.
-
Member
Originally Posted by
thateuler
Thanks scizzydo. It works perfectly.
It seems that there's a facing angle at obj+0x158 and another at [obj+0xf0]+0x30. I have some code to draw a line between my toon and the target. its red when i'm in front of the target and green when behind. it helps make it easier to make sure i'm behind the boss when i play a melee toon. Sometimes obj+0x158 is wrong. i'll try the latter. (i'm assuming, maybe incorrectly, that npcs also have movedata at obj+0xf0.)
I'm guessing that when the server acks the move update, 0x158 is updated to the angle in f0+30.
Can you tell me the parameters?
It seems to be different from the PFace mentioned above, the first one is LocalplayerPtr, the second one is a float that directly to the Rotation, and the third one is true by default?
And do I need to call a function to notify the server?
-
Contributor
Originally Posted by
helloworld1024
Can you tell me the parameters?
It seems to be different from the PFace mentioned above, the first one is LocalplayerPtr, the second one is a float that directly to the Rotation, and the third one is true by default?
And do I need to call a function to notify the server?
If only you could scroll up a bit more and read... That might be too hard though to find the arguments needed, and answer your other question
-
Member
Originally Posted by
scizzydo
If only you could scroll up a bit more and read... That might be too hard though to find the arguments needed, and answer your other question
Thanks. Riddler.
Another Setfacing function I had forgotten about a long time ago, and the confusion arose because the parameters were different from what I remembered.
__int64 __fastcall CGUnit_C__OnSetRawFacingLocal(_QWORD *a1, unsigned int a2, float a3)
Arguments: locPtr, currupdatetime(), rotation.
Last edited by helloworld1024; 03-25-2024 at 03:33 AM.