  | 
				
				Cheat Engine The Official Site of Cheat Engine   
				
 
				 | 
			 
		 
		 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		Gear2ndGandalf Cheater
  Reputation: 0
  Joined: 22 Jan 2018 Posts: 36 Location: USA
  | 
		
			
				 Posted: Sun Jun 02, 2024 5:42 pm    Post subject: How Can I Do A CMP Between 25% of Max HP and True HP? | 
				       | 
			 
			
				
  | 
			 
			
				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 | 
		 | 
	 
	
		  | 
	 
	
		ParkourPenguin I post too much
  Reputation: 152
  Joined: 06 Jul 2014 Posts: 4706
 
  | 
		
			
				 Posted: Sun Jun 02, 2024 7:08 pm    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				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 | 
		 | 
	 
	
		  | 
	 
	
		Gear2ndGandalf Cheater
  Reputation: 0
  Joined: 22 Jan 2018 Posts: 36 Location: USA
  | 
		
			
				 Posted: Sun Jun 02, 2024 7:45 pm    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				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 | 
		 | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
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
  | 
   
 
		 |