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
waitmessage B_WAIT_TIME_LONG
orword gHitMarker, HITMARKER_ATTACKSTRING_PRINTED | HITMARKER_NO_PPDEDUCT | HITMARKER_ALLOW_NO_PP
bicword gHitMarker, HITMARKER_NO_ATTACKSTRING
setmagiccoattarget BS_ATTACKER
return

View file

@ -619,6 +619,9 @@ struct BattleStruct
u8 stickyWebUser;
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.
// 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)

View file

@ -4989,6 +4989,20 @@ static bool32 TryKnockOffBattleScript(u32 battlerDef)
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)
{
s32 i;
@ -5381,6 +5395,7 @@ static void Cmd_moveend(void)
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
gProtectStructs[gBattlerAttacker].targetAffected = TRUE;
gBattleStruct->targetsDone[gBattlerAttacker] |= gBitTable[gBattlerTarget];
if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& !gProtectStructs[gBattlerAttacker].chargingTurn
@ -5388,28 +5403,12 @@ static void Cmd_moveend(void)
|| moveTarget == MOVE_TARGET_FOES_AND_ALLY)
&& !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
{
u8 battlerId;
if (moveTarget == MOVE_TARGET_FOES_AND_ALLY)
{
u32 nextTarget = GetNextTarget(moveTarget);
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;
MoveValuesCleanUp();
gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect;
@ -5417,12 +5416,32 @@ static void Cmd_moveend(void)
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
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_PPDEDUCT;
}
}
RecordLastUsedMoveBy(gBattlerAttacker, gCurrentMove);
gBattleScripting.moveendState++;
break;
@ -5635,6 +5654,7 @@ static void Cmd_moveend(void)
CancelMultiTurnMoves(gBattlerAttacker); // Cancel it
#endif
gBattleStruct->targetsDone[gBattlerAttacker] = 0;
gProtectStructs[gBattlerAttacker].usesBouncedMove = FALSE;
gProtectStructs[gBattlerAttacker].targetAffected = FALSE;
gBattleStruct->ateBoost[gBattlerAttacker] = 0;
@ -8037,6 +8057,7 @@ static void Cmd_various(void)
CancelMultiTurnMoves(gActiveBattler);
break;
case VARIOUS_SET_MAGIC_COAT_TARGET:
gBattleStruct->attackerBeforeBounce = gActiveBattler;
gBattlerAttacker = gBattlerTarget;
side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE;
if (IsAffectedByFollowMe(gBattlerAttacker, side, gCurrentMove))