resetes12 / pokeemerald

Modern Emerald
63 stars 10 forks source link

Hidden Power Type Effectiveness Issue Fix #9

Closed PinkShellos closed 5 months ago

PinkShellos commented 5 months ago

Addresses Hidden Power Type Effectiveness issue #8

Description

Modified src/battle_script_commands.c to add Hidden Power's type check into the Type Effectiveness functions with a conditional statement after the initial type declaration to calculate Hidden Power's type bits if the move in use is Hidden Power.

Tested by modifying Torchic to have Hidden Power as starter move and changed Zigzagoon's typing to Ghost. Type effectiveness now shows correctly.

resetes12 commented 5 months ago

Unless I'm doing something wrong, I still can't make it work. Still shows the incorrect type effectiveness, and sometimes breaks the hidden power typing so typing match-ups don't match.

I'll test further if I have the time to do so.

PinkShellos commented 5 months ago

Is there a location where the move type is recorded for the move when it’s learned? It might be easier to read from that value instead of trying to have it recalculate from the IVs each time?

PinkShellos commented 5 months ago

Alright! I've tested this one a bunch and I think I've got a good solution here!

First, a small QoL fix: It bugged me that Normal status moves like Growl were showing no-effect on a Ghost-type, but those still work. So inside the function TypeEffectiveness() in src/battle_controller_player.c, I added these lines to check for Ground's immunity to Electric-type status moves:

    if (IS_MOVE_STATUS(move) == TRUE && gBattleMoves[move].type != TYPE_ELECTRIC) {
        return 10; // return non-electric status moves as normal effectiveness
    }
    else if (IS_MOVE_STATUS(move) == TRUE && gBattleMoves[move].type == TYPE_ELECTRIC) {
        if (gBattleMons[targetId].type1 || gBattleMons[targetId].type2 == TYPE_GROUND) {
            return 26; // ground is immune to electric status moves
        }
    }

Second, I created a function to handle calculating the Hidden Power type, since it seemed like the calculations weren't working when hard-coded into the type check function directly. I added that into src/battle_script_commands.c above AI_TypeCalc()

u8 getHiddenPowerType(void)
{
    u8 typeBits  = ((gBattleMons[gBattlerAttacker].hpIV & 1) << 0)
                 | ((gBattleMons[gBattlerAttacker].attackIV & 1) << 1)
                 | ((gBattleMons[gBattlerAttacker].defenseIV & 1) << 2)
                 | ((gBattleMons[gBattlerAttacker].speedIV & 1) << 3)
                 | ((gBattleMons[gBattlerAttacker].spAttackIV & 1) << 4)
                 | ((gBattleMons[gBattlerAttacker].spDefenseIV & 1) << 5);

    // Subtract 3 instead of 1 below because 2 types are excluded (TYPE_NORMAL and TYPE_MYSTERY)
    // The final + 1 skips past Normal, and the following conditional skips TYPE_MYSTERY
    u8 type = ((NUMBER_OF_MON_TYPES - 2) * typeBits) / 63 + 1;
    if (type == TYPE_MYSTERY)
        type = TYPE_FAIRY;
    return type;
}

Inside AI_TypeCalc(), I replaced moveType = gBattleMoves[move].type; with:

    if (move == MOVE_HIDDEN_POWER)
        moveType = getHiddenPowerType();
    else
        moveType = gBattleMoves[move].type;

Give it a test and let me know if it works for you!

resetes12 commented 5 months ago

Alright! I've tested this one a bunch and I think I've got a good solution here!

First, a small QoL fix: It bugged me that Normal status moves like Growl were showing no-effect on a Ghost-type, but those still work. So inside the function TypeEffectiveness() in src/battle_controller_player.c, I added these lines to check for Ground's immunity to Electric-type status moves:

    if (IS_MOVE_STATUS(move) == TRUE && gBattleMoves[move].type != TYPE_ELECTRIC) {
        return 10; // return non-electric status moves as normal effectiveness
    }
    else if (IS_MOVE_STATUS(move) == TRUE && gBattleMoves[move].type == TYPE_ELECTRIC) {
        if (gBattleMons[targetId].type1 || gBattleMons[targetId].type2 == TYPE_GROUND) {
            return 26; // ground is immune to electric status moves
        }
    }

Second, I created a function to handle calculating the Hidden Power type, since it seemed like the calculations weren't working when hard-coded into the type check function directly. I added that into src/battle_script_commands.c above AI_TypeCalc()

u8 getHiddenPowerType(void)
{
    u8 typeBits  = ((gBattleMons[gBattlerAttacker].hpIV & 1) << 0)
                 | ((gBattleMons[gBattlerAttacker].attackIV & 1) << 1)
                 | ((gBattleMons[gBattlerAttacker].defenseIV & 1) << 2)
                 | ((gBattleMons[gBattlerAttacker].speedIV & 1) << 3)
                 | ((gBattleMons[gBattlerAttacker].spAttackIV & 1) << 4)
                 | ((gBattleMons[gBattlerAttacker].spDefenseIV & 1) << 5);

    // Subtract 3 instead of 1 below because 2 types are excluded (TYPE_NORMAL and TYPE_MYSTERY)
    // The final + 1 skips past Normal, and the following conditional skips TYPE_MYSTERY
    u8 type = ((NUMBER_OF_MON_TYPES - 2) * typeBits) / 63 + 1;
    if (type == TYPE_MYSTERY)
        type = TYPE_FAIRY;
    return type;
}

Inside AI_TypeCalc(), I replaced moveType = gBattleMoves[move].type; with:

    if (move == MOVE_HIDDEN_POWER)
        moveType = getHiddenPowerType();
    else
        moveType = gBattleMoves[move].type;

Give it a test and let me know if it works for you!

Cool! I have limited time so I can't do much, sorry about that.

It seems to work though! I would like to test it extensively before merging, but first impressions are good and type match-up works as expected. Haven't tried the first part, but I also think it's a great addition and a nice idea overall. Let's see if this weekend I can merge it.

Thanks for your support to the project! I would gladly consider any other addition you think could work for this game.

PinkShellos commented 5 months ago

Thanks so much! I’ll resolve the conflicts on PR #6 after it’s merged.