|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Cissamannen Cheater Reputation: 0
Joined: 16 Jul 2009 Posts: 36
|
Posted: Thu Sep 02, 2021 4:03 am Post subject: Conditional Value Change & AOB Values |
|
|
Hey there, again.
2 part question but somewhat follows for same game.
Part 1:
Using old gameshark codes works fine here, by altering the offsets by say +1000 so I have already done that for my table, my main issue is, some codes will break the game if always enabled, hence I need a way to get the conditional way to work, and I guess lua be the way to go.
So for example:
if 1000E11B8 = 1 (Byte)
then 1000EDF38 = 999(int)/03E7 (frozen or not doesnt matter i believe)
if 1000E11B8 is not 1
then 1000EDF38 = what game changes it to be
1000E11B8 = 1 is basically the flag for being in battle
Taking from ParkourPenguin in another post by setting this as an AA script:
Code: | {$lua}
[ENABLE]
if readByte(0x1000EDF38) == 1 then
writeSmallInteger(0x1000EDF38, 999)
end
[DISABLE]
-- lua code - |
what would the disabled way be? And would this code in general, always change it whenever the readbyte offset is 1 in memory until script is disabled?
_____________________________________
Part 2
The other problem here is, some codes are also stored in the static offsets, but some of these areas are protected and I must aob scan to find the correct offset (which always ends in same 4 digits of the offset). The other problem there is, since this location is stored in physical memory and not via the emulator app itself, i cannot make it aob scan through that injection way.
Is there a way to scan for certain AOB ways?
Example:
Having offset 100017EB6 shows the value correct, but it cannot be changed. AOB scanning C2 A0 08 00 E0 03 shows the results, always showing 2 offsets which are identical in a long strong. Meaning its always the 2nd offset found that is correct as it ends in xxxx7EB6. The value stored there can then be changed normally and it will reflect on the 100017EB6 offset too (and also work in game).
Is there a way to scan for that offset via lua then, and have it use 2nd option (or if i have to, use a long long string to find it so its single result)? If yes, can it then be defined into a name so I can set that as address and have the value always found correctly this way without aob scanning manually each time I boot the emulator again?
Knowing the basics of these 2 will fix most if not all these issues I've been trying to overcome.
Thanks in advance!
P.S: Yes setting compiler to interpreter would allow me to change the locked offset directly, but the offsets gets scrambled everytime then, meaning I have to adjust the header offset on every boot. Figured having a script to search the bytes instead would make it easier through all the games.
|
|
Back to top |
|
|
Birdi Expert Cheater Reputation: 0
Joined: 08 Jun 2020 Posts: 122 Location: Migrating
|
Posted: Thu Sep 02, 2021 4:51 am Post subject: |
|
|
1:
You'd need to set a timer to constantly read that address, otherwise it is only going to be run a single time, when you enable it. Enabling the timer which calls a function to do so is enough for the Enable section, and disabling it can reset it just as easily.
This could be headed in the main table lua script, and should use proper local variables but I'm on phone, so best I can offer right now.
You can use variables to store the addresses if you need to evaluate them as well, obviously.
Code: |
[ENABLE]
{$lua}
function checkValue()
if readByte(0x1000EDF38) == 1 then
writeSmallInteger(0x1000EDF38, 999)
end
end
oldValue = readBytes(0x1000EDF38,2) --use 4 bytes & writeInteger if you need that instead
valTimer = createTimer(MainForm, false)
valTimer.Interval = 1
valTimer.OnTimer = checkValue
valTimer.Enabled = true
{$asm}
[DISABLE]
{$lua}
writeSmallInteger(0x1000EDF38,oldValue)
oldValue = nil
valTimer.Enabled = false
valTimer.Destroy()
valTimer = nil
{$asm}
|
If it's any easier, you can also just directly read some table entry's values/addresses and act on that, rather than reading it all in memory. I've got an example table I could send you if that's something you want. Just contact me on Discord, even if you just want more direct help, I can try: Birdi#0007
2:
I'm not sure the issue myself here, but look into:
Code: |
LUA: fullAccess(Address, Size)
AA: define(Name, Value)
|
Wish I could offer more for the second question, but I have practically no experience in emulator-run gamehacking.
_________________
Trying to learn!
Add me on Discord if you want hands-on help: Birdi#0007 |
|
Back to top |
|
|
Cissamannen Cheater Reputation: 0
Joined: 16 Jul 2009 Posts: 36
|
Posted: Thu Sep 02, 2021 5:29 am Post subject: |
|
|
Thanks, I will test it out. And yes, the specific offset needing to be 1 is already on the table as well, figured it used the same function, but if it just reads a stored adress thats easier I guess
|
|
Back to top |
|
|
LeFiXER Grandmaster Cheater Supreme Reputation: 20
Joined: 02 Sep 2011 Posts: 1055 Location: 0x90
|
Posted: Thu Sep 02, 2021 8:13 am Post subject: |
|
|
To add to what Birdi has mentioned already, you're miscontruing what an offset actually is. The addresses you have are relative virtual addresses which are locations in mapped memory that are calculated with a base address and offset(s).
An offset is just that, a value that is added to an address to define the location e.g.: 0xDEADBEEF + 0x0BADFEED = 0xEA5BBDDC, 0xDEADBEEF would be the base address and 0x0BADFEED would be the offset.
I would add some alternative checks to ensure other cases are dealt with:
Code: |
[ENABLE]
{$LUA}
local inBattle = 1
local addressToCheck = 0x1000EDF38
function checkValue()
if readByte(addressToCheck) == inBattle then
writeSmallInteger(addressToCheck, 999)
else
--We don't want the script to write a new value unless this address explicitly contains the value 1
return
end
end
--Use 4 bytes & writeInteger if you need that instead
oldValue = readBytes(addressToCheck , 2)
valTimer = createTimer(MainForm, false)
valTimer.Interval = 10
valTimer.OnTimer = checkValue
valTimer.Enabled = true
{$ASM}
[DISABLE]
{$LUA}
writeSmallInteger(addressToCheck, oldValue)
oldValue = nil
valTimer.Enabled = false
valTimer.Destroy()
valTimer = nil
{$ASM}
|
|
|
Back to top |
|
|
Cissamannen Cheater Reputation: 0
Joined: 16 Jul 2009 Posts: 36
|
Posted: Thu Sep 02, 2021 9:14 am Post subject: |
|
|
Ah thanks for the clarification!
I'll test those changes you made on some other entries too! Thanks a bunch!
|
|
Back to top |
|
|
LeFiXER Grandmaster Cheater Supreme Reputation: 20
Joined: 02 Sep 2011 Posts: 1055 Location: 0x90
|
Posted: Thu Sep 02, 2021 10:20 am Post subject: |
|
|
No problem . If you're unsure about anything feel free to ask away.
|
|
Back to top |
|
|
Cissamannen Cheater Reputation: 0
Joined: 16 Jul 2009 Posts: 36
|
Posted: Thu Sep 02, 2021 10:47 am Post subject: |
|
|
LeFiXER wrote: | No problem . If you're unsure about anything feel free to ask away. |
Ok I got one.
Considering I got a few entries that wants to use the same conditional address to figure out to change a value or not, can the conditional check be made into its own script, or added to main table lua somehow, and the cheat entries just uses that?
I notice if I have the same type of script with timers on, it messes with enabling/disabling and can just stop functioning, meaning it needs to be enabled only 1 at a time.
To take your example into account here:
Code: | [ENABLE]
{$lua}
local inBattle = 1
local addressToCheck = 0x1000E11B8
function checkValue()
if readBytes(addressToCheck,1) == inBattle then
writeSmallInteger(0x1000EDF38, 999)
else
--We don't want the script to write a new value unless this address explicitly contains the value 1
return
end
end
oldValue = readBytes(0x1000EDF38,2) --use 4 bytes & writeInteger if you need that instead
valTimer = createTimer(MainForm, false)
valTimer.Interval = 10
valTimer.OnTimer = checkValue
valTimer.Enabled = true
{$asm}
[DISABLE]
{$lua}
writeSmallInteger(0x1000EDF38,oldValue)
oldValue = nil
valTimer.Enabled = false
valTimer.Destroy()
valTimer = nil
{$asm} |
So my goal would be, to have the
Code: | function checkValue()
if readBytes(addressToCheck,1) == inBattle then |
as it's own script running from either an AA entry, or in main lua, so I can then say for example (its most likely wrong but):
Code: | [ENABLE]
{$lua}
function checkValue()
if readBytes(addressToCheck,1) == inBattle then
writeSmallInteger(0x1000EDF38, 999)
else
--We don't want the script to write a new value unless this address explicitly contains the value 1
return
end
end
[DISABLE] |
It seems more stable if I can have a script read from 1 point where the timer is engaged for checking the battle condition, and not having the timer created on several different cheat entries at once.
I'll clarify more if it's needed
|
|
Back to top |
|
|
LeFiXER Grandmaster Cheater Supreme Reputation: 20
Joined: 02 Sep 2011 Posts: 1055 Location: 0x90
|
Posted: Thu Sep 02, 2021 11:04 am Post subject: |
|
|
I think I understand what you mean, perhaps something like this will be better suited. On the main Cheat Engine form click Table on the Menu followed by Show Cheat Table Lua Script and make sure it's as follows:
Code: |
local inBattle = 1
addressToCheck = 0x1000E11B8
oldValue = readBytes(addressToCheck,2)
function checkValue(newValue)
if readBytes(addressToCheck,1) == inBattle then
writeSmallInteger(addressToCheck, newValue)
else
if valTimer ~= nil then valTimer.destroy() valTimer = nil end
--We don't want the script to write a new value unless this address explicitly contains the value 1
return
end
end
valTimer = createTimer(MainForm, false)
valTimer.Interval = 10
valTimer.OnTimer = checkValue
valTimer.Enabled = true
function disableCheck()
if valTimer then valTimer.destroy() valTimer = nil end
end
|
In the script you can just call it like this:
Code: |
[ENABLE]
{$LUA}
-- Number passed will be the value to write to that address so you can apply a different value based on the script
checkValue(999)
...
other script stuff
...
{$ASM}
[DISABLE]
{$LUA}
disableCheck()
|
|
|
Back to top |
|
|
Cissamannen Cheater Reputation: 0
Joined: 16 Jul 2009 Posts: 36
|
Posted: Thu Sep 02, 2021 11:40 am Post subject: |
|
|
I see, i might need some aid in tweaking it a bit.
So basically 0x1000E11B8 is only to be read from, never needs to be written to.
As its like a flag of being in roaming, in battle, in cutscene etc. When in battle, its value is 1.
When it is 1, i want to have a script that can read from that address, and write a value to the cheat address I want it to.
So for example
Cheat entry 1:
write 999 to 0x1000EDF38
Cheat entry 2:
write 9999 to 0x100088668
write 9999 to 0x1000F8F24
And so on. I want them as different entries as they have different functions in battle/during result screen.
But I want to be able to disable each cheat manually, without the check for 0x1000E11B8 being 1 in value or not stopping (via the timer). Unless how you put disableCheck in the AA script only works if every cheat using the check needs to be disabled before its actually disabled?
|
|
Back to top |
|
|
LeFiXER Grandmaster Cheater Supreme Reputation: 20
Joined: 02 Sep 2011 Posts: 1055 Location: 0x90
|
Posted: Thu Sep 02, 2021 1:13 pm Post subject: |
|
|
The script there is a Lua code block in an AA script btw. The Lua Cheat Table Script can hold Lua functions that are accessible throughout other scripts in the table.
So you want the check to run continuously to decide if you're in battle. For that we use the check in the Lua Cheat Table Script.
Code: |
inBattle = false
-- This is the address that holds the flag value
addressToCheck = 0x1000E11B8
oldValue = readBytes(addressToCheck,2)
function isInBattle()
if readBytes(addressToCheck,1) == 1 then
return inBattle = true
else
return inBattle = false
end
end
tmrInBattle = createTimer(MainForm, false)
tmrInBattle.Interval = 10
tmrInBattle.OnTimer = isInBattle
tmrInBattle.Enabled = true
--Some housework just in case you want to disable the timer because we don't want a memory leak
function disableCheck()
if tmrInBattle ~= nil then tmrInBattle.destroy() tmrInBattle = nil end
end
|
Now, in other scripts you can just reference the inBattle flag like so:
Code: |
[ENABLE]
{$LUA}
local myScriptAddress = 0x1000EDF38
local defaultValue = readBytes(myScriptAddress,1)
if inBattle then
writeBytes(myScriptAddress, 999)
else return end
{$ASM}
[DISABLE]
{$LUA}
-- Omit the check and write directly to the address.
writeBytes(myScriptAddress, defaultValue)
|
Say you add a new script to the table and assign your battle-related hacks to that group, you can make sure that the child scripts are only visible providing that check script is enabled. In that check script you can use the functions in the main Lua Cheat Table Script:
Code: |
[ENABLE]
{$LUA}
-- Do preliminary check and start the timer.
isInBattle()
{$ASM}
[DISABLE]
{$LUA}
-- Only disable the timer if we stop the isInBattle script.
disableCheck()
|
I hope this is of help.
Last edited by LeFiXER on Fri Sep 03, 2021 5:07 am; edited 2 times in total |
|
Back to top |
|
|
Cissamannen Cheater Reputation: 0
Joined: 16 Jul 2009 Posts: 36
|
Posted: Thu Sep 02, 2021 5:19 pm Post subject: |
|
|
Thanks a bunch mate! Will test this tomorrow!
|
|
Back to top |
|
|
Cissamannen Cheater Reputation: 0
Joined: 16 Jul 2009 Posts: 36
|
Posted: Fri Sep 03, 2021 2:46 am Post subject: |
|
|
Ok so it seems to be some error for setting the latest inbattle script into main table.
Can check attached photo.
I dont see whats wrong considering the 'end' is at line 35 instead following the return/else.
Description: |
|
Filesize: |
99.96 KB |
Viewed: |
4043 Time(s) |
|
|
|
Back to top |
|
|
LeFiXER Grandmaster Cheater Supreme Reputation: 20
Joined: 02 Sep 2011 Posts: 1055 Location: 0x90
|
Posted: Fri Sep 03, 2021 3:39 am Post subject: |
|
|
Strange, try this.
Code: |
function isInBattle()
if readBytes(addressToCheck,2) == 1 then
inBattle = true
else
inBattle = false
end
end
|
|
|
Back to top |
|
|
Cissamannen Cheater Reputation: 0
Joined: 16 Jul 2009 Posts: 36
|
Posted: Fri Sep 03, 2021 4:00 am Post subject: |
|
|
Ok that worked to input.
After saving and running, and running the 2 extra scripts, it doesnt seem to reflect in game though.
I enable this first:
Code: | [ENABLE]
{$LUA}
-- Do preliminary check and start the timer.
isInBattle()
{$ASM}
[DISABLE]
{$LUA}
-- Only disable the timer if we stop the isInBattle script.
disableCheck() |
And then I enabled:
Code: | [ENABLE]
{$LUA}
local myScriptAddress = 0x1000EDF38
local defaultValue = readSmallInteger(myScriptAddress)
if inBattle then
writeSmallInteger(myScriptAddress, 999)
else return end
{$ASM}
[DISABLE]
{$LUA}
-- Omit the check and write directly to the address.
writeSmallInteger(myScriptAddress, defaultValue) |
Though the set values doesnt show up in game
Is there something im missing from here regarding either of the 2, or the main table one?
|
|
Back to top |
|
|
LeFiXER Grandmaster Cheater Supreme Reputation: 20
Joined: 02 Sep 2011 Posts: 1055 Location: 0x90
|
Posted: Fri Sep 03, 2021 4:03 am Post subject: |
|
|
When you change the value of the address in the CE table, does the value update automatically in-game? because often times, new values won't reflect until there has been a change to the value in-game.
What game is it? I think I will have to do some debugging.
|
|
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
|
|