handsomematt / botw-modding

The Legend of Zelda: Breath of the Wild - Modding Documentation and Tools
71 stars 9 forks source link

Friendly request for AAMP #1

Open igoticecream opened 6 years ago

igoticecream commented 6 years ago

Hello, excellent job describing BotW files structures. Following you explanation I have been able to decompress yaz0 and unpack byml and sarc.

BotW have a lot of aamp files that I did like to take a look at them, do you have any information about them?

zephenryus commented 6 years ago

AAMP Format and a python unpacker

igoticecream commented 6 years ago

Yea i have checked those, but that description is incomplete.

Check https://github.com/jam1garner/aamp2xml/blob/master/AAMP2XML/AAMP.cs

zephenryus commented 6 years ago

Oh, I like that. I've been looking for a good c# implementation of that. Have you used that?

igoticecream commented 6 years ago

Yes i have parsed that to python and the output is a json not a xml.

The thing with that format is, it seems that the names of the values are the output of the crc32 algorithm rather that the name itself.

I have a table of all strings i have found so far on the U-King.rpx with its respective crc32 value... but still not enought. This is the output of Enemy_Lynel_Junior.bdrop

{
    "param_root": [
        {
            "TableNum": 15,
            "unknown-3688406449": "Normal",
            "unknown-1121045515": "Normal2",
            "unknown-903281821": "Normal3",
            "unknown-2880596286": "FireArrow",
            "unknown-3702872488": "FireArrow2",
            "unknown-1169950738": "FireArrow3",
            "unknown-851130500": "IceArrow",
            "unknown-2718180629": "IceArrow2",
            "unknown-3573749123": "IceArrow3",
            "unknown-3049561190": "ElectricArrow",
            "unknown-3267603696": "ElectricArrow2",
            "unknown-1540029770": "ElectricArrow3",
            "unknown-751685084": "BombArrow_A",
            "unknown-2997442687": "BombArrow_A2",
            "unknown-3316541673": "BombArrow_A3"
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 1,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_14",
            "unknown-2115683950": 10.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_13",
            "unknown-2115683950": 100.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_12",
            "unknown-2115683950": 100.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 3,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 2,
            "unknown-3335024642": "Obj_FireArrow_A_02",
            "unknown-2115683950": 50.0,
            "unknown-1606492600": "Item_Enemy_13",
            "unknown-3876820948": 50.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 1,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_14",
            "unknown-2115683950": 10.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_12",
            "unknown-2115683950": 100.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 3,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 2,
            "unknown-3335024642": "Obj_IceArrow_A_02",
            "unknown-2115683950": 50.0,
            "unknown-1606492600": "Item_Enemy_13",
            "unknown-3876820948": 50.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 1,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_14",
            "unknown-2115683950": 10.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_12",
            "unknown-2115683950": 100.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 3,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 2,
            "unknown-3335024642": "Obj_ElectricArrow_A_02",
            "unknown-2115683950": 50.0,
            "unknown-1606492600": "Item_Enemy_13",
            "unknown-3876820948": 50.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 1,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_14",
            "unknown-2115683950": 10.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_12",
            "unknown-2115683950": 100.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 3,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 2,
            "unknown-3335024642": "Obj_BombArrow_A_03",
            "unknown-2115683950": 50.0,
            "unknown-1606492600": "Item_Enemy_13",
            "unknown-3876820948": 50.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 1,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_14",
            "unknown-2115683950": 10.0
        },
        {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_12",
            "unknown-2115683950": 100.0
        }
    ]
}

As you can see, those unknown-xyx are missing names, where xyz is the crc32 value. Im looking for more info about this format.

zephenryus commented 6 years ago

I see what you mean.

I wonder if the names were compressed out. From what it looks like and referring to this, It seems that the first portion is just outlining the different types of arrows used (normal, fire, ice, electric and bomb) by the Lynel which dictates the drop.

Actually, I wonder if the json is just malformed. Perhaps the structure should be something like this

{
    "param_root": [
        {
            "TableNum": 15,
        },
        "Normal": {
            "RepeatNumMin": 1, // Drop Min
            "RepeatNumMax": 1, // Drop Max
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_14", // Lynel Guts
            "unknown-2115683950": 10.0 // Drop probability
        },
        "Normal2": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_13", // Lynel Hoof
            "unknown-2115683950": 100.0
        },
        "Normal3": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_12", // Lynel Horn
            "unknown-2115683950": 100.0
        },
        "FireArrow": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 3,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 2,
            "unknown-3335024642": "Obj_FireArrow_A_02", // Fire Arrow x10
            "unknown-2115683950": 50.0,
            "unknown-1606492600": "Item_Enemy_13", // Lynel Hoof
            "unknown-3876820948": 50.0
        },
        "FireArrow2": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 1,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_14", // Lynel Guts
            "unknown-2115683950": 10.0
        },
        "FireArrow3": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_12", // Lynel Horn
            "unknown-2115683950": 100.0
        },
        "IceArrow": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 3,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 2,
            "unknown-3335024642": "Obj_IceArrow_A_02", // Ice Arrow x10
            "unknown-2115683950": 50.0,
            "unknown-1606492600": "Item_Enemy_13", // Lynel Hoof
            "unknown-3876820948": 50.0
        },
        "IceArrow2": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 1,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_14", // Lynel Guts
            "unknown-2115683950": 10.0
        },
        "IceArrow3": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_12", // Lynel Horn
            "unknown-2115683950": 100.0
        },
        "ElectricArrow": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 3,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 2,
            "unknown-3335024642": "Obj_ElectricArrow_A_02", // Shock Arrow x10
            "unknown-2115683950": 50.0,
            "unknown-1606492600": "Item_Enemy_13", // Lynel Hoof
            "unknown-3876820948": 50.0
        },
        "ElectricArrow2": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 1,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_14", // Lynel Guts
            "unknown-2115683950": 10.0
        },
        "ElectricArrow3": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_12", // Lynel Horn
            "unknown-2115683950": 100.0
        },
        "BombArrow_A": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 3,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 2,
            "unknown-3335024642": "Obj_BombArrow_A_03", // Bomb Arrow x10
            "unknown-2115683950": 50.0,
            "unknown-1606492600": "Item_Enemy_13", // Lynel Hoof
            "unknown-3876820948": 50.0
        },
        "BombArrow_A2": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 1,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_14", // Lynel Guts
            "unknown-2115683950": 10.0
        },
        "BombArrow_A3": {
            "RepeatNumMin": 1,
            "RepeatNumMax": 2,
            "ApproachType": 0,
            "OccurrenceSpeedType": 0,
            "ColumnNum": 1,
            "unknown-3335024642": "Item_Enemy_12", // Lynel Horn
            "unknown-2115683950": 100.0
        }
    ]
}

So I wonder if the crc32 value is being returned because it is a pointer to an object? I guess that wouldn't make much sense for the probabilities though.

Thoughts?

leoetlino commented 6 years ago

The strings are dynamically generated in the function that loads info from bdrop files, so the entire string cannot be directly found in the executable (and thus your crc hashmap will be incomplete).

In particular, it looks like the game reads TableNum for the header then additional pairs of nodes depending on the number of 'tables'. Same for each table where ColumnNum is used to determine how many pairs of nodes to read (actor name + value, where value appears to be a probability between 0-100 when ApproachType is 0)