liveoverflow_youtube icon indicating copy to clipboard operation
liveoverflow_youtube copied to clipboard

Pwn Adventure 3 Fly Not Working Issue

Open RetroGamesEngineer opened this issue 5 years ago • 0 comments

Hi LiveOverflow I saw your latest Pwn Adventure 3 video and saw that you didn't quite get the Fly cheat you wanted working even with the help of another youtuber.

So I decided to give it a go as well and today I reached the solution!

I also then converted it to a cheat engine auto assembler script using pure code injection (instead of dll injection) just for fun.

See my repo here: https://github.com/RetroGamesEngineer/LOPWN

The .cpp and .h file for the cpp version... or the .cea for the cheat engine asm version Or a directly copy and paste-able version below.

Yea perhaps it can be vectorized to make it a bit faster by adding or multiplying to multiple values at once, and/or using a faster sin & cos than built into x86 fsincos instruction but it's really not necessary as it's fast enough for these purposes.

:D

Copy and paste-able directly into CE's CheatTable list:

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>11</ID>
      <Description>"Pwn Fly"</Description>
      <LastState/>
      <VariableType>Auto Assembler Script</VariableType>
      <AssemblerScript>[enable]
//RetroGamesEngineer on github (C) 2019
alloc(FlyThread,$1000)
registersymbol(FlyThread)
createthread(FlyThreadStart)

define(VK_F1,70) //Toggle on/off
define(VK_MBUTTON,4) //Trigger Flying

struct rot
pitch: dd ?
yaw: dd ?
pitchcos: dd ?
pitchsin: dd ?
yawcos: dd ?
yawsin: dd ?
endstruct

struct vec3
x: dd ?
y: dd ?
z: dd ?
endstruct

FlyThread:
label(NewPlayerPosition) //Forcing good alignment for NewPlayerPosition (so movaps works fine)
NewPlayerPosition:
dd 0 0 0 0
label(FlyEnabled)
FlyEnabled:
dd 1
label(FlyActive)
FlyActive:
dd 0
label(FlySpeed)
FlySpeed:
dd (float)33.33

label(FlyThreadStart)
FlyThreadStart:
push 1
call Sleep
//Get Pointers on initially starting thread before proceeding to main loop
//"PitchYaw","[[[[[['GameLogic.dll']+97d80]+58]+1cc]+294]+2a0]"
mov eax,[GameLogic.Game] //Same as
//mov eax,["GameLogic.dll"+97d80] // &lt;--
test eax,eax
je @b
mov eax,[eax+58]
test eax,eax
je @b
mov eax,[eax+1cc]
test eax,eax
je @b
mov eax,[eax+294]
test eax,eax
je @b
lea eax,[eax+2a0]
mov [PitchYawPointer],eax
//"PlayerPosition","[[[[[['GameLogic.dll']+97d7c]+1c]+4]+114]+90]"
mov eax,[GameLogic.GameWorld] //Same as
//mov eax,["GameLogic.dll"+97d7c] &lt;--
test eax,eax
je @b
mov eax,[eax+1c]
test eax,eax
je @b
mov eax,[eax+4]
test eax,eax
je @b
mov eax,[eax+114]
test eax,eax
je @b
lea eax,[eax+90]
mov [PlayerPositionPointer],eax

label(FlyThreadLoop)
FlyThreadLoop:
push 1
call Sleep
cmp [FlyEnabled],0 //Exit thread upon disabling
je FlyThreadExit
push VK_F1
call GetAsyncKeyState
and ax,8000
je @f
xor [FlyActive],1 //Toggle Fly on/off
push #337
call Sleep
@@:
cmp [FlyActive],1 //Only Fly if activated
jne FlyThreadLoop
push VK_MBUTTON  //And Middle Mouse Button is pressed
call GetAsyncKeyState
and ax,8000
je FlyThreadLoop

mov eax,[PitchYawPointer]
mov edx,PitchYaw
//Get pitch sin &amp; cos
fld dword [eax+pitch]
fmul dword [PI_divided_by_180] //Degrees to radians
fsincos
fstp dword [edx+pitchcos]
fstp dword [edx+pitchsin]
//Get yaw sin &amp; cos
fld dword [eax+yaw]
fsub dword [Ninety] //rot.yaw - 90.0f
fmul dword [PI_divided_by_180] //Degrees to radians
fsincos
fstp dword [edx+yawcos]
fstp dword [edx+yawsin]

mov ebx,[PlayerPositionPointer]
mov ecx,NewPlayerPosition
//Calculate new x coordinate
xorps xmm0,xmm0
subss xmm0,[edx+yawsin]   // -(sinf(DegreesToRadians(rot.yaw-90.0f)))
mulss xmm0,[edx+pitchcos] // * cosf(DegreesToRadians(rot.pitch)
mulss xmm0,[FlySpeed]     // * FlySpeed
addss xmm0,[ebx+x]        // + PlayerPosition.x ==
movss [ecx+x],xmm0        //Store in NewPlayerPosition.x
//Calculate new y coordinate
movss xmm0,[edx+yawcos]   // cosf(DegreesToRadians(rot.yaw-90.0f)
mulss xmm0,[edx+pitchcos] // * cosf(DegreesToRadians(rot.pitch)
mulss xmm0,[FlySpeed]     // * FlySpeed
addss xmm0,[ebx+y]        // + PlayerPosition.y ==
movss [ecx+y],xmm0        //Store in NewPlayerPosition.y
//Calculate new z coordinate
movss xmm0,[edx+pitchsin] // sinf(DegreesToRadians(rot.pitch))
mulss xmm0,[FlySpeed]     // * FlySpeed
addss xmm0,[ebx+z]        // + PlayerPosition.z ==
movss [ecx+z],xmm0        //Store in NewPlayerPosition.z

//Write new player position to current player position! :)
movaps xmm0,[ecx]
movaps [ebx],xmm0
jmp FlyThreadLoop

label(FlyThreadExit)
FlyThreadExit:
ret

label(PI_divided_by_180)
PI_divided_by_180:
dd (float)0.0174532

label(Ninety)
Ninety:
dd (float)90.0

label(PitchYaw)
PitchYaw:
dd 0 0 0 0 0 0

label(PitchYawPointer)
PitchYawPointer:
dd 0

label(PlayerPositionPointer)
PlayerPositionPointer:
dd 0

[disable]

FlyThread+10: //Causes FlyThread to exit
dd 0

unregistersymbol(FlyThread)
</AssemblerScript>
      <CheatEntries>
        <CheatEntry>
          <ID>13</ID>
          <Description>"NewPlayerPosition.x"</Description>
          <VariableType>Float</VariableType>
          <Address>FlyThread</Address>
        </CheatEntry>
        <CheatEntry>
          <ID>14</ID>
          <Description>"NewPlayerPosition.y"</Description>
          <VariableType>Float</VariableType>
          <Address>FlyThread+4</Address>
        </CheatEntry>
        <CheatEntry>
          <ID>15</ID>
          <Description>"NewPlayerPosition.z"</Description>
          <VariableType>Float</VariableType>
          <Address>FlyThread+8</Address>
        </CheatEntry>
        <CheatEntry>
          <ID>16</ID>
          <Description>"FlyEnabled"</Description>
          <VariableType>4 Bytes</VariableType>
          <Address>FlyThread+10</Address>
        </CheatEntry>
        <CheatEntry>
          <ID>17</ID>
          <Description>"FlyActive"</Description>
          <VariableType>4 Bytes</VariableType>
          <Address>FlyThread+14</Address>
        </CheatEntry>
        <CheatEntry>
          <ID>18</ID>
          <Description>"FlySpeed"</Description>
          <VariableType>Float</VariableType>
          <Address>FlyThread+18</Address>
        </CheatEntry>
      </CheatEntries>
    </CheatEntry>
  </CheatEntries>
</CheatTable>

RetroGamesEngineer avatar Nov 12 '19 08:11 RetroGamesEngineer