-
Contributor
Originally Posted by
natemiddleman
This is driving me nuts. I have two different tiles with 0x30 % 7 = 3 that need to be rotated differently. Reading 0x30 as a byte and short was the same. Maybe it needs to be read as an int or long but the server shut down before I had a chance to test it. I probably won't do much work for at least a week after league start.
Working things out for yourself is certainly important, but I think you're on the wrong track now
zaafar is on the right track with some of the functions posted, but there's more to the system, so he's maybe like 3/4 of the way done with what's been posted
The FUN_140ba8350 function is a helper function, and the subfunction inside, FUN_140c438a0 is another helper function
However, neither of those are 'GetHeightAt', so some more reversing is required to see how those helper functions are used
Once you have GetHeightAt + Helper1 + Helper2 you can start to make sense of the system I suppose, but it's not terribly important unless you want to do 3d world building
As it pertains to bots and the like, your next goal is to come up with a WorldToScreen or ScreenToWorld function so you can use the height, but if you think about the way the game works, if you just replicate what the client does, you don't have to guess or even understand what the underlying math is doing, because it'll be correct (ofc it's useful to at least know where all the data is coming from)
So for example, if I use GetHeightAt + use a correct WorldToScreen, the mouse position is pixel perfect. I don't know the specifics of rotations or what everything means, but I don't really need to since I'm doing what the client does and the observed result certainly looks correct
-
i am going to pause my reverse engineering activity and resume it after 1 week into the game. sorry for that.
-
Member
@zaafar
Same. I got Ghidra running and now I just need to figure out how to associate memory addresses with functions but that will have to wait.
@pushedx
I have a WorldToScreen function working which is why I need the height and I'd rather not use the in game function (not that I know how to in the first place).
-
Contributor
Originally Posted by
natemiddleman
@
pushedx
I have a WorldToScreen function working which is why I need the height and I'd rather not use the in game function (not that I know how to in the first place).
I'm not saying call the game's function, but rather work through it as zaafar is rather than try to play around with some of the stuff you've posted
-
-> Same. I got Ghidra running and now I just need to figure out how to associate memory addresses with functions but that will have to wait.
i do that by taking first X (0xXX 0xXX 0xXX) bytes of the function and searching it in Ghidra.
Ghidra -> Search -> instruction pattern
in that click "pencil button"
don't forget to change Binary to HEX.
EDIT: u can get first few bytes of the function by right clicking function byte in CE and selecting "Highlight current function" <---- this is a CE feature.
-
Member
Originally Posted by
zaafar
-> Same. I got Ghidra running and now I just need to figure out how to associate memory addresses with functions but that will have to wait.
i do that by taking first X (0xXX 0xXX 0xXX) bytes of the function and searching it in Ghidra.
Ghidra -> Search -> instruction pattern
in that click "pencil button"
don't forget to change Binary to HEX.
EDIT: u can get first few bytes of the function by right clicking function byte in CE and selecting "Highlight current function" <---- this is a CE feature.
You can just deduct the base image address from the function address.
eg. function address: 0x7ff71337888
then just change address in cheat engine to: 0x7ff71337888 - "PathOfExile_x64.exe" to get relative address.
Rebase the exe in ghidra from 0x140000000 to 0x0
then just press g to go to the relative addresss
-
Originally Posted by
NoobToken
You can just deduct the base image address from the function address.
eg. function address: 0x7ff71337888
then just change address in cheat engine to: 0x7ff71337888 - "PathOfExile_x64.exe" to get relative address.
Rebase the exe in ghidra from 0x140000000 to 0x0
then just press g to go to the relative addresss
that works 99% of the time (and i do that all the time) but sometime relative address in exe is different from relative address in running process. no idea why but that's what happening to me.
-
Active Member
I am finding height map during last three weeks, too. Thanks to @pushedx's tips(long long ago).
I already found the height map last week, and reversing the process about GridPos->Height.
Code:
v5 = *(_QWORD *)(a1TerrainData + 0x28) + 0x38 * (v2GridPosX / 23 + *(_QWORD *)(a1TerrainData + 0x18) * (v4GridPosY / 23));//
got v5, and need to
Code:
v6 = *(__int64 **)v5;
return *(_DWORD *)(v3TerrainData + 0x80) * *(signed __int16 *)(v5 + 0x30)//
+ (unsigned int)GetHeightINTFunction(v6,*(_BYTE *)(v5 + 0x36));//
What I wonder is that the final height is positive, and the real height is negative? but the number is equal.
What about you, @zaafar @natemiddleman?
Last edited by Aoooooooo; 06-09-2021 at 01:49 AM.
Reason: something not necessary and wrong
-
Contributor
Originally Posted by
Aoooooooo
What I wonder is that the final height is positive, and the real height is negative? but the number is equal.
Yes, you have to take the negative of the height to correctly use it in WorldToScreen mapping.
-
Post Thanks / Like - 1 Thanks
Aoooooooo (1 members gave Thanks to pushedx for this useful post)
-
Active Member
Last edited by Aoooooooo; 05-03-2021 at 09:04 AM.
-
Active Member
-
Member
Just FYI for anyone that tries to figure this out later, 00+ is offset above ground level while FF- is offset below ground level.
This gave me quite a headache trying to figure why there were cliffs in the hightmap where it should have been flat.
-
Originally Posted by
Aoooooooo
I am finding height map during last three weeks, too. Thanks to @
pushedx's tips(long long ago).
I already found the height map last week, and reversing the process about GridPos->Height.
Code:
v5 = *(_QWORD *)(a1TerrainData + 0x28) + 0x38 * (v2GridPosX / 23 + *(_QWORD *)(a1TerrainData + 0x18) * (v4GridPosY / 23));//
got v5, and need to
Code:
v6 = *(__int64 **)v5;
v8 = v2GridPosX % 23;
return *(_DWORD *)(v3TerrainData + 0x80) * *(signed __int16 *)(v5 + 0x30)//
//
// *(_DWORD *)(v3 + 0x80) = 0x1 In liones's Watch
+ (unsigned int)GetHeightINTFunction(v6, &v8, *(_BYTE *)(v5 + 0x36));//
got the Return Int type Height, need to multiply a float number 7.8 , then got the real height,
What I wonder is that the final height is positive, and the real height is negative? but the number is equal.
What about you, @
zaafar @
natemiddleman?
nah, still playing the game so didn't get a chance to continue doing this. Also, I have a different goal I need to complete before I can get back to calculating height.
This league i noticed that it takes me 2 - 4 hours to update my private HUD offsets (or validate that private hud offsets are fine) and at league start those 2 - 4 hours can be important. So right now I am creating (configuring actually ~ the tool already exists in private) an executable code static analysis tool which will help me automatically reverse engineer 90% - 99% of the known offsets at league start. Once I have completed that and validated that next league start won't fuck me up then I will continue back to finding height.
Quick question, I don't see you rotating the height. where are you doing that? Basically when i say rotation I mean the following.
let's say following is the 23x23 tile.
1 2 3 4
5 6 7 8
9 0 A B
C D E F
now when game loads this tile on the map, the tile might be rotated to 90 degree (counter-clockwise) as shown below.
4 8 B C
3 7 A D
2 6 0 E
1 5 9 F
so, lets say u want height of the top - left side of the tile. Now if you don't rotate, you get height of "1" which is wrong. only after you rotate you will get height of "4" which is correct. Rotation info is also stored in the memory.
let me know if you don't understand my question.
Last edited by GameHelper; 05-05-2021 at 03:25 AM.
-
Member
Rotation is a byte at 0x36 so I am assuming (unsigned int)GetHeightINTFunction(v6, &v8, *(_BYTE *)(v5 + 0x36)) is where that is taken into account. I have not been able to fully test it but I have height calculations working without a problem so far. I can probably provide any assistance if you need it but it should be fairly simple given how much has been worked out in this thread.
-
Post Thanks / Like - 1 Thanks
GameHelper (1 members gave Thanks to natemiddleman for this useful post)
-
Active Member
Originally Posted by
zaafar
nah, still playing the game so didn't get a chance to continue doing this. Also, I have a different goal I need to complete before I can get back to calculating height.
This league i noticed that it takes me 2 - 4 hours to update my private HUD offsets (or validate that private hud offsets are fine) and at league start those 2 - 4 hours can be important. So right now I am creating (configuring actually ~ the tool already exists in private) an executable code static analysis tool which will help me automatically reverse engineer 90% - 99% of the known offsets at league start. Once I have completed that and validated that next league start won't fuck me up then I will continue back to finding height.
Quick question, I don't see you rotating the height. where are you doing that? Basically when i say rotation I mean the following.
let's say following is the 23x23 tile.
1 2 3 4
5 6 7 8
9 0 A B
C D E F
now when game loads this tile on the map, the tile might be rotated to 90 degree (counter-clockwise) as shown below.
4 8 B C
3 7 A D
2 6 0 E
1 5 9 F
so, lets say u want height of the top - left side of the tile. Now if you don't rotate, you get height of "1" which is wrong. only after you rotate you will get height of "4" which is correct. Rotation info is also stored in the memory.
let me know if you don't understand my question.
It changed again.
Last edited by Aoooooooo; 07-18-2021 at 04:31 AM.
Reason: Update Information