Fix Magic Coat targets

This commit is contained in:
DizzyEggg 2022-08-26 15:01:51 +02:00
parent 3facc4875a
commit 6331931ba3
3 changed files with 104 additions and 79 deletions

View file

@ -7421,6 +7421,7 @@ BattleScript_MagicCoatBounce::
printfromtable gMagicCoatBounceStringIds printfromtable gMagicCoatBounceStringIds
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
orword gHitMarker, HITMARKER_ATTACKSTRING_PRINTED | HITMARKER_NO_PPDEDUCT | HITMARKER_ALLOW_NO_PP orword gHitMarker, HITMARKER_ATTACKSTRING_PRINTED | HITMARKER_NO_PPDEDUCT | HITMARKER_ALLOW_NO_PP
bicword gHitMarker, HITMARKER_NO_ATTACKSTRING
setmagiccoattarget BS_ATTACKER setmagiccoattarget BS_ATTACKER
return return

View file

@ -619,6 +619,9 @@ struct BattleStruct
u8 stickyWebUser; u8 stickyWebUser;
u8 appearedInBattle; // Bitfield to track which Pokemon appeared in battle. Used for Burmy's form change u8 appearedInBattle; // Bitfield to track which Pokemon appeared in battle. Used for Burmy's form change
u8 skyDropTargets[MAX_BATTLERS_COUNT]; // For Sky Drop, to account for if multiple Pokemon use Sky Drop in a double battle. u8 skyDropTargets[MAX_BATTLERS_COUNT]; // For Sky Drop, to account for if multiple Pokemon use Sky Drop in a double battle.
// When using a move which hits multiple opponents which is then bounced by a target, we need to make sure, the move hits both opponents, the one with bounce, and the one without.
u8 attackerBeforeBounce:2;
u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit.
}; };
#define F_DYNAMIC_TYPE_1 (1 << 6) #define F_DYNAMIC_TYPE_1 (1 << 6)

View file

@ -4989,6 +4989,20 @@ static bool32 TryKnockOffBattleScript(u32 battlerDef)
return FALSE; return FALSE;
} }
static u32 GetNextTarget(u32 moveTarget)
{
u32 i;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (i != gBattlerAttacker
&& IsBattlerAlive(i)
&& !(gBattleStruct->targetsDone[gBattlerAttacker] & gBitTable[i])
&& (GetBattlerSide(i) != GetBattlerSide(gBattlerAttacker) || moveTarget == MOVE_TARGET_FOES_AND_ALLY))
break;
}
return i;
}
static void Cmd_moveend(void) static void Cmd_moveend(void)
{ {
s32 i; s32 i;
@ -5381,6 +5395,7 @@ static void Cmd_moveend(void)
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
gProtectStructs[gBattlerAttacker].targetAffected = TRUE; gProtectStructs[gBattlerAttacker].targetAffected = TRUE;
gBattleStruct->targetsDone[gBattlerAttacker] |= gBitTable[gBattlerTarget];
if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& !gProtectStructs[gBattlerAttacker].chargingTurn && !gProtectStructs[gBattlerAttacker].chargingTurn
@ -5388,28 +5403,12 @@ static void Cmd_moveend(void)
|| moveTarget == MOVE_TARGET_FOES_AND_ALLY) || moveTarget == MOVE_TARGET_FOES_AND_ALLY)
&& !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) && !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
{ {
u8 battlerId; u32 nextTarget = GetNextTarget(moveTarget);
if (moveTarget == MOVE_TARGET_FOES_AND_ALLY)
{
gHitMarker |= HITMARKER_NO_PPDEDUCT; gHitMarker |= HITMARKER_NO_PPDEDUCT;
for (battlerId = gBattlerTarget + 1; battlerId < gBattlersCount; battlerId++)
{
if (battlerId == gBattlerAttacker)
continue;
if (IsBattlerAlive(battlerId))
break;
}
}
else
{
battlerId = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
gHitMarker |= HITMARKER_NO_ATTACKSTRING;
}
if (IsBattlerAlive(battlerId)) if (IsBattlerAlive(nextTarget))
{ {
gBattleStruct->moveTarget[gBattlerAttacker] = gBattlerTarget = battlerId; // Fix for moxie spread moves gBattleStruct->moveTarget[gBattlerAttacker] = gBattlerTarget = nextTarget; // Fix for moxie spread moves
gBattleScripting.moveendState = 0; gBattleScripting.moveendState = 0;
MoveValuesCleanUp(); MoveValuesCleanUp();
gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect; gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect;
@ -5417,12 +5416,32 @@ static void Cmd_moveend(void)
gBattlescriptCurrInstr = BattleScript_FlushMessageBox; gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
return; return;
} }
else // Check if the move used was actually a bounced move. If so, we need to go back to the original attacker and make sure, its move hits all 2 or 3 pokemon.
else if (gProtectStructs[gBattlerAttacker].usesBouncedMove)
{ {
u8 originalBounceTarget = gBattlerAttacker;
gBattlerAttacker = gBattleStruct->attackerBeforeBounce;
gBattleStruct->targetsDone[gBattlerAttacker] |= gBitTable[originalBounceTarget];
gBattleStruct->targetsDone[originalBounceTarget] = 0;
nextTarget = GetNextTarget(moveTarget);
if (nextTarget != MAX_BATTLERS_COUNT)
{
// We found another target for the original move user.
gBattleStruct->moveTarget[gBattlerAttacker] = gBattlerTarget = nextTarget;
gBattleScripting.moveendState = 0;
gBattleScripting.animTurn = 0;
gBattleScripting.animTargetsHit = 0;
MoveValuesCleanUp();
BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]);
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
return;
}
}
gHitMarker |= HITMARKER_NO_ATTACKSTRING; gHitMarker |= HITMARKER_NO_ATTACKSTRING;
gHitMarker &= ~HITMARKER_NO_PPDEDUCT; gHitMarker &= ~HITMARKER_NO_PPDEDUCT;
} }
}
RecordLastUsedMoveBy(gBattlerAttacker, gCurrentMove); RecordLastUsedMoveBy(gBattlerAttacker, gCurrentMove);
gBattleScripting.moveendState++; gBattleScripting.moveendState++;
break; break;
@ -5635,6 +5654,7 @@ static void Cmd_moveend(void)
CancelMultiTurnMoves(gBattlerAttacker); // Cancel it CancelMultiTurnMoves(gBattlerAttacker); // Cancel it
#endif #endif
gBattleStruct->targetsDone[gBattlerAttacker] = 0;
gProtectStructs[gBattlerAttacker].usesBouncedMove = FALSE; gProtectStructs[gBattlerAttacker].usesBouncedMove = FALSE;
gProtectStructs[gBattlerAttacker].targetAffected = FALSE; gProtectStructs[gBattlerAttacker].targetAffected = FALSE;
gBattleStruct->ateBoost[gBattlerAttacker] = 0; gBattleStruct->ateBoost[gBattlerAttacker] = 0;
@ -8037,6 +8057,7 @@ static void Cmd_various(void)
CancelMultiTurnMoves(gActiveBattler); CancelMultiTurnMoves(gActiveBattler);
break; break;
case VARIOUS_SET_MAGIC_COAT_TARGET: case VARIOUS_SET_MAGIC_COAT_TARGET:
gBattleStruct->attackerBeforeBounce = gActiveBattler;
gBattlerAttacker = gBattlerTarget; gBattlerAttacker = gBattlerTarget;
side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE; side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE;
if (IsAffectedByFollowMe(gBattlerAttacker, side, gCurrentMove)) if (IsAffectedByFollowMe(gBattlerAttacker, side, gCurrentMove))