• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • Our weekly protagonist poll is now up! Vote for your favorite Conquest protagonist in the poll by clicking here.
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Switching if choice locked into bad moves

  • 14
    Posts
    6
    Years
    • Seen today
    Hi, I've been trying to add something in battle_ai_switch_items.c which will cause the AI to switch out if their pokemon is locked into a move the opponent is immune to. In normal Emerald, the AI will just sit in repeatedly selecting an ineffective move, which can be game breaking if you want trainers in your game to use choice bands regularly.

    So far what I have is:
    Code:
    static bool8 ShouldSwitchIfLockedIntoBadMove (void)
    {	 
    	u8 holdEffect;
    	u8 moveFlags;
    	u16 *choicedMove = &gBattleStruct->choicedMove[gActiveBattler];
    	u8 notveryeffectivemove;
    	u8 nvemovedamage;
    	u8 opposingPosition;
    	u8 opposingBattler;
    	
    	opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(gActiveBattler));	
    	opposingBattler = GetBattlerAtPosition(opposingPosition);
    	
    	holdEffect = ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item);
    	moveFlags = AI_TypeCalc(*choicedMove, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability);
    	
    	if (holdEffect == HOLD_EFFECT_CHOICE_BAND && moveFlags & MOVE_RESULT_DOESNT_AFFECT_FOE)
    	{
    		return TRUE;
    	}
    	else
    	{
    		return FALSE;
    	}
    }

    and a little further down, in ShouldSwitch, I have changed it to:
    Code:
        if (availableToSwitch == 0)
            return FALSE;
        if (ShouldSwitchIfPerishSong())
            return TRUE;
        if (ShouldSwitchIfLockedIntoBadMove())
    	return TRUE;
        if (ShouldSwitchIfWonderGuard())
            return TRUE;
        if (FindMonThatAbsorbsOpponentsMove())
            return TRUE;
        if (ShouldSwitchIfNaturalCure())
            return TRUE;
        if (HasSuperEffectiveMoveAgainstOpponents(FALSE))
            return FALSE;
        if (AreStatsRaised())
            return FALSE;
        if (FindMonWithFlagsAndSuperEffective(MOVE_RESULT_DOESNT_AFFECT_FOE, 2)
            || FindMonWithFlagsAndSuperEffective(MOVE_RESULT_NOT_VERY_EFFECTIVE, 3))
            return TRUE;

    In game, I have been testing it in a battle where the opponent has a banded Armaldo. Basically I bait the Armaldo to use Earthquake with Jolteon, then switch to Gengar which is immune to it. However, as soon as I select a move the following turn, the game freezes. It does not freeze under any other circumstances involving choice banders. The fact that it freezes at this specific point and only this point seems to suggest that the code is at least partially working, but I just can't figure out what's causing it to freeze instead of switching out.

    Hoping this is just some amateur error which will be easily spotted by someone else.
     
    Ok, I figured it out for anyone who's interested. I basically missed out of the bit of code which (I think) is concerned with actually switching. So, if you change the above to:

    Code:
    static bool8 ShouldSwitchIfLockedIntoBadMove(void)
    {	 
    	u8 holdEffect;
    	u8 moveFlags;
    	u16 *choicedMove = &gBattleStruct->choicedMove[gActiveBattler];
    	u8 opposingPosition;
    	u8 opposingBattler;
    	
    	opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(gActiveBattler));	
    	opposingBattler = GetBattlerAtPosition(opposingPosition);
    	
    	holdEffect = ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item);
    	moveFlags = AI_TypeCalc(*choicedMove, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability);
    	
    	if (holdEffect == HOLD_EFFECT_CHOICE_BAND && moveFlags & MOVE_RESULT_DOESNT_AFFECT_FOE)
    	{
    		*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = PARTY_SIZE;
            BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SWITCH, 0);
    		return TRUE;
    	}
    	else
    	{
    		return FALSE;
    	}
    }

    Then it will work. However, there is now a second problem where, after switching out, if the AI brings the previously choice locked pokemon back in again against the pokemon that was previously immune to its attack, it will immediately switch back out again (despite having the ability to select a new move). So it looks like the choicedMove thing isn't resetting after the AI switches a mon out. I will try and figure out how to do this and post if I succeed. In the meantime, if anyone has any suggestions they would be welcome.
     
    ...and finally:
    Code:
    static bool8 ShouldSwitchIfLockedIntoBadMove(void)
    {	 
    	u8 holdEffect;
    	u8 moveFlags;
    	u8 notveryeffectivemove;
    	u8 opposingPosition;
    	u8 opposingBattler;
    	
    	opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(gActiveBattler));	
    	opposingBattler = GetBattlerAtPosition(opposingPosition);
    	
    	holdEffect = ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item);
    	moveFlags = AI_TypeCalc(gLastMoves[gActiveBattler], gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability);
    	
    	if (holdEffect == HOLD_EFFECT_CHOICE_BAND && moveFlags & MOVE_RESULT_DOESNT_AFFECT_FOE && gDisableStructs[gActiveBattler].isFirstTurn == 0)
    	{
    		*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = PARTY_SIZE;
            BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SWITCH, 0);
    		return TRUE;
    	}
    	else
    	{
    		return FALSE;
    	}
    }

    So this makes choice band users switch out if the opponent is immune to their move, without any shenanigans involving repeated switches. Just added a simple check to see if it's the pokemon's first turn out. Just remember to add the bit to ShouldSwitch from the first post.

    Feel free to use.
     
    Back
    Top