Golden Sun Hacking Community
September 20, 2017, 02:29:46 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News:
 
  Home Forum DC Wiki Help Search Calendar Downloads Login Register  
  Show Posts
Pages: [1] 2 3 ... 149
1  The Editor / Golden Sun: The Lost Age Editor / Re: Golden Sun Magic (Beta) - Forge, Elemental Data, Encounters on: Today at 01:37:16 AM
There has been Map Editor progress, yes. (Fresh ROM recommended.)

No Dark Dawn progress. (Unless you count the stuff that was documented (from June and before) in the document as progress?)
2  General Hacking / General Editor / Re: Best Map Editor? on: Today at 01:28:55 AM
Okay cool.

Layers? Eh? Is there a possibility it works very similar to Golden Sun? - /(like, not just 3 layers for graphics, but also for events, height, etc... and each npc picks which layer to use.)

@that ones: For which?
SF1 = https://forums.shiningforcecentral.com/viewtopic.php?t=15145
Would that be a good example? I haven't even looked at it, yet, though.. (So don't even know if it has a map editor. :P)
3  Golden Sun Games / Golden Sun / Re: Lash Ropes on: September 18, 2017, 03:06:06 PM
Sounds interesting. Would it have to do with the distance between both posts? I guess I can take a closer look at exactly what's being checked.

----
There are two types of Ropes - One that requires Lash, the other that's already connected... So I'll post the sections of code for both... (To point out the general section is already known, but a lot of it might not be documented good enough.)

Code:
Lash Pegs Group 1 (0300009C)
080D897C = Lashy - Initialization (Called from Map Code.)
080D8A00 = Lashy - Called every ~frame?
080D8C10 = See Movement Type - This is based on Lash pegs. - Called every ~frame?

080D8FA8 = Lashy
080D8FF8 = Lashy

080D9104 = Lash/peg/rope related (If flag is off) (pegset,peg1,peg2)
080D9194 = Lashy
080D92A4 = Lashy
080D92D4 = Lashy
080D9498 = Lashy
080D9710 = Lashy
080D9790 = Lashy
080D9974 = Return
080D9978 = *Research needed: One place tries to write “1” to 080F3944.
080D99B8 = isPlayerNextToPeg(peg1,peg2) Returns 1 if the player is next to a peg, otherwise 0. ; The pegs that you use Lash on.
080D9A74 = Lash/peg/rope related(peg1,addr1,addr2) peg2 placed in addr1, pegset placed in addr2.  (When r0=peg1, returns -1 if no match.)
080D9AB0 = Lash/peg/rope related
080D9AD0 = addLashy(pegset,flagInd,peg1,peg2) (Called from Map Code.)

Lash Pegs Group 2 (030000A0) - May not contain flag indexes, so these probably don’t need the Lash psynergy.
080D9D40 = See Movement Type - This is based on Lash pegs.
080D9E74 = [030000A0]+EC, return an empty slot (return address)
080D9E98 = addLashy(pegset,peg1,peg2)
080D9F1C = Lashy
080DA060 = Lashy(,peg1?,peg2?,)
080DA0B0 = Lashy
080DA1B8 = Lashy
080DA22C = Lashy
080DA334 = Lashy
080DA3BC = Lashy
080DA660 = Lashy
080DA6E0 = Lashy
080DA908 = Lashy
080DA938 = Lashy
080DA968 = *Research needed: One place tries to write “1” to 080F3950.

@ room 23 (Shrine of the Sea God entrance room.)
02036CF8 = (value is 6) Seems to affect the sprite. But not length.
First rope entry:
02036D00 = Length of rope. (Probably for number of rope segments in a list.)
02036D18 = Pointer to what looks like a list of entries for each rope segment.

So I guess I kind-of see it?
Shrine of the sea god (Map 23) = Length 15
Kandorian temple lobby (Map 22) = Two ropes that are length 10
Madra catacombs (Map 47) = Length 17
Ahafran Cave (Map 101) = Length 8

But to figure out how the length is decided, I'll need to study one quick thing.

Looking at 080D9194 function for calculation:
Yep! Distance between both is checked - So that means Pythagorean Theorem is used.
(root(x^2 + y^2 + z^2) / 6) + 1
(Where x, y, and z are the difference between both objects, ofcourse.)


---
Was that what you were looking for, or did I miss something?
4  The Community / Open Discussion / Re: Favourite/Least Favourite Season? on: September 09, 2017, 08:50:02 AM
Autumn:
-Large spiders that like to build big beautiful webs. (Sometimes in places you'd never expect them.)  You get the benefit of tricking someone into walking right through one.
-It's also usually hurricane season, so if you get flooded like Houston, well, good luck! ; I would hope such things can have a benefit like cleaning out the bad bugs... but eh.... mosquitoes flourish in/near still water.

Winter:
-Snowfall is beautiful to watch,
-If the lake is completely frozen, you can go ice-skating on the lake. (If the ice breaks, it can be deadly, though... so better to have it on land.)
-Do like Sheldon (I think?) and wear clothes over clothes?  (To help keep warm?) ; (Only reason I mention Sheldon, though, is because it always looks like he's wearing a short-sleeve shirt over a long one. https://cdn2.hercampus.com/rehost-2016-9-13-d0cf2ce9-ca2b-4be6-a428-5aa8b34da2d4.jpg)
-The "cost a lot to warm the place"... is probably what the fireplace is for?? :P Although, I'm no fan of a fireplace if it has an odor....) Such things like insulation should also be considered.
-Outdoor cold weather can replace your refrigerator(s).... possibly saving some on electric. (Compared to what it would have been for winter, and not necessarily vs. other seasons.)
5  Golden Sun Games / Golden Sun / Re: Game Crash from falling Z-coordinate and retreat glitch on: September 08, 2017, 09:48:06 PM
I tried it again.
I went to the Retreat Map (Went to World Map and back just to make sure it sets it correctly.)
Then I went to that room.
(Did not bother with ladder glitch... even though I did try that a little earlier.)
I Retreat Glitch.
Save.
Restart.
(Made sure Debug Mode was on because that's what I usually use/and since it can affect sanctum warping.)
And I get a crash.

So unless I did something wrong (doubt it), there's definitely a crash not involving glitching the z-coord.  (At the minimum.) ... (Doesn't prove changing the coords can't cause a crash, but anyway.... I need to investigate those Lift blocks.... since those are like the only "objects" here... (Other than chests/Isaac)  ... Like 4 objects in list (if ignoring Isaac)... and two of them (Lift blocks) appear to be at (0,0)?)

^I mean, the code pointers in the NPC data ... when called... when a different map code file is used... would cause a memory leak  (depending on pointer) ... (What do you call it when you skip putting stuff in the stack/take it out as though it were there?) ... which basically messes everything up.... esp. when return addresses are put in the stack, and some values that aren't return addresses are treated as such.
6  Golden Sun Games / Golden Sun / Re: Game Crash from falling Z-coordinate and retreat glitch on: September 08, 2017, 09:19:09 PM
Oh cool... About the infinite falling thing... But doesn't the crash happen without the ladder glitch as well? Hmm...

I'll look, but it wouldn't surprise me if both rooms used different map code files and that's why. No idea, yet, though.


Edit:  They do use different map code files. But not sure which part causes the crash yet.


Edit:  It is possible this could be similar to the mirror puzzles.... there's pointers to 02009AA9... see the objects at 02030EBC... will look a little further, though.
Those are the Lift blocks.
7  Golden Sun Games / Golden Sun: The Lost Age / Re: More RNG Questions on: September 06, 2017, 09:45:35 PM
Yes. So, have you changed my script to do anything, or are simply looking at the numbers I added?

Since if there's a priority for the stats/djinn... I suppose it could be possible to develope the script further...

And making a recursive function for this could be a perfect fit! (I think? Depends.)

I'm kind of thinking something like this:

findBestWhatever(0)

function findBestWhatever(depth)
    if depth >= 10 then return --Important to avoid endless calls.
    rng = grnseed --rng needs to be a function-level variable.
    statregen()
    findBestWhatever(depth + 1)
    grnseed = rng
    djinnpicker()
    findBestWhatever(depth + 1)
end

Incomplete, ofcourse.... but I hope I did the base example correctly? Erm...
As you can see, it kind of mimics a data tree... and it's also easy to add more conditions if needed.

--
Going to see what I can do with putting in Isaac's Attack in a bit, but who knows if it'll work out/execute fast enough.


WIP code:
Code:
local grnseed = 0
local brnseed = 0
function reset()
    grnseed = memory.readdword(0x030011BC)
    brnseed = memory.readdword(0x020054C8)
end
function grn16()
    g = grnseed
    m1 = 0x4e6d
    m2 = 0x41c6
    g1 = g*m1
    g2 = g*m2
    g2 = bit.band(g2,0xFFFF)
    g = g1 + g2*0x10000
    c=0x3039
    g = g+c
    g = bit.band(g,0xFFFFFFFF)
    grnseed = g
    g = bit.lshift(g,8)
    g = bit.rshift(g,16)
    --g = bit.band(g,0xFFFF)
    return g
end
function brn16()
    g = brnseed
    m1 = 0x4e6d
    m2 = 0x41c6
    g1 = g*m1
    g2 = g*m2
    g2 = bit.band(g2,0xFFFF)
    g = g1 + g2*0x10000
    c=0x3039
    g = g+c
    g = bit.band(g,0xFFFFFFFF)
    brnseed = g
    g = bit.lshift(g,8)
    g = bit.rshift(g,16)
    return g
end
    stat = {}
    stat[1] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[2] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[3] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[4] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[5] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[6] = {0, 0, 0, 0, 0, 0, 0, 0}
function startingStats()
    stat[1] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[2] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[3] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[4] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[5] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[6] = {0, 0, 0, 0, 0, 0, 0, 0}
    for pc=0,7 do
        dLv = memory.readbyte(0x080C0F4C + (pc * 0xB4) + 0x96)
        lv = 0
        while lv < dLv do
            lv = lv + 1
            if (lv == 1) then
                stat[1][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x50)
                stat[2][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x5C)
                stat[3][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x68)
                stat[4][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x74)
                stat[5][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x80)
                stat[6][pc + 1] = memory.readbyte(0x080C0F4C + (pc * 0xB4) + 0x8C)
            end

            statGrowthI = math.floor(lv / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x50 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[1][pc + 1] = stat[1][pc + 1] + math.floor(v / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x5C + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[2][pc + 1] = stat[2][pc + 1] + math.floor(v / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x68 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[3][pc + 1] = stat[3][pc + 1] + math.floor(v / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x74 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[4][pc + 1] = stat[4][pc + 1] + math.floor(v / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x80 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[5][pc + 1] = stat[5][pc + 1] + math.floor(v / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x8C + (statGrowthI)
            v = memory.readbyte(v + 1) - memory.readbyte(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[6][pc + 1] = stat[6][pc + 1] + math.floor(v / 20)

-- current stat += ((upper stat growth - lower stat growth) + ((grn16 * 20) >> 16))  / 20
        end
    end
--    for i=1,6 do
--        for j=1,8 do
--            gui.text(90 + j * 16 ,112 + i * 6,stat[i][j])
--        end
--    end
end
function djinnPercents(element, djinni)
    return memory.readword(0x080B1290 + ((element - 1) * 14) + ((djinni - 1) * 2))
end
function rollDjinn()
    haveDjinni = {}
    haveDjinni[1] = {1, 0, 0, 0, 0, 0, 0}
    haveDjinni[2] = {1, 0, 0, 0, 0, 0, 0}
    haveDjinni[3] = {0, 0, 0, 0, 0, 0, 0}
    haveDjinni[4] = {0, 0, 0, 0, 0, 0, 0}
    djinnCounts = {1, 1, 0, 0}
    djinnToAdd = 16
    while djinnToAdd > 0 do
        element = 1 + bit.rshift(grn16() * 4, 16)
        djinni = 1 + bit.rshift(grn16() * 7, 16)
        if haveDjinni[element][djinni] == 0 then
            djinnCounts[element] = djinnCounts[element] + 1
            low = 9
            high = 0
            for i=1,4 do
                if djinnCounts[i] < low then
                    low = djinnCounts[i]
                end
                if djinnCounts[i] > high then
                    high = djinnCounts[i]
                end
            end
            djinnCounts[element] = djinnCounts[element] - 1
            if (high - low) <= 1 then
                if bit.rshift(grn16() * 100, 16) < djinnPercents(element, djinni) then
                    haveDjinni[element][djinni] = 1
                    djinnCounts[element] = djinnCounts[element] + 1
                    djinnToAdd = djinnToAdd - 1
                end
            end
        end
    end
--    for i=1,4 do
--        for j=1,7 do
--            gui.text(195 + j * 5 ,0 + i * 6,haveDjinni[i][j])
--        end
--    end
    return
end

hAtk = 0
hAtk2 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} --0 --
atk = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} --0
tree = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
hTree = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
function savetree()
    for i=1,10 do
        hTree[i] = tree[i]
        hAtk2[i] = atk[i]
    end
    return
end
function findBest(depth)
    if depth >= 4 then return end --Important to avoid endless calls.
    rng = grnseed --rng needs to be a function-level variable.
    tree[depth] = 1
    startingStats() --statregen()
    atk[depth] = stat[3][1]
    if hAtk < stat[3][1] then
        hAtk = stat[3][1]
        savetree()
    end
    findBest(depth + 1)

    tree[depth] = 2
    grnseed = rng
    rollDjinn() --djinnpicker()
    findBest(depth + 1)

    tree[depth] = 0
    --atk[depth] = 0;
    return
end

while true do
    reset()
    hAtk = 0
    --gui.text(200, 10, "!")
    findBest(1)
    for i=1,3 do --10 do
        gui.text(150 + i * 20, 0, hTree[i])
        gui.text(150 + i * 20, 10, hAtk2[i])
    end
    --startingStats()
    --reset()
    --rollDjinn()
    vba.frameadvance();
end
Was not fully tested, so there may or may not be errors.

Here, shows 6 numbers... (Columns represent each cycle= 1st, 2nd, or 3rd action.)

The top row is:
0 = Nothing/Ignore
1 = Do a Felix Cancel
2 = Do an Isaac Cancel

The bottom row is Isaac's base attack at each stage. (So if the same column is switched to a 1/"Felix Cancel" in case of 2 (not tested, though.), you'd get this value.)


TODO = I want to add in a map/door check... as well as a check to a certain pointer in the stack. (So the info is only generated when necessary instead of every frame. = Would appear to increase the speed of searches of larger depths a great deal.


*Takes a look at your script at pastebin, and then becmes curous if something similar to "return (bit.band(g,0xF) == 0) or ((bit.band(g2,0x1F) ==0) * 2)" can be done. (All those if statements as a one liner.)
Except operationss as such can't be done on boolean values in LUA.... ... but one can still make a hack for that, and use a dictionary.
EX:
    t = {}
    t[true] = 1
    t[false] = 0
    gui.text(200, 20, t[0==0] * 2)


    t = {[false]=0, [true]=1}
    gui.text(200, 20, t[0==0] * 3)
8  Golden Sun Games / Golden Sun: The Lost Age / Re: More RNG Questions on: September 06, 2017, 08:41:57 PM
Quote
The frustrating thing is that FC IC =/= IC FC for some reason.
It's probably because of the way the djinn picker code works. (Chance to fail at picking one, and pick another.)

So while it is possible Felix Cancels (Stat generation) might always generate the same number of random numbers, the Isaac Cancels (Djinn Picker) are variable based on (un)successful picks.
9  Golden Sun Games / Golden Sun / Re: Graphical glitch in Lamakan on: September 03, 2017, 08:12:51 AM
Oh.  Would have been cool if there was an easy way to dump RAM from console... oh well.
Frame perfect sounds likely because the glitch is hard to make sense of.


Hm... I suppose it might be possible that it could be that you were going into Reveal at the same time a dialogue was suppose to pop up. Since I don't think those dialogues will pop up in Reveal mode.
I only say into, b/c of messed up thermometer graphics... but otherwise, I dunno... into or out of?

However, I have not yet replicated the glitch, so.... this is more just theory until then.

02030182 = The set of messages to use (1-3) ... Non-zero to make one appear... ; Value does nothing/doesn't reset when menus are open... hm... but exiting a menu (Even if by using reveal..) will make the dialgoue pop up first, followed by Reveal being used... Huh... ; Both those observations did not result in any glitching as of yet.

Actually wait, that value (02030182) might actually works the same for all maps.... (As in, not dialogue-specific.) ... possibly used to automatically call function(s) with event type 6 in the event list. (With the same id matching number?)

@0200A62C:

00000006 02010001 02008C6D
00000006 02010002 02008C6D
00000006 02010003 02008C6D

Somehow Reveal turns on flag 0x201... hmmm... and that turns off outside of Reveal...

Which makes me think there is an Event for Reveal. Hm... Yep!

@0200A614:
50009085 FFFF0000 0200888D = When entering Reveal
40009085 FFFF0000 020084E5 = When leaving Reveal
^Bold is ability/psynergy id. ; (For Event Type 5.)


---
I guess I'm stuck? Meanwhile... I learn that the oasis/djinni that appear, may be based on map. (So Retreat Glitch could change that some. - As in, other tiles get edited? Will need to test, though.) Probably not of any use, though.... Imagine if something like that ever helped with going OOBs... )
10  Golden Sun Games / Golden Sun / Re: Graphical glitch in Lamakan on: September 02, 2017, 07:46:37 AM
Oh cool...

I'm not sure what it is... but I guess I can look at the functions that are for the thermometer.... since it had a glitch between using Reveal and getting the djinni.

I'm not sure if this is one of those frame-perfect glitches?

02000472 = 16-bit value that ssays how much it is filled.
02009054 = For event id 0x15 tiles (Thumb code)
02009638 = .... executes every frame, and is what picks the dialogue set to use. (I do not expect the glitch to be here, so moving on....)

Quote
25% filled:
Garet: "Agh... This desert is much hotter than I ever imagined..."
Ivan: "Just walking around here saps every ounce of my strength."
Mia: "I can't stop sweating... I wish I'd brought a change of clothes..."

50% filled:
Garet: "I'm so thirsty... Water! I need some water!"
Ivan: "I can't keep my cool when it's this hot..."
Mia: "Ew... My clothes are drenched in sweat! This is gross!"

75% filled:
Garet: "Aghh! I can't stand it! My feet are burning!"
Ivan: "I can't stand another minute of this! Where's an oasis?"
Mia: "If we don't find an oasis soon, I'm gonna shrivel up and blow away!"


Have you been able to replicate the glitch?
If not... then it could have probably also helped if you made a savestate... like on the textbox glitch, so I could look at the data.... Hm... Otherwise, I'll keep looking.


Also not sure if this is one of those glitches where the battle undoes it or not.
11  Golden Sun Games / Golden Sun: The Lost Age / Re: More RNG Questions on: August 31, 2017, 06:38:40 AM
Okay.

And you are welcome...


I've been working on the calculations for stats.... and I'm currently at this point.
The code's there, sort of, but I'm not getting the right results, so I shall look into this!

WIP code:
Code:
local grnseed = 0
local brnseed = 0

function reset()
    grnseed = memory.readdword(0x030011BC)
    brnseed = memory.readdword(0x020054C8)
end
function grn16()
    g = grnseed
    m1 = 0x4e6d
    m2 = 0x41c6
    g1 = g*m1
    g2 = g*m2
    g2 = bit.band(g2,0xFFFF)
    g = g1 + g2*0x10000
    c=0x3039
    g = g+c
    g = bit.band(g,0xFFFFFFFF)
    grnseed = g
    g = bit.lshift(g,8)
    g = bit.rshift(g,16)
    return g
end
function brn16()
    g = brnseed
    m1 = 0x4e6d
    m2 = 0x41c6
    g1 = g*m1
    g2 = g*m2
    g2 = bit.band(g2,0xFFFF)
    g = g1 + g2*0x10000
    c=0x3039
    g = g+c
    g = bit.band(g,0xFFFFFFFF)
    brnseed = g
    g = bit.lshift(g,8)
    g = bit.rshift(g,16)
    return g
end
function startingStats()
    stat = {}
    stat[1] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[2] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[3] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[4] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[5] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[6] = {0, 0, 0, 0, 0, 0, 0, 0}
    for pc=0,7 do
        dLv = memory.readbyte(0x080C0F4C + (pc * 0xB4) + 0x96)
        lv = 0
        while lv < dLv do
            lv = lv + 1
            if (lv == 1) then
                stat[1][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x50)
                stat[2][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x5C)
                stat[3][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x68)
                stat[4][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x74)
                stat[5][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x80)
                stat[6][pc + 1] = memory.readbyte(0x080C0F4C + (pc * 0xB4) + 0x8C)
            end

            statGrowthI = bit.band(lv / 20, 0xFF)

            v = 0x080C0F4C + (pc * 0xB4) + 0x50 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[1][pc + 1] = stat[1][pc + 1] + bit.band(v / 20, 0xFFFF)

            v = 0x080C0F4C + (pc * 0xB4) + 0x5C + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[2][pc + 1] = stat[2][pc + 1] + bit.band(v / 20, 0xFFFF)

            v = 0x080C0F4C + (pc * 0xB4) + 0x68 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[3][pc + 1] = stat[3][pc + 1] + bit.band(v / 20, 0xFFFF)

            v = 0x080C0F4C + (pc * 0xB4) + 0x74 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[4][pc + 1] = stat[4][pc + 1] + bit.band(v / 20, 0xFFFF)

            v = 0x080C0F4C + (pc * 0xB4) + 0x80 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[5][pc + 1] = stat[5][pc + 1] + bit.band(v / 20, 0xFFFF)

            v = 0x080C0F4C + (pc * 0xB4) + 0x8C + (statGrowthI)
            v = memory.readbyte(v + 1) - memory.readbyte(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[6][pc + 1] = stat[6][pc + 1] + bit.band(v / 20, 0xFF)
-- current stat += ((upper stat growth - lower stat growth) + ((grn16 * 20) >> 16))  / 20
        end
    end
    for i=1,6 do
        for j=1,8 do
            gui.text(100 + j * 20 ,0 + i * 6,stat[i][j])
        end
    end
end
function djinnPercents(element, djinni)
    return memory.readword(0x080B1290 + ((element - 1) * 14) + ((djinni - 1) * 2))
end
function rollDjinn()
    haveDjinni = {}
    haveDjinni[1] = {1, 0, 0, 0, 0, 0, 0}
    haveDjinni[2] = {1, 0, 0, 0, 0, 0, 0}
    haveDjinni[3] = {0, 0, 0, 0, 0, 0, 0}
    haveDjinni[4] = {0, 0, 0, 0, 0, 0, 0}
    djinnCounts = {1, 1, 0, 0}
    djinnToAdd = 16
    while djinnToAdd > 0 do
        element = 1 + bit.rshift(grn16() * 4, 16)
        djinni = 1 + bit.rshift(grn16() * 7, 16)
        if haveDjinni[element][djinni] == 0 then
            djinnCounts[element] = djinnCounts[element] + 1
            low = 9
            high = 0
            for i=1,4 do
                if djinnCounts[i] < low then
                    low = djinnCounts[i]
                end
                if djinnCounts[i] > high then
                    high = djinnCounts[i]
                end
            end
            djinnCounts[element] = djinnCounts[element] - 1
            if (high - low) <= 1 then
                if bit.rshift(grn16() * 100, 16) < djinnPercents(element, djinni) then
                    haveDjinni[element][djinni] = 1
                    djinnCounts[element] = djinnCounts[element] + 1
                    djinnToAdd = djinnToAdd - 1
                end
            end
        end
    end
    for i=1,4 do
        for j=1,7 do
            gui.text(195 + j * 5 ,0 + i * 6,haveDjinni[i][j])
        end
    end
    return
end

while true do
    reset()
    startingStats()
    --rollDjinn()
    vba.frameadvance();
end
LUA is hard to use. :/ It's like... even worse than assembly. :P (Assembly is cool, though... but it often looks bloated.)
Better yet, to the majority of programmers who are familiar with how bad VB sucks... I kinda want to say LUA is just as bad or worse. :P

Well, at least I learned something this pass week about LUA = Indexes (in lists/arrays) start at 1 instead of 0... So that also adds more unnecessary bloat to my code.


@Isaac's Luck = Hmm.. why does my script generate Luck at ~17, when it can only be 3... Huh. - Luck stats always stay the same for starting stats = I could possibly comment it out....


@ bit.band(v / 20, 0xFF)
I expected that to return a 0 when v is 19... but it can return a 1? Wha? ... Hmmmm...... Probably cuz nasty floats. :/  (I'm an integer type of guy. Which is good, b/c most of the time I don't need decimal places, and  in some ways the rarity of it can make me think it shouldn't hurt to use a second integer as the denominator. :P But it depends.)... maybe math.floor(a/b) works.


Code:
local grnseed = 0
local brnseed = 0

function reset()
    grnseed = memory.readdword(0x030011BC)
    brnseed = memory.readdword(0x020054C8)
end
function grn16()
    g = grnseed
    m1 = 0x4e6d
    m2 = 0x41c6
    g1 = g*m1
    g2 = g*m2
    g2 = bit.band(g2,0xFFFF)
    g = g1 + g2*0x10000
    c=0x3039
    g = g+c
    g = bit.band(g,0xFFFFFFFF)
    grnseed = g
    g = bit.lshift(g,8)
    g = bit.rshift(g,16)
    --g = bit.band(g,0xFFFF)
    return g
end
function brn16()
    g = brnseed
    m1 = 0x4e6d
    m2 = 0x41c6
    g1 = g*m1
    g2 = g*m2
    g2 = bit.band(g2,0xFFFF)
    g = g1 + g2*0x10000
    c=0x3039
    g = g+c
    g = bit.band(g,0xFFFFFFFF)
    brnseed = g
    g = bit.lshift(g,8)
    g = bit.rshift(g,16)
    return g
end
function startingStats()
    stat = {}
    stat[1] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[2] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[3] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[4] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[5] = {0, 0, 0, 0, 0, 0, 0, 0}
    stat[6] = {0, 0, 0, 0, 0, 0, 0, 0}
    for pc=0,7 do
        dLv = memory.readbyte(0x080C0F4C + (pc * 0xB4) + 0x96)
        lv = 0
        while lv < dLv do
            lv = lv + 1
            if (lv == 1) then
                stat[1][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x50)
                stat[2][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x5C)
                stat[3][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x68)
                stat[4][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x74)
                stat[5][pc + 1] = memory.readword(0x080C0F4C + (pc * 0xB4) + 0x80)
                stat[6][pc + 1] = memory.readbyte(0x080C0F4C + (pc * 0xB4) + 0x8C)
            end

            statGrowthI = math.floor(lv / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x50 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[1][pc + 1] = stat[1][pc + 1] + math.floor(v / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x5C + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[2][pc + 1] = stat[2][pc + 1] + math.floor(v / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x68 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[3][pc + 1] = stat[3][pc + 1] + math.floor(v / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x74 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[4][pc + 1] = stat[4][pc + 1] + math.floor(v / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x80 + (statGrowthI * 2)
            v = memory.readword(v + 2) - memory.readword(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[5][pc + 1] = stat[5][pc + 1] + math.floor(v / 20)

            v = 0x080C0F4C + (pc * 0xB4) + 0x8C + (statGrowthI)
            v = memory.readbyte(v + 1) - memory.readbyte(v)
            v = v + bit.rshift(grn16() * 20, 16)
            stat[6][pc + 1] = stat[6][pc + 1] + math.floor(v / 20)

-- current stat += ((upper stat growth - lower stat growth) + ((grn16 * 20) >> 16))  / 20
        end
    end
    for i=1,6 do
        for j=1,8 do
            gui.text(90 + j * 16 ,112 + i * 6,stat[i][j])
        end
    end
end
function djinnPercents(element, djinni)
    return memory.readword(0x080B1290 + ((element - 1) * 14) + ((djinni - 1) * 2))
end
function rollDjinn()
    haveDjinni = {}
    haveDjinni[1] = {1, 0, 0, 0, 0, 0, 0}
    haveDjinni[2] = {1, 0, 0, 0, 0, 0, 0}
    haveDjinni[3] = {0, 0, 0, 0, 0, 0, 0}
    haveDjinni[4] = {0, 0, 0, 0, 0, 0, 0}
    djinnCounts = {1, 1, 0, 0}
    djinnToAdd = 16
    while djinnToAdd > 0 do
        element = 1 + bit.rshift(grn16() * 4, 16)
        djinni = 1 + bit.rshift(grn16() * 7, 16)
        if haveDjinni[element][djinni] == 0 then
            djinnCounts[element] = djinnCounts[element] + 1
            low = 9
            high = 0
            for i=1,4 do
                if djinnCounts[i] < low then
                    low = djinnCounts[i]
                end
                if djinnCounts[i] > high then
                    high = djinnCounts[i]
                end
            end
            djinnCounts[element] = djinnCounts[element] - 1
            if (high - low) <= 1 then
                if bit.rshift(grn16() * 100, 16) < djinnPercents(element, djinni) then
                    haveDjinni[element][djinni] = 1
                    djinnCounts[element] = djinnCounts[element] + 1
                    djinnToAdd = djinnToAdd - 1
                end
            end
        end
    end
    for i=1,4 do
        for j=1,7 do
            gui.text(195 + j * 5 ,0 + i * 6,haveDjinni[i][j])
        end
    end
    return
end

while true do
    reset()
    startingStats()
    reset()
    rollDjinn()
    vba.frameadvance();
end
^How does it look? I think the calculations looking better now. (Calculates base stats and not current stats, when comparing to memory viewer.)
Stat table's in a pretty bad spot = It's a bit big.... so not sure what to do with it. - I guess that's up to you.
12  Golden Sun Games / Golden Sun: The Lost Age / Re: OOB Tile replacement - Air's Rock on: August 30, 2017, 04:54:59 AM
Well, of course! Before this topic, I kinda was messing with Walk-through-walls feature... and noticed something strange about how tiles are set... when getting off tiles/going to another unreachable location... so then that's when I looked into what was going on...
That of course, was originally in a room Retreat doesn't work, so I looked at a Retreat map a bit later to notice this thing...

---
Correct, I think... as I don't think this has anything to do with sprites.... just tilemap/map code?
13  Golden Sun Games / Golden Sun: The Lost Age / Re: More RNG Questions on: August 30, 2017, 01:41:55 AM
It would return OPWR.

WR is 8-bit, OPWR is 16-bit...


By the way, the Djinn Picker's done. Still got to do stat regeneration, though... but if using this script, it'll draw 1's for the djinn you'll get on next reroll...
Code:
local grnseed = 0
local brnseed = 0

function reset()
    grnseed = memory.readdword(0x030011BC)
    brnseed = memory.readdword(0x020054C8)
end
function grn16()
    g = grnseed
    m1 = 0x4e6d
    m2 = 0x41c6
    g1 = g*m1
    g2 = g*m2
    g2 = bit.band(g2,0xFFFF)
    g = g1 + g2*0x10000
    c=0x3039
    g = g+c
    g = bit.band(g,0xFFFFFFFF)
    grnseed = g
    g = bit.lshift(g,8)
    g = bit.rshift(g,16)
    return g
end
function brn16()
    g = brnseed
    m1 = 0x4e6d
    m2 = 0x41c6
    g1 = g*m1
    g2 = g*m2
    g2 = bit.band(g2,0xFFFF)
    g = g1 + g2*0x10000
    c=0x3039
    g = g+c
    g = bit.band(g,0xFFFFFFFF)
    brnseed = g
    g = bit.lshift(g,8)
    g = bit.rshift(g,16)
    return g
end
function djinnPercents(element, djinni)
    return memory.readword(0x080B1290 + ((element - 1) * 14) + ((djinni - 1) * 2))
end
function rollDjinn()
    reset()
    haveDjinni = {}
    haveDjinni[1] = {1, 0, 0, 0, 0, 0, 0}
    haveDjinni[2] = {1, 0, 0, 0, 0, 0, 0}
    haveDjinni[3] = {0, 0, 0, 0, 0, 0, 0}
    haveDjinni[4] = {0, 0, 0, 0, 0, 0, 0}
    djinnCounts = {1, 1, 0, 0}
    djinnToAdd = 16
    while djinnToAdd > 0 do
        element = 1 + bit.rshift(grn16() * 4, 16)
        djinni = 1 + bit.rshift(grn16() * 7, 16)
        if haveDjinni[element][djinni] == 0 then
            djinnCounts[element] = djinnCounts[element] + 1
            low = 9
            high = 0
            for i=1,4 do
                if djinnCounts[i] < low then
                    low = djinnCounts[i]
                end
                if djinnCounts[i] > high then
                    high = djinnCounts[i]
                end
            end
            djinnCounts[element] = djinnCounts[element] - 1
            if (high - low) <= 1 then
                if bit.rshift(grn16() * 100, 16) < djinnPercents(element, djinni) then
                    haveDjinni[element][djinni] = 1
                    djinnCounts[element] = djinnCounts[element] + 1
                    djinnToAdd = djinnToAdd - 1
                end
            end
        end
    end
    for i=1,4 do
        for j=1,7 do
            gui.text(195 + j * 5 ,0 + i * 6,haveDjinni[i][j])
        end
    end
    return
end

while true do
    rollDjinn()
    vba.frameadvance();
end
14  Golden Sun Games / Golden Sun: The Lost Age / Re: More RNG Questions on: August 29, 2017, 07:02:47 AM
I guess we can start with #2, since I kinda have it already...

Quote from: From my GS2 Documentation
08119AD0 = if [0200048B]=00, it's checked randomly (below); if 06, your party is caught by surprise:
1/16 chance for your party to attack first.
1/32 chance for your party to be caught by surprise.

So that's generate number. (16-bit) & 0xF ; If that's 0, you attack first... if not.... then generate another number (16-bit) & 0x1F, if that's 0, your party is caught by surprise. (This second number is not generated if you are attacking first; and these checks are not made if [0200048B] is not 00.)

Pseudo-code: (To show similar formatting of GS's code.)
Code:
if ([0200048B] == 00)
{
    if ((brn16() & 0xF) == 0)
    {
        You attack first.
    }
    else if ((brn16() & 0x1F) == 0)
    {
        You are caught by surprise.
    }
}
else if ([0200048B] == 06)
{
    You are caught by surprise.
}

And as always, where I say 16-bit just means the bytes on the left/right of the 32-bit are always ignored/removed for the actual calculations. (Except for calculating the seed, but anyway.)


@0200048B = This is also in my documentation:
Quote
0200048B = Battle: Flee / Battle Type
 00 = Normal
 - 1/16 chance for your party to attack first.
 - 1/32 chance for your party to be caught by surprise.
 01 = ?
 02 = No Flee option.
 03/04 = "This is no time to be running away!"
 06 = Your party is caught by surprise.
So it just goes to show you don't get the chance to attack first with bosses and stuff...


--

And #1... Hm...
Going to review code... some of which was doc'd in the image in this post:
http://forum.goldensunhacking.net/index.php?topic=2214.msg39054#msg39054
(Except that I may have to follow the function calls.)
But otherwise will have to get back to you on that.

It does looks like Isaac's party stats are generated with Felix's as well. (At first?) ... Hm.... So I guess it's generated twice? (Probably the same calculations as normal when you level up? Will need to check.) (EDIT:
EDIT: I think I know now... ALL PCs have their stats generated at once.... but djinn have stats, so Party 1's team is updated again only by the djinn stats (And not PC levels)?

Rename Felix:
  For each PC (all 8), level to (whatever level)

Rename Isaac:
  For each Party 1 PC.... Hmm....


level up function... (psuedo)


level += 1
if (level == 1)
{
    stats are the first values of stat growths....
}
level / 20 (Determines which value of stat growth to get)

current stat += ((upper stat growth - lower stat growth) + ((grn16 * 20) >> 16))  / 20

Note:  (grn16 * 20) >> 16 basically means a random number from 0-19.
Note 2: / is supose to be integral division. (Remove decimal places.)
----

for each pc
{
    for each level
    {
        for each stat
        {
            raise stat
        }
    }
}


080AF79C = PC Starting Data
PC * 0xB4
... and for the growths ( To calculate the address location of them.)
+0x50
+0x5C
+0x68
+0x74
+0x80
+0x8C
... and then for which in each..
+(level / 20) should get you the idea.

Alternately, you can make a table for them in the script.

(Would like to test to see if I missed something, though.)



How djinn are picked...

(Flint and Fizz are 100% obtained prior to checks.)
element = (grn16() * 4) >> 16
djinni (of element) = (grn16() * 7) >> 16
If we already have this djinni, do the above two again until we don't.
If the minimum and maximum between elements is greater than 1 (if this djinni were added), generate a new djinni.... (Go back up.)
(grn16() * 100) >> 16 ; Basically check against percents to add a djinni (Table at 080B1290) , If failed, go back up.)


Psuedo-code: (May not be exact, but should be enough... but this is mainly an example anyway, so...)

haveDjinni[0, 0] == 1; //add Flint
haveDjinni[1, 0] == 1; //add Fizz
int[] djinnCounts = {1, 1, 0, 0} //For each element: Venus, Mercury, Mars, Jupiter

int djinnToAdd = 0x10
while (djinnToAdd > 0)
{
    int element = (grn16() * 4) >> 16;
    int djinni = (grn16() * 7) >> 16;
    if (haveDjinni[element, djinni] == 0)
    {
        djinnCounts[element] += 1;
        int low = 9;
        int high = 0;
        //High/low calculations/checks
        for (int e = 0; e < 4; e++)
        {
            if (djinnCounts[e] < low)
            {
                low = djinnCounts[e];
            }
            if (djinnCounts[e] > high)
            {
                high = djinnCounts[e];
            }
        }
        djinnCounts[element] -= 1;
        if ((high - low) < = 1)
        {
            //Percents calculations
            if (((grn16() * 100) >> 16) < djinnPercents[element, djinni])
            {
                haveDjinni[element, djinni] = 1;
                djinnCounts[element] += 1;
                djinnToAdd -= 1;
            }
        }
    }
}


---
Might see if I can put all this (Level up calculations and Djinn picker) in LUA soon? But I'm a bit rusty with LUA... so I don't even know if I'll go on with it.
15  Golden Sun Games / Golden Sun: The Lost Age / OOB Tile replacement - Air's Rock on: August 28, 2017, 10:25:43 PM
Similar to Tret (http://forum.goldensunhacking.net/index.php?topic=2836.0), GS2 also has some stuff that'll replace the tile at the player's coordinates. When out of bounds, this could edit other things. (It might get complicated, though.)

I haven't yet found a successfully exploitation result yet... (My assumption is it might only be good for TAS if there is something?)

There's one big thing to note, though... if you get off the tile that gets edited, it gets changed back to what it was.

Tiles are stored/grabbed from here:
02019118 = Approximate section for tiles grabbed.
02019124 = The tile gets stored here so it can change to whatever's here when you get off the tile.

Event ids to look at:
0x50
0x51
0x52
0x53

0x5A is also another, but it wasn't listed in the Retreat Map's event list. (Map 85 was what I was looking at.)


Tiles that are edited:...
Look at the pointer at 020301A4.
[020301A4]+0x8000 for the first tile to be changed.
[020301A4]+0x8200 for the second tile to be changed.
Pages: [1] 2 3 ... 149
Cbox
Today at 12:08:05 AM
Atrius: Thanks for letting me know, it should be fixed now.
Yesterday at 11:47:02 PM
Fox: Okay cool.  Speaking about broken things = There was some error I've known about for awhile now:  When you try to upload something to the Downloads section. The user may think the upload failed, but it actually succeeds. - I wonder if that was one of the few things? And whether that could be fixed if it hasn't yet.
Yesterday at 11:42:01 PM
Atrius: Oops, that wasn't even supposed to go up.  So, our hosting company moved the site over to a different server, and I was just updating some settings to fix things that broke in the move.
Yesterday at 11:39:18 PM
Fox: @Atrius: Probably going to need to update the Maintenance Description... I was confused at first, but it says 20 Mar 2017.
Yesterday at 07:29:35 AM
dawnbomb: can someone link me the discord
Yesterday at 04:52:32 AM
Majora: That's hilarious, lmao. I thought it read like something you might have written, Fox, was almost unsure if it was a bot at first
September 18, 2017, 03:01:57 PM
Fox: Yeah, he copied this post: http://forum.goldensunhacking.net/index.php?topic=1425.0
September 18, 2017, 02:57:48 PM
Fox: (Although, not sure about the last part, it just feels strangely familiar for some reason.)
September 18, 2017, 02:56:43 PM
Fox: BOT ALERT! Kill it, kill it! I think it copied one of my posts? :P
September 17, 2017, 12:58:02 AM
Fox: Not saing we actually need those ofcourse (we don't?), but more saying that minorities could get too attached to them.
September 17, 2017, 12:54:47 AM
Fox: I think it's interesting how Facebook likes to start things, and then retire them. For example, Advanced Search, and E-mail. - They seemed like pretty fine features in my opinion, but retiring them because most people aren't using them at that time? I'm not sure if they know what they're doing, but it sound like they don't. :P
September 14, 2017, 12:59:16 PM
Fox: (At leat when I think about establishments...)  ; Oops, pardon my rudeness... .I forgot to welcome you back.... Well... WElcome back! We are glad you've returned.
September 14, 2017, 12:52:57 PM
Fox: (Just want to clarify that "founded" may be an actual word, but sounds weird the way it was used.)
September 14, 2017, 12:47:42 PM
Fox: Cringy? Let me check... Hm... Low number of posts [check] (5 posts) ; misspellings/grammar [check] ("Toturial" (Torture-ial?) , ; founded, ehh.... double past-tense?) ; The best part is at least the posts have a positive attitude! (That may be the most important part?) :)
September 14, 2017, 05:59:01 AM
KeinoGSTLA: back then my posts were so cringy lmao
September 14, 2017, 05:58:39 AM
KeinoGSTLA: damn feels good to find this place again
September 10, 2017, 04:27:04 PM
Fox: I don't suppose there is anything else? ;; Hmmm... What if a Big Brother game was similar to ... er.... Exit/Corners .... which seems to have a Trust system. 
September 06, 2017, 11:02:17 AM
Plexa: Honestly we haven't looked into that ... I completely forgot about it until now!
September 06, 2017, 05:44:33 AM
Fox: (Referring to the box/crate that would allow you to get stuck.)
September 06, 2017, 05:43:42 AM
Fox: Is SW Atteka Islet the only one that forgets to update the heightmap when save/resetting? ... The Move pillar seems to update it fine... Hm.

Affiliates
Temple of Kraden Golden Sunrise
Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.094 seconds with 20 queries.