Hi all,
I'm having some difficulty getting World::Intersect to work in 1.12.
I am calling it like this (this is pseudocode for the actual code but verified with a debugger):
Code:
float[] points = {p1x, p1y, p1z, p2x, p2y, p2z};
float[] intersect = {0, 0, 0};
float distance = 1.0f; // Tried different values, like 10.0f too, in case it's not the usual normalized parameter
int flags = 0x1e; // Tried many others, including 7fffffff, some suggested by Apoc, etc.
// I call it as a fastcall, first 2 args are in ecx, edx, next two on the stack
// Actually I reserve memory for intersect, zero it and pass the pointer
// EDIT: prototype
sub_6aa160(points, &distance, intersect, flags);
The function proceeds to calculate the distance between p1 and p2 (correctly) but starts calling other functions and I end up losing it.
It always returns (as a byte) 0x00 and as an Int I sometimes see 0x6a0000 (if 0F000FFh & flags == 0) or 0x1900 otherwise.
EDIT: After using the right prototype it returns proper booleans but it always comes out as zero.
I've tried to raycast from char to ground or between walls of a house, with identical results always. Adding Player.Height to Z components doesn't make a difference.
First of all, from a recent post in 1.12's thread:
So World::Intersect located at 0x6AA160. It's a little bit different from traceline that we all know, it takes 4 parameters World::Intersect(Vector3[] Line, &Vector3 Intersection, float Distance, int Flags). And flags are different too, didn't check them all.
After inspection of the function, I see it's fastcall with Vector3[] Line referring to 6 float's with layout:
Code:
struct arg1 {x1, y1, z1, x2, y2, z2}
As demonstrated by:
Code:
.text:006AA166 mov esi, ecx
.text:006AA168 fld dword ptr [esi+0Ch]
.text:006AA16B xor bl, bl
.text:006AA16D fsub dword ptr [esi]
.text:006AA16F mov [ebp+var_4], edx
.text:006AA172 fld dword ptr [esi+10h]
.text:006AA175 fsub dword ptr [esi+4]
.text:006AA178 fld dword ptr [esi+14h]
.text:006AA17B fsub dword ptr [esi+8]
The second (EDIT: third) argument I guess it's an out parameter with room for 3 floats to be filled with the intersection, if we detect one. Because the function always returns (BYTE) 0x00, I've never seen the supposedly out parameter get filled with anything and it remains set to {0.0f, 0.0f...}.
4th parameter should indeed refer to flags (it's 2nd on the stack due to fastcall):
Code:
(...)
.text:006AA1AE mov edi, [ebp+arg_4]
.text:006AA1B1 test edi, 0F000FFh
.text:006AA1B7 jz short loc_6AA1CA
(...)
.text:006AA1CA test edi, 0F00F0Fh
.text:006AA1D0 jz short loc_6AA1E0
(...)
I include all this because I've seen different signatures for this function in newer versions and I wanted to establish this first, if you see any mistakes (including calling the wrong function!) please correct me. Also the layout of the function is different from the Alpha's (CWorld::Intersect), which is a rather short function that calls CMap::VectorIntersect and returns its result.
Thanks