Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


How Can I Do A CMP Between 25% of Max HP and True HP?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Gear2ndGandalf
Cheater
Reputation: 0

Joined: 22 Jan 2018
Posts: 36
Location: USA

PostPosted: Sun Jun 02, 2024 5:42 pm    Post subject: How Can I Do A CMP Between 25% of Max HP and True HP? Reply with quote

Like a prior topic of mine, I'm having an issue but on Silent Hill 3 with an hp regen script. I want it to regenerate quicker when health is critical; Below or equal to 25% of max health.

Max HP float varies between 200.00, 100.00, and 50.00 depending on difficulty.

I would like to compare 1/4 of max hp against true hp to determine whether critRegen or slowRegen will be used.

No matter what my health is the code jumps to healCrit.

[00898664] = Max HP
[00898660] = True HP


Code:
{ Game   : sh3.exe
  Version: 1.0
  Date   : 2024-06-02
  Author : Gear2

  Regen to max hp.
  When health is at or below 25% of max hp we will use critRegen.
  Otherwise slowRegen will be used.
}

[ENABLE]

aobscanmodule(totalHpRegen,sh3.exe,D9 81 74 01 00 00)
alloc(newmem,2048)
alloc(critRegen,4)
alloc(slowRegen,4)
alloc(timer,4)
alloc(percentCrit,8)
alloc(percentMax,8)

label(begin)
label(damaged)
label(count)
label(checkCrit)
label(healCrit)
label(healHP)
label(code)
label(return)

critRegen:
  dd (float)0.0025

slowRegen:
  dd (float)0.0001

timerCounter:
  dd 0

percentCrit:
  dq (double)25

percentMax:
  dq (double)100

newmem:
  fld dword ptr [ecx+00000174]
  push ebx
  push edx
  mov edx,[00898664]
  mov ebx,[00898660]
  cmp ebx,edx
  pop edx
  pop ebx
  jb begin
  jmp return

begin:
  cmp [0712C663],0
  jnz damaged
  jmp count

damaged:
  mov dword ptr [timer],500
  jmp return

count:
  cmp dword ptr [timer],0
  jle checkCrit
  dec dword ptr [timer]
  jmp return

checkCrit:
  cvtsi2sd xmm0,[00898664]
  mulsd xmm0,[percentCrit]
  divsd xmm0,[percentMax]
  cvttsd2si eax,xmm0
  cmp eax,[00898660]
  jle healCrit
  jmp healHP

healCrit:
  fld dword ptr [00898660]
  fadd dword ptr [critRegen]
  fstp dword ptr [00898660]
  jmp return

healHP:
  fld dword ptr [00898660]
  fadd dword ptr [slowRegen]
  fstp dword ptr [00898660]
  jmp return

code:
  //fld dword ptr [ecx+00000174]
  //jmp return

totalHpRegen:
  jmp newmem
  nop
return:
registersymbol(totalHpRegen)
registersymbol(critRegen)
registersymbol(slowRegen)
registersymbol(timer)

[DISABLE]

totalHpRegen:
  db D9 81 74 01 00 00

unregistersymbol(*)
dealloc(*)
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 150

Joined: 06 Jul 2014
Posts: 4657

PostPosted: Sun Jun 02, 2024 7:08 pm    Post subject: Reply with quote

You should really use game.exe+1234 instead of literal addresses

Don't mix SSE and x87; use whatever the game uses

What type is maxhp / hp? You're treating it as both an integer (SSE code) and a float (x87 code)

What's at 0712C663? Is that set to some nonzero value when you take damage? I doubt that's an unaligned 4-byte value; maybe it's a 1-byte value?

That's 0x500, or 1280.

Instead of using the semantic equivalent of fixed point arithmetic, how about you use actual percentages? 25% = 0.25


I guess maxHP / HP is a float because you included a fractional part in your example.
Something like this:
Code:
define(currentHP,00898660) // should really be game.exe+something
define(maxHP,00898664)

...

percentCrit:
  dd (float)0.25

newmem:
// only regen if hp < maxhp
  fld dword ptr [currentHP]
  fld dword ptr [maxHP]
  fcomi st,st(1)
  ja checkDamaged
  fstp st(0)
  fstp st(0)
  jmp code

checkDamaged:
// reset regen timer if damaged
  cmp byte ptr [0712C663],0
  je checkTimeSinceDamaged
  fstp st(0)
  fstp st(0)
  mov dword ptr [timer],#500
  jmp code

checkTimeSinceDamaged:
// wait to regen after taking damage
  cmp dword ptr [timer],0
  jg decreaseTimer
// checkCriticalHP
// big regen if below 25% HP
  fmul dword ptr [percentCrit]  // st(0) = maxHP * percentCrit
  fcomip st,st(1)  // pop critHP after cmp
  ja useCriticalRegen  // if critHP > currentHP, big regen
  fld dword ptr [slowRegen]  // otherwise, slow regen
addHealth:
  faddp   // add regen to currentHP, pop regen
  fstp dword ptr [currentHP]
  jmp code
useCriticalRegen:
  fld dword ptr [critRegen]
  jmp addHealth

decreaseTimer:
  fstp st(0)
  fstp st(0)
  dec dword ptr[timer]

code:
  fld dword ptr [ecx+174]
  jmp return

...

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Gear2ndGandalf
Cheater
Reputation: 0

Joined: 22 Jan 2018
Posts: 36
Location: USA

PostPosted: Sun Jun 02, 2024 7:45 pm    Post subject: Reply with quote

You are on fire Penguin it works 100%. I've tried a hundred things with chat gpt and ended up with sse mixed with x87. Anything to get it to work.

Even if it didn't look right.

The initial code worked fine aside from checkCrit: code. HP would regen but I wanted two seperate regen speeds.

My code was like this before messing with AI...

Code:

...
newmem:
  fld dword ptr [ecx+00000174]
  push ebx
  push edx
  mov edx,[00898664]
  mov ebx,[00898660]
  cmp ebx,edx
  pop edx
  pop ebx
  jb begin
  jmp return

begin:
  cmp [0712C663],0
  jnz damaged
  jmp count

damaged:
  mov dword ptr [timerCounter],500
  jmp return

count:
  cmp dword ptr [timerCounter],0
  jle checkCrit
  dec dword ptr [timerCounter]
  jmp return

checkCrit:
  push eax
  push ecx
  mov ecx,4
  mov eax,[00898664]
  div ecx,eax
  cmp eax,[00898660]
  pop ecx
  pop eax
  jl healCrit
  jmp healHP

healCrit:
  fld dword ptr [00898660]
  fadd dword ptr [critRegen]
  fstp dword ptr [00898660]
  jmp return

healHP:
  fld dword ptr [00898660]
  fadd dword ptr [lowRegen]
  fstp dword ptr [00898660]
  jmp return

code:
  //fld dword ptr [ecx+00000174]
  //jmp return

...


Hey really thanks!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites