Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Beat Up's battle script to avoid an out-of-bounds array access #2541

Merged
merged 1 commit into from
Dec 27, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion asm/macros/battle_script.inc
Original file line number Diff line number Diff line change
@@ -1022,7 +1022,7 @@
.4byte \ptr
.endm

.macro trydobeatup endPtr:req, failPtr:req
.macro trydobeatup endPtr=NULL, failPtr=NULL
.byte 0xc4
.4byte \endPtr
.4byte \failPtr
16 changes: 9 additions & 7 deletions data/battle_scripts_1.s
Original file line number Diff line number Diff line change
@@ -5183,10 +5183,18 @@ BattleScript_EffectTeleportNew:
BattleScript_EffectTeleportNewEnd:
goto BattleScript_MoveEnd

.if B_BEAT_UP < GEN_5
BattleScript_EffectBeatUp::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
.if B_BEAT_UP >= GEN_5
attackstring
ppreduce
critcalc
damagecalc
adjustdamage
trydobeatup
goto BattleScript_HitFromAtkAnimation
.else
attackstring
pause B_WAIT_TIME_SHORT
ppreduce
@@ -5216,12 +5224,6 @@ BattleScript_BeatUpAttack::
goto BattleScript_BeatUpLoop
BattleScript_BeatUpEnd::
end
.else
BattleScript_EffectBeatUp::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
addbyte gBattleCommunication, 1
goto BattleScript_HitFromAtkString
.endif

BattleScript_EffectSemiInvulnerable::
1 change: 1 addition & 0 deletions include/battle.h
Original file line number Diff line number Diff line change
@@ -650,6 +650,7 @@ struct BattleStruct
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 beatUpSlot:3;
u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit.
u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching)
};
1 change: 1 addition & 0 deletions src/battle_main.c
Original file line number Diff line number Diff line change
@@ -3039,6 +3039,7 @@ static void BattleStartClearSetData(void)

gBattleStruct->stickyWebUser = 0xFF;
gBattleStruct->appearedInBattle = 0;
gBattleStruct->beatUpSlot = 0;

for (i = 0; i < PARTY_SIZE; i++)
{
5 changes: 5 additions & 0 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
@@ -12855,6 +12855,10 @@ static void Cmd_trysetfutureattack(void)

static void Cmd_trydobeatup(void)
{
#if B_BEAT_UP >= GEN_5
gBattleStruct->beatUpSlot++;
gBattlescriptCurrInstr += 9;
#else
struct Pokemon *party;

if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
@@ -12898,6 +12902,7 @@ static void Cmd_trydobeatup(void)
else
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5);
}
#endif
}

static void Cmd_setsemiinvulnerablebit(void)
7 changes: 4 additions & 3 deletions src/battle_util.c
Original file line number Diff line number Diff line change
@@ -230,8 +230,9 @@ static u8 CalcBeatUpPower(void)
party = gPlayerParty;
else
party = gEnemyParty;
// Party slot is set in the battle script for Beat Up
species = GetMonData(&party[gBattleCommunication[0] - 1], MON_DATA_SPECIES);

// Party slot is incremented by the battle script for Beat Up after this damage calculation
species = GetMonData(&party[gBattleStruct->beatUpSlot], MON_DATA_SPECIES);
basePower = (gSpeciesInfo[species].baseAttack / 10) + 5;

return basePower;
@@ -3875,7 +3876,7 @@ u8 AtkCanceller_UnableToUseMove(void)
gMultiHitCounter++;
}

gBattleCommunication[0] = 0; // For later
gBattleStruct->beatUpSlot = 0;
PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
}
#endif