01-31-2018, 09:48 AM
(This post was last modified: 01-31-2018, 12:46 PM by TheKillerVortex.)
Hello.
Is anyone aware of how Diablo deals with a player's health?
I've clearly found the 20 bytes (yes: 20!) that pertain directly the the character's health / effective health & maximum health / effective maximum health.
The last 4 bytes I am not sure how is used (that may be apart of what's causing my issues).
Here's what I've gathered (first: A good laugh): Math is killing me!!!
I had Diablo in the background while I was trying to input what I believe will produce 110HP! Only to find my Sorcerer dead on the floor in town.
Desired HP: 100
100(HP) / 4 = 25
25 = 0x00 0x19
Desired HP: 108 (+4 HP more)
108(HP) / 4 = "27"
"27" = 0x00 0x1B
Desired HP: 112 (+4 HP more)
108(HP) / 4 = "27"
"27" = 0x00 0x1B
I can clearly predict how to apply new health using the 2nd byte (divisible by 4).
How would one apply the health of 111? Or 110 (even number)? I thought perhaps this would work:
Desired HP: 110
110(HP) / 2 = 55
55 = 0x37 0x00
Unfortunately, this produces some odd side effects.
The health orb displays: 1 / 0 HP (alive in town).
The lying character screen displays: 0 / 1 HP (alive in town).
The 20th byte went from a usual 0x50 (80); Which usually represents 100% health to: 0x5D (93).
Any ideas? Thanks!
EDIT: I just thought of something real fast... If I can maintain "0x50" on the 20th byte: It should work!
I was close... I modified my health values (all 4) to this:
Unfortunately: It produced half of my desired target of 110HP (52HP generated).
EDIT #2: Now I am REALLY confused! I doubled the first byte and it added +1HP (52 -> 53)????
(Me)
EDIT #3: OK! I think I've figured this out almost all the way (taking quite a bit)...
0xA1 = 26
0x1B = 27
A1 / 2 = 80
A1 + 1B = 107 (rounded: 110?)
OR
0x1B 0xA1 = 7073
(7073 / 8) / 8 = 110
The latter seems to yield more predictable results.
0x1C 0xA1 = 7329
(7329 / 8) / 8 = 114
EDIT #4: Yes... It seems that is the formula. I am just doing something wrong. I almost have this down!
I predicted that the target "113" HP would be:
0x37 0x1C
It yielded 112HP (off by 1).
The correct answer:
0x40 0x1C!
EDIT #5: Yup! Close, but just off by 1! Frustrating.
Target HP: 133 (odd number)
Idea: Multiply target HP by 4
Split value into two bytes represented in hex
EG: 0x214 = 0x04 0x21
Turns out (maybe I read it wrong?) the answer is: 0x40 0x21!
EDIT #6: Yes! I absolutely have the answer now. The only problem is: I do not know how to mathematically (programatically) explain what I am doing.
The 20th byte remains at 0x50 (80); I am not sure how "80" represents 100% health, but I may be incorrect on what it's purpose is.
... In fact: You can use the latter formula to calculate evenly divisible numbers (it comes out all the same).
100 -> 400 -> 25 (0x19 to the 2nd byte)
... This is actually incorrect. Although it is the closest thing to an accurate solution I've come up with yet.
I feel stuck on figuring out what the formula is or how to extract it. Any pointers (no jokes please!) or help would be appreciated.
EDIT #???: Oh... You can just simply multiply the desired HP by 4 and use only base-16 (no division necessary).
EDIT: I would love to know how to solve this mathematically and pragmatically. I am assuming in C: You would solve this with either bit shifting or the modulus operator.
However: Using only pencil and paper: I am failing to come up with a solution here.
123 * 4 = 492
492 / 16 = 30
This is the first value we need to extract (to write to the 2nd byte). 0x1E
How do you extract the other digit? 0x0C! This has me stumped. I can almost describe what it is I am trying to do, but I cannot quite put my tongue on it.
Another (with a calculator, of course) method that I've been successfully using is to do this:
Target HP = 983
983 * 4 = 3932 (0xF5C)
3932 * 16 = 0xF5 0xC0
0xC0 0xF5 0x00 0x00 yields our results in-game! 983.
Is anyone aware of how Diablo deals with a player's health?
I've clearly found the 20 bytes (yes: 20!) that pertain directly the the character's health / effective health & maximum health / effective maximum health.
The last 4 bytes I am not sure how is used (that may be apart of what's causing my issues).
Here's what I've gathered (first: A good laugh): Math is killing me!!!
I had Diablo in the background while I was trying to input what I believe will produce 110HP! Only to find my Sorcerer dead on the floor in town.
Desired HP: 100
100(HP) / 4 = 25
25 = 0x00 0x19
Desired HP: 108 (+4 HP more)
108(HP) / 4 = "27"
"27" = 0x00 0x1B
Desired HP: 112 (+4 HP more)
108(HP) / 4 = "27"
"27" = 0x00 0x1B
I can clearly predict how to apply new health using the 2nd byte (divisible by 4).
How would one apply the health of 111? Or 110 (even number)? I thought perhaps this would work:
Desired HP: 110
110(HP) / 2 = 55
55 = 0x37 0x00
Unfortunately, this produces some odd side effects.
The health orb displays: 1 / 0 HP (alive in town).
The lying character screen displays: 0 / 1 HP (alive in town).
The 20th byte went from a usual 0x50 (80); Which usually represents 100% health to: 0x5D (93).
Any ideas? Thanks!
EDIT: I just thought of something real fast... If I can maintain "0x50" on the 20th byte: It should work!
I was close... I modified my health values (all 4) to this:
Code:
006865D8 - 37 0D 00 00 37 0D 00 00 37 0D 00 00 37 0D 00 00 7...7...7...7...
Unfortunately: It produced half of my desired target of 110HP (52HP generated).
EDIT #2: Now I am REALLY confused! I doubled the first byte and it added +1HP (52 -> 53)????
(Me)
Quote:When the 1st byte is: 0
The 2nd byte is treated as divisible by 4.
When the first byte is NOT 0: It is divisible by 2
The second byte increments by +1
EDIT #3: OK! I think I've figured this out almost all the way (taking quite a bit)...
Code:
006865D8 - A1 1B 00 00 A1 1B 00 00 A1 1B 00 00 A1 1B 00 00 ¡...¡...¡...¡...
0xA1 = 26
0x1B = 27
A1 / 2 = 80
A1 + 1B = 107 (rounded: 110?)
OR
0x1B 0xA1 = 7073
(7073 / 8) / 8 = 110
The latter seems to yield more predictable results.
0x1C 0xA1 = 7329
(7329 / 8) / 8 = 114
EDIT #4: Yes... It seems that is the formula. I am just doing something wrong. I almost have this down!
I predicted that the target "113" HP would be:
0x37 0x1C
It yielded 112HP (off by 1).
The correct answer:
0x40 0x1C!
EDIT #5: Yup! Close, but just off by 1! Frustrating.
Target HP: 133 (odd number)
Idea: Multiply target HP by 4
Split value into two bytes represented in hex
EG: 0x214 = 0x04 0x21
Turns out (maybe I read it wrong?) the answer is: 0x40 0x21!
EDIT #6: Yes! I absolutely have the answer now. The only problem is: I do not know how to mathematically (programatically) explain what I am doing.
Code:
Is the desired HP divisible by 4 evenly?
Step 1: Divide target HP by 4 (100 -> 25)
Step 2: Write 00 to the first byte; Write quotient (25 or 0x19) to the second byte
Is the desired HP an odd number (not divisible ending in a whole number for a quotient)?
Step 1: Multiply target HP by 4 (123 (7B) -> 492 (1EC))
Step 2: Divide by 16 (quotient: 30 (0x1E))
Step 3: Write quotient to the 2nd byte (30 (0x1E))
Step 4: Write the ???? to the 1st byte (12 (0x1C))
The 20th byte remains at 0x50 (80); I am not sure how "80" represents 100% health, but I may be incorrect on what it's purpose is.
... In fact: You can use the latter formula to calculate evenly divisible numbers (it comes out all the same).
100 -> 400 -> 25 (0x19 to the 2nd byte)
... This is actually incorrect. Although it is the closest thing to an accurate solution I've come up with yet.
I feel stuck on figuring out what the formula is or how to extract it. Any pointers (no jokes please!) or help would be appreciated.
EDIT #???: Oh... You can just simply multiply the desired HP by 4 and use only base-16 (no division necessary).
EDIT: I would love to know how to solve this mathematically and pragmatically. I am assuming in C: You would solve this with either bit shifting or the modulus operator.
However: Using only pencil and paper: I am failing to come up with a solution here.
123 * 4 = 492
492 / 16 = 30
This is the first value we need to extract (to write to the 2nd byte). 0x1E
How do you extract the other digit? 0x0C! This has me stumped. I can almost describe what it is I am trying to do, but I cannot quite put my tongue on it.
Another (with a calculator, of course) method that I've been successfully using is to do this:
Target HP = 983
983 * 4 = 3932 (0xF5C)
3932 * 16 = 0xF5 0xC0
0xC0 0xF5 0x00 0x00 yields our results in-game! 983.