Fix Magic Coat targets
This commit is contained in:
parent
3facc4875a
commit
6331931ba3
3 changed files with 104 additions and 79 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Reference in a new issue