News:

As a consequence of the forum being updated and repaired, the chatbox has been lost.
However, you can still come say hi on our Discord server!

Main Menu

GS2 Utility Script

Started by Plexa, 07, October, 2016, 08:50:05 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Plexa

Hello everyone! I'm back to work out some things for writing a utility script for GS2 akin to the one made for GS1 http://forum.goldensunhacking.net/index.php?topic=2656.0

The big difference between GS1 and GS2 is that the kinds of things I need out of the script are somewhat different. I've ported over everything from the GS1 script but there's one thing in particular that would be much more useful in GS2 than GS1 is the value of the agility roll in a fight.

So let's be precise. We know that a member of your party can have its agility boosted between 0-6% depending on RNG (specifically, the general random number "GRN" i.e. the random number in the 0x03xxxxxx series). What Zetonegi found a couple months ago is that the reason the GRN advances when finalising your party members action is that the game calculates the 0-6% boost at that step.

Just so there's no confusion; Say the party member is Felix, you command Felix to attack an enemy. You then get to issue a command for Jenna. Once the attack is issued and before you choose Jenna's action the random number is rolled to determine what Felix's agility will be for that action. If you cancel Felixs command (by pressing B) and issue a new one, a new agility boost is calculated by rolling the random number again.

I'm curious as to where this value is stored, so that I can get my script to read this value and know what agility my party members will have on that turn. 

Daddy Poi's Oily Gorillas

#1
Where it is stored? Already have that "magic trick" up my sleeve..

The turn table is at 0x02030338. (Shows only a single round of all character turns.)
0x10 bytes per character.
First byte = Starts with who's turn it is.
I think the Agility one would be at [+0x4] in a turn entry.

(You could read 0x02030338 directly (Since I don't expect the position to actually change), or follow the pointer @03000024 the way the game does. - Everything in 03000000-030000FF is pretty much pointers to RAM data tables... with the first two being free space pointers.)
Golden Sun Docs: Broken Seal - The Lost Age - Dark Dawn | Mario Sports Docs: Mario Golf & Mario Tennis | Misc. Docs
Refer to Yoshi's Lighthouse for any M&L hacking needs...

Sometimes I like to compare apples to oranges. (Figuratively) ... They are both fruits, but which one would you eat more? (If taken literally, I'd probably choose apples.)
Maybe it is over-analyzing, but it doesn't mean the information is useless.


The only GS Discord servers with significance are:
Golden Sun Hacking Community
GS Speedrunning
/r/Golden Sun
GS United Nations
Temple of Kraden

Can you believe how small the Golden Sun Community is?

2+2=5 Don't believe me? Those are rounded decimal numbers. Take that, flat earth theorists! :)

Salanewt

And that's total Agility post-RNG.

Need any other questions answered?
Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

Plexa

#3
Quote from: Fox on 07, October, 2016, 09:11:51 AM
Where it is stored? Already have that "magic trick" up my sleeve..

The turn table is at 0x02030338. (Shows only a single round of all character turns.)
0x10 bytes per character.
First byte = Starts with who's turn it is.
I think the Agility one would be at [+0x4] in a turn entry.

(You could read 0x02030338 directly (Since I don't expect the position to actually change), or follow the pointer @03000024 the way the game does. - Everything in 03000000-030000FF is pretty much pointers to RAM data tables... with the first two being free space pointers.)
Perfect! I'll poke around and extract what I need from there :)

@Lord Squirtle, I think that's the only missing thing that I can't brute force conveniently. I did want to look into the other random number (BRN) and predict when you get attacks first and whatnot but I don't know how to use that information in a useful way in the context of GS2 (i know that encounters add 1 BRN per enemy provided you don't have attacks first, but if I can't predict the size of the mob without a script then I can utilise manip'ing for attacks first).

I eventually want to learn how collision works in this game (because its really really weird), but that extends beyond the scope of this question :)

Plexa

#4
Actually, now I do have another question!

So I know the agility of, say, Felix is stored at 0x02000A90 but this is the agility after modifiers have been added (class, equipment, etc). Where might I find the raw agility stat of each character? This is important because its useful to know how many "imperfect" level ups we get for each character since we don't control the stat boost for each level up. (the HP stat would also be useful!)

EDIT: Nevermind! Found it :)

Daddy Poi's Oily Gorillas

#5
You mean the part in the base stats? (Should be in the same order as the current stats.) - Base stats might include Stat Bonuses from Use items. (Apple, Hard Nut, etc.)
Golden Sun Docs: Broken Seal - The Lost Age - Dark Dawn | Mario Sports Docs: Mario Golf & Mario Tennis | Misc. Docs
Refer to Yoshi's Lighthouse for any M&L hacking needs...

Sometimes I like to compare apples to oranges. (Figuratively) ... They are both fruits, but which one would you eat more? (If taken literally, I'd probably choose apples.)
Maybe it is over-analyzing, but it doesn't mean the information is useless.


The only GS Discord servers with significance are:
Golden Sun Hacking Community
GS Speedrunning
/r/Golden Sun
GS United Nations
Temple of Kraden

Can you believe how small the Golden Sun Community is?

2+2=5 Don't believe me? Those are rounded decimal numbers. Take that, flat earth theorists! :)

Plexa

I literally just found it myself, with that said, your image is very useful. Thank you :)

Plexa

Sorry to make yet another reply, but how do sleep bombs work? When using the pirate sword dream tide may make enemies sleep based off of your mercury power. However, sleep bombs don't have an elemental affinity? So I was wondering how this works?

Daddy Poi's Oily Gorillas

#8
QuoteSorry to make yet another reply, but how do sleep bombs work?
The Ailment Success function? (Which is listed on http://forum.goldensunhacking.net/index.php?topic=2460.0)

QuoteWhen using the pirate sword dream tide may make enemies sleep based off of your mercury power. However, sleep bombs don't have an elemental affinity? So I was wondering how this works?
It's Unleash is the Dreamtide ability (Water attribute), and not Sleep Bomb (As an ability, Wind attribute.).  Both can inflict Sleep.
Golden Sun Docs: Broken Seal - The Lost Age - Dark Dawn | Mario Sports Docs: Mario Golf & Mario Tennis | Misc. Docs
Refer to Yoshi's Lighthouse for any M&L hacking needs...

Sometimes I like to compare apples to oranges. (Figuratively) ... They are both fruits, but which one would you eat more? (If taken literally, I'd probably choose apples.)
Maybe it is over-analyzing, but it doesn't mean the information is useless.


The only GS Discord servers with significance are:
Golden Sun Hacking Community
GS Speedrunning
/r/Golden Sun
GS United Nations
Temple of Kraden

Can you believe how small the Golden Sun Community is?

2+2=5 Don't believe me? Those are rounded decimal numbers. Take that, flat earth theorists! :)

Plexa

Quote from: Fox on 08, October, 2016, 08:23:00 PM
QuoteSorry to make yet another reply, but how do sleep bombs work?
The Ailment Success function? (Which is listed on http://forum.goldensunhacking.net/index.php?topic=2460.0)

QuoteWhen using the pirate sword dream tide may make enemies sleep based off of your mercury power. However, sleep bombs don't have an elemental affinity? So I was wondering how this works?
It's Unleash is the Dreamtide ability (Water attribute), and not Sleep Bomb (As an ability, Wind attribute.).  Both can inflict Sleep.
So I get that it successes the Ailment success function, just didn't know what element it was associated to (I guessed jupiter).

I'm currently debugging my script because I think a lot of the memory addresses I'm trying to read are the wrong ones lol

Does 0x080C6684 point to the enemy index?

Daddy Poi's Oily Gorillas

#10
QuoteDoes 0x080C6684 point to the enemy index?
Nope.... That's Elemental data... Enemies index to them. - The info can be seen at the bottom in Atrius's enemy editor... The first four top values are actually just one value. (32-bit), and should represent elemental type. (Forgot what for? Attack?)
Golden Sun Docs: Broken Seal - The Lost Age - Dark Dawn | Mario Sports Docs: Mario Golf & Mario Tennis | Misc. Docs
Refer to Yoshi's Lighthouse for any M&L hacking needs...

Sometimes I like to compare apples to oranges. (Figuratively) ... They are both fruits, but which one would you eat more? (If taken literally, I'd probably choose apples.)
Maybe it is over-analyzing, but it doesn't mean the information is useless.


The only GS Discord servers with significance are:
Golden Sun Hacking Community
GS Speedrunning
/r/Golden Sun
GS United Nations
Temple of Kraden

Can you believe how small the Golden Sun Community is?

2+2=5 Don't believe me? Those are rounded decimal numbers. Take that, flat earth theorists! :)

Plexa

#11
EDIT: actually it's worse than that lol I have 0x080C6684 all over the place in places it shouldn't be.

S=memory.readbyte(0x02030A12)
function enemy (S,Elm) -- Enemy Elemental Data Table
       elemInd = memory.readbyte(0x080C6684  + ((S - 8) * 0x54) + 0x34)
       enemyelmlevel = memory.readbyte(0x080C6684  + (elemInd * 0x18) + 4+Elm)
       return enemyelmlevel
end

That first instance of 6684 looks okay, the second one doesn't look okay.  
if memory.readbyte(0x080C6684  + (PC * 0xB4) + 0x92 + Elm) == 54 then
elmaff = 5
else
elmaff = 0
end

Again, this one is probably wrong since that should be pointing to the PC elemental data. From the gs2 data google doc shouldn't this be 080C6644?  But then +0xB4 would take it back into the enemy elemntal index.

EDIT2:
Made these edits
function enemy (S,Elm) -- Enemy Elemental Data Table
        elemInd = memory.readbyte(0x080C6684  + ((S - 8) * 0x4C) + 0x2A)
        enemyelmlevel = memory.readbyte(0x080B9E7C  + (elemInd * 0x18) + 4+Elm)
        return enemyelmlevel
end

if memory.readbyte(0x080C0F4C  + (U * 0xB4) + 0x92 + Elm) == 54 then
elmaff = 5
else
elmaff = 0
end

But this still doesn't work... tried to follow your advice here: http://forum.goldensunhacking.net/index.php?topic=2656.msg44420#msg44420

Daddy Poi's Oily Gorillas

#12
@1: Other way around? Haha...

080B9E7C = Enemy Stats (76 bytes per entry)
GS2 is 0x4C bytes/entry here... (GS1's could probably be 0x54/entry, but would have to check.)
+2A = Elem. Index?

Which means I'm getting this for GS2 version:

        elemInd = memory.readbyte(0x080B9E7C  + ((S - 8) * 0x4C) + 0x2A)
        enemyelmlevel = memory.readbyte(0x080C6684  + (elemInd * 0x18) + 4+Elm)

@2: Looks like it should be the Party data (Stuff you start with.)

080C0F4C


EDIT: I forgot to refresh the page.
Golden Sun Docs: Broken Seal - The Lost Age - Dark Dawn | Mario Sports Docs: Mario Golf & Mario Tennis | Misc. Docs
Refer to Yoshi's Lighthouse for any M&L hacking needs...

Sometimes I like to compare apples to oranges. (Figuratively) ... They are both fruits, but which one would you eat more? (If taken literally, I'd probably choose apples.)
Maybe it is over-analyzing, but it doesn't mean the information is useless.


The only GS Discord servers with significance are:
Golden Sun Hacking Community
GS Speedrunning
/r/Golden Sun
GS United Nations
Temple of Kraden

Can you believe how small the Golden Sun Community is?

2+2=5 Don't believe me? Those are rounded decimal numbers. Take that, flat earth theorists! :)

Plexa

#13
Yeah I still had the first two addresses round the wrong way, fixed that now...

Still getting the wrong results =/ 0x02030A12 is enemy index correct? (for the first enemy)

EDIT: Here's the full script atm http://pastebin.com/qMpEmPnT it's just the unleash/effect proc stuff thats messing up atm.

EDIT2: Now I think there's a problem here
function vuln (S)
e1Ind = S
vuln1 = memory.readbyte(0x080B9E7C  + ((e1Ind - 8) * 0x4C) + 0x48)
vuln2 = memory.readbyte(0x080B9E7C  + ((e1Ind - 8) * 0x4C) + 0x49)
vuln3 = memory.readbyte(0x080B9E7C  + ((e1Ind - 8) * 0x4C) + 0x4A)
return vul1, vul2, vul3
end

Daddy Poi's Oily Gorillas

@    eind = memory.readbyte(0x02030A12) -- Enemy Index

It may be a byte in GS1, but it is a 16-bit in GS2.

@Edit 2: Yeah, Probably should be +0x3E, +0x3F, and +0x40.... (For enemy vulns....)
Golden Sun Docs: Broken Seal - The Lost Age - Dark Dawn | Mario Sports Docs: Mario Golf & Mario Tennis | Misc. Docs
Refer to Yoshi's Lighthouse for any M&L hacking needs...

Sometimes I like to compare apples to oranges. (Figuratively) ... They are both fruits, but which one would you eat more? (If taken literally, I'd probably choose apples.)
Maybe it is over-analyzing, but it doesn't mean the information is useless.


The only GS Discord servers with significance are:
Golden Sun Hacking Community
GS Speedrunning
/r/Golden Sun
GS United Nations
Temple of Kraden

Can you believe how small the Golden Sun Community is?

2+2=5 Don't believe me? Those are rounded decimal numbers. Take that, flat earth theorists! :)

Plexa

#15
Right I've updated things. Still getting the wrong results.

When I run
proc = (((uelm + elmaff - eelm)-(math.floor(eluc/2)))*3+bchance(E)+v)

During the King Scorpion fight with Sheba (with 2 jupiter djinn) using the sleep bomb I get the following data
uelm = 7 -- user elemental level
elmaff = 5 -- user elemental affinity
eelm = 0 -- enemy elemental level
math.floor(eluc/2) = 20 -- enemy luck/2
bchance(E) = 40 -- base chance
v=0

So I get the value of -20 at the end of this. This isn't right because it's very easy to get the King Scorpion to sleep. I don't see that KS is vulnerable to sleep in Atrius's editor either. Do any of these numbers look wrong?


Daddy Poi's Oily Gorillas

#16
King Scorpion vuln - Effect 24 is the Sleep effect... King Scorpion has 12, 13, and 24... So I see it.

Sleep is supposed to be 45 base chance... The Master Function List topic say 35%, but I think it is wrong.  The other effect base chances are correct if the Master Function List is correct on those.

Quotemath.floor(eluc/2) = 20 -- enemy luck/2
This is actually just eluck >> 1, in-game...  bit.rshift(eluck,1) , but I put that other stuff there (in my original announcement of the formula) for newbies who don't know bit-shifts.  (Simpler to explain. :P)

Quoteeluc = memory.readbyte(0x020308E6) -- Enemy Luck
Base luck?
Golden Sun Docs: Broken Seal - The Lost Age - Dark Dawn | Mario Sports Docs: Mario Golf & Mario Tennis | Misc. Docs
Refer to Yoshi's Lighthouse for any M&L hacking needs...

Sometimes I like to compare apples to oranges. (Figuratively) ... They are both fruits, but which one would you eat more? (If taken literally, I'd probably choose apples.)
Maybe it is over-analyzing, but it doesn't mean the information is useless.


The only GS Discord servers with significance are:
Golden Sun Hacking Community
GS Speedrunning
/r/Golden Sun
GS United Nations
Temple of Kraden

Can you believe how small the Golden Sun Community is?

2+2=5 Don't believe me? Those are rounded decimal numbers. Take that, flat earth theorists! :)

Plexa

#17
Right then its the vuln function thats messing up in my script! Thanks for the help (as always lol). I'll continue debugging this later tonight and keep you posted with any updates.

EDIT: ugh there was a type in the vuln function which lead to me trying to call vul1 instead of vuln1 etc hahhahhaha

Everything appears to be working now!

Daddy Poi's Oily Gorillas

#18
Okay. Sounds good!

I do have a small question myself, though?

Is there even a way to call GBA thumb functions from LUA? (There probably is if you can write values to RAM... (Think: Writing in function pointers)  But not so sure if that's efficient/user-friendly enough.)
And if not, then would it be wise to code this stuff you are doing into something that could get converted to Thumb for insertion? (Similar to that devkitadv/devkitpro stuff I was looking into...)

@devkit: In that case, calling a function could be as simple as setting a list of them up. (So you can use them anywhere in your code.) For example:
Quoteregister int *r4 asm ("r4"); //Should be at the top, and allows variable "r4" to use register "r4"...
int Calculate_Ailment_Success(int attacker, int defender, int element, int effect, int percentMod) {
   r4=(int*)0x080B075D; goto *r4; //Thumb pointers are odd numbers.
}

(I haven't figured out the best most user-friendly way of inserting the new code back into the ROM, but I assume it is easy enough for any partially experienced user. - Basically cut & paste + attach a hook (I mean get the code execution to call your main function.))

(Assuming one can still get graphics on the screen? - But even then you could still do a combo - LUA for graphics only, Thumb for everything else/store stuff in memory... In the area where there's plenty of free space.)
(I would still need to think out any kinks and think about how much shorter the code could be. - On the plus side, shorter code could mean fewer bugs slip through.)

For example, effectproc, would mainly be a function call to:
Well,  basically...

int temp = [currentRNG];
(Loop to count how many RNG cycles needed) ; 080B075C = Calculate_Ailment_Success(attacker,defender,element,effect,percentMod)
[currentRNG] = temp;

Pretty much.... (Defender would be 0x80 for the first enemy... And percentMod would be set at 100% assuming you are only calculating for the target...)


I'm also assuming Unleash could be this one?:
080B04BC = unleash_check(pc) Returns ability to cast. (Unleash if chance succeeds, or attack.)

(Relies on having checked item equipped...)

Hmm..
while Calculate_Ailment_Success(5,0x80,1,24,100%) == false or unleash_check(5) != Dreamtide do
....




EDIT:::

Quoteif memory.readbyte(0x02030900+0x14C*4)>0 then
        gui.text(60,80, "E5 Agi: " .. memory.readbyte(0x020308E4+0x14C*4))
        gui.text(110,80, "HP: " .. memory.readbyte(0x02030900+0x14C*5))
    else
TYPO!! :P (That "5", and I also thought these were 16-bits as well??) - But yeah, that's my point about bugs possibly appearing when you have an excess of dirty code. Looks like something that could have its own function/loop. (Of course, even I understand that cleaning it can be a nuisance. :P)

I think item drops are more like... if rnd(0,0xFFFF) < 0x20000 >> chance { get item } (But shift two extra depending on djinn or not?  Looking at the damage function, it seems more like there's a random chance for the quadruple rate to be applied... One of the variables for that may include Elemental Resistance... still looking, though. - It is assume that the element of djinn in which the enemy has the highest resistance in (of all their elements),... may have a 0% chance to quadruple rate?
And the one with the least resistance... should then execute this check.... still need to read the rest, though.
Golden Sun Docs: Broken Seal - The Lost Age - Dark Dawn | Mario Sports Docs: Mario Golf & Mario Tennis | Misc. Docs
Refer to Yoshi's Lighthouse for any M&L hacking needs...

Sometimes I like to compare apples to oranges. (Figuratively) ... They are both fruits, but which one would you eat more? (If taken literally, I'd probably choose apples.)
Maybe it is over-analyzing, but it doesn't mean the information is useless.


The only GS Discord servers with significance are:
Golden Sun Hacking Community
GS Speedrunning
/r/Golden Sun
GS United Nations
Temple of Kraden

Can you believe how small the Golden Sun Community is?

2+2=5 Don't believe me? Those are rounded decimal numbers. Take that, flat earth theorists! :)

Plexa

#19
Good catch on the *5 error! Probably would have never found that myself since its so rare that you even get 5 enemies (to the point where I never bothered including them in the flee calculation).

I don't know enough LUA to be able to answer your question about calling thumb functions. I imagine there is since it is possible to write to RAM (we use that to suppress encounters when hunting for oob doors).

Interesting that there's a random increased drop chance, keep me posted on what you find.

EDIT: Are you sure that you're not just talking about rainbow killing enemies xD