2017-11-12 16:39:21 +01:00
|
|
|
#include "global.h"
|
|
|
|
#include "battle.h"
|
2019-03-31 19:15:39 +02:00
|
|
|
#include "battle_anim.h"
|
2017-11-12 16:39:21 +01:00
|
|
|
#include "battle_controllers.h"
|
2018-11-29 12:24:28 +01:00
|
|
|
#include "alloc.h"
|
2017-11-12 16:39:21 +01:00
|
|
|
#include "pokemon.h"
|
2019-01-13 20:50:08 +01:00
|
|
|
#include "trainer_hill.h"
|
2018-12-24 00:02:29 +01:00
|
|
|
#include "party_menu.h"
|
2017-11-12 16:39:21 +01:00
|
|
|
#include "event_data.h"
|
2017-12-05 18:55:48 +01:00
|
|
|
#include "constants/abilities.h"
|
2017-12-05 19:27:33 +01:00
|
|
|
#include "random.h"
|
2017-12-02 14:08:55 +01:00
|
|
|
#include "battle_scripts.h"
|
2017-11-12 16:39:21 +01:00
|
|
|
|
|
|
|
void AllocateBattleResources(void)
|
|
|
|
{
|
2018-09-20 22:00:00 +02:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL)
|
2019-01-13 20:50:08 +01:00
|
|
|
InitTrainerHillBattleStruct();
|
2017-11-12 16:39:21 +01:00
|
|
|
|
|
|
|
gBattleStruct = AllocZeroed(sizeof(*gBattleStruct));
|
|
|
|
|
|
|
|
gBattleResources = AllocZeroed(sizeof(*gBattleResources));
|
|
|
|
gBattleResources->secretBase = AllocZeroed(sizeof(*gBattleResources->secretBase));
|
|
|
|
gBattleResources->flags = AllocZeroed(sizeof(*gBattleResources->flags));
|
|
|
|
gBattleResources->battleScriptsStack = AllocZeroed(sizeof(*gBattleResources->battleScriptsStack));
|
|
|
|
gBattleResources->battleCallbackStack = AllocZeroed(sizeof(*gBattleResources->battleCallbackStack));
|
2019-04-05 00:05:51 +02:00
|
|
|
gBattleResources->beforeLvlUp = AllocZeroed(sizeof(*gBattleResources->beforeLvlUp));
|
2017-11-12 16:39:21 +01:00
|
|
|
gBattleResources->ai = AllocZeroed(sizeof(*gBattleResources->ai));
|
|
|
|
gBattleResources->battleHistory = AllocZeroed(sizeof(*gBattleResources->battleHistory));
|
|
|
|
gBattleResources->AI_ScriptsStack = AllocZeroed(sizeof(*gBattleResources->AI_ScriptsStack));
|
|
|
|
|
|
|
|
gLinkBattleSendBuffer = AllocZeroed(BATTLE_BUFFER_LINK_SIZE);
|
|
|
|
gLinkBattleRecvBuffer = AllocZeroed(BATTLE_BUFFER_LINK_SIZE);
|
|
|
|
|
|
|
|
gUnknown_0202305C = AllocZeroed(0x2000);
|
|
|
|
gUnknown_02023060 = AllocZeroed(0x1000);
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_SECRET_BASE)
|
|
|
|
{
|
2018-12-10 01:22:59 +01:00
|
|
|
u16 currSecretBaseId = VarGet(VAR_CURRENT_SECRET_BASE);
|
2017-11-12 16:39:21 +01:00
|
|
|
CreateSecretBaseEnemyParty(&gSaveBlock1Ptr->secretBases[currSecretBaseId]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FreeBattleResources(void)
|
|
|
|
{
|
2018-09-20 22:00:00 +02:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL)
|
2019-01-13 20:50:08 +01:00
|
|
|
FreeTrainerHillBattleStruct();
|
2017-11-12 16:39:21 +01:00
|
|
|
|
|
|
|
if (gBattleResources != NULL)
|
|
|
|
{
|
|
|
|
FREE_AND_SET_NULL(gBattleStruct);
|
|
|
|
|
|
|
|
FREE_AND_SET_NULL(gBattleResources->secretBase);
|
|
|
|
FREE_AND_SET_NULL(gBattleResources->flags);
|
|
|
|
FREE_AND_SET_NULL(gBattleResources->battleScriptsStack);
|
|
|
|
FREE_AND_SET_NULL(gBattleResources->battleCallbackStack);
|
2019-04-05 00:05:51 +02:00
|
|
|
FREE_AND_SET_NULL(gBattleResources->beforeLvlUp);
|
2017-11-12 16:39:21 +01:00
|
|
|
FREE_AND_SET_NULL(gBattleResources->ai);
|
|
|
|
FREE_AND_SET_NULL(gBattleResources->battleHistory);
|
|
|
|
FREE_AND_SET_NULL(gBattleResources->AI_ScriptsStack);
|
|
|
|
FREE_AND_SET_NULL(gBattleResources);
|
|
|
|
|
|
|
|
FREE_AND_SET_NULL(gLinkBattleSendBuffer);
|
|
|
|
FREE_AND_SET_NULL(gLinkBattleRecvBuffer);
|
|
|
|
|
|
|
|
FREE_AND_SET_NULL(gUnknown_0202305C);
|
|
|
|
FREE_AND_SET_NULL(gUnknown_02023060);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-08 11:17:41 +01:00
|
|
|
void AdjustFriendshipOnBattleFaint(u8 battlerId)
|
2017-11-12 16:39:21 +01:00
|
|
|
{
|
2018-03-01 00:59:52 +01:00
|
|
|
u8 opposingBattlerId;
|
2017-11-12 16:39:21 +01:00
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
|
|
|
{
|
2018-03-01 00:59:52 +01:00
|
|
|
u8 opposingBattlerId2;
|
2017-11-12 16:39:21 +01:00
|
|
|
|
2018-03-01 00:59:52 +01:00
|
|
|
opposingBattlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
|
|
|
opposingBattlerId2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
2017-11-12 16:39:21 +01:00
|
|
|
|
2018-03-01 00:59:52 +01:00
|
|
|
if (gBattleMons[opposingBattlerId2].level > gBattleMons[opposingBattlerId].level)
|
|
|
|
opposingBattlerId = opposingBattlerId2;
|
2017-11-12 16:39:21 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-03-01 00:59:52 +01:00
|
|
|
opposingBattlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
2017-11-12 16:39:21 +01:00
|
|
|
}
|
|
|
|
|
2018-03-01 00:59:52 +01:00
|
|
|
if (gBattleMons[opposingBattlerId].level > gBattleMons[battlerId].level)
|
2017-11-12 16:39:21 +01:00
|
|
|
{
|
2018-03-01 00:59:52 +01:00
|
|
|
if (gBattleMons[opposingBattlerId].level - gBattleMons[battlerId].level > 29)
|
2018-02-08 11:17:41 +01:00
|
|
|
AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[battlerId]], 8);
|
2017-11-12 16:39:21 +01:00
|
|
|
else
|
2018-02-08 11:17:41 +01:00
|
|
|
AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[battlerId]], 6);
|
2017-11-12 16:39:21 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[battlerId]], 6);
|
2017-11-12 16:39:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-08 11:17:41 +01:00
|
|
|
void sub_80571DC(u8 battlerId, u8 arg1)
|
2017-11-12 16:39:21 +01:00
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
if (GetBattlerSide(battlerId) != B_SIDE_OPPONENT)
|
2017-11-12 16:39:21 +01:00
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
// gBattleStruct->field_60[0][i]
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
gUnknown_0203CF00[i] = *(0 * 3 + i + (u8*)(gBattleStruct->field_60));
|
|
|
|
|
2018-02-08 11:17:41 +01:00
|
|
|
sub_81B8FB0(pokemon_order_func(gBattlerPartyIndexes[battlerId]), pokemon_order_func(arg1));
|
2017-11-12 16:39:21 +01:00
|
|
|
|
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
*(0 * 3 + i + (u8*)(gBattleStruct->field_60)) = gUnknown_0203CF00[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-08 11:17:41 +01:00
|
|
|
u32 sub_805725C(u8 battlerId)
|
2017-11-12 16:39:21 +01:00
|
|
|
{
|
|
|
|
u32 effect = 0;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
switch (gBattleCommunication[MULTIUSE_STATE])
|
|
|
|
{
|
|
|
|
case 0:
|
2018-02-08 11:17:41 +01:00
|
|
|
if (gBattleMons[battlerId].status1 & STATUS1_SLEEP)
|
2017-11-12 16:39:21 +01:00
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
if (UproarWakeUpCheck(battlerId))
|
2017-11-12 16:39:21 +01:00
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
gBattleMons[battlerId].status1 &= ~(STATUS1_SLEEP);
|
|
|
|
gBattleMons[battlerId].status2 &= ~(STATUS2_NIGHTMARE);
|
2017-11-12 16:39:21 +01:00
|
|
|
BattleScriptPushCursor();
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
|
|
|
gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
|
|
|
|
effect = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
u32 toSub;
|
|
|
|
|
2018-02-08 11:17:41 +01:00
|
|
|
if (gBattleMons[battlerId].ability == ABILITY_EARLY_BIRD)
|
2017-11-12 16:39:21 +01:00
|
|
|
toSub = 2;
|
|
|
|
else
|
|
|
|
toSub = 1;
|
|
|
|
|
2018-02-08 11:17:41 +01:00
|
|
|
if ((gBattleMons[battlerId].status1 & STATUS1_SLEEP) < toSub)
|
|
|
|
gBattleMons[battlerId].status1 &= ~(STATUS1_SLEEP);
|
2017-11-12 16:39:21 +01:00
|
|
|
else
|
2018-02-08 11:17:41 +01:00
|
|
|
gBattleMons[battlerId].status1 -= toSub;
|
2017-11-12 16:39:21 +01:00
|
|
|
|
2018-02-08 11:17:41 +01:00
|
|
|
if (gBattleMons[battlerId].status1 & STATUS1_SLEEP)
|
2017-11-12 16:39:21 +01:00
|
|
|
{
|
|
|
|
gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep;
|
|
|
|
effect = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
gBattleMons[battlerId].status2 &= ~(STATUS2_NIGHTMARE);
|
2017-11-12 16:39:21 +01:00
|
|
|
BattleScriptPushCursor();
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
|
|
|
gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
|
|
|
|
effect = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
break;
|
|
|
|
case 1:
|
2018-02-08 11:17:41 +01:00
|
|
|
if (gBattleMons[battlerId].status1 & STATUS1_FREEZE)
|
2017-11-12 16:39:21 +01:00
|
|
|
{
|
|
|
|
if (Random() % 5 != 0)
|
|
|
|
{
|
|
|
|
gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
gBattleMons[battlerId].status1 &= ~(STATUS1_FREEZE);
|
2017-11-12 16:39:21 +01:00
|
|
|
BattleScriptPushCursor();
|
|
|
|
gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze;
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
|
|
|
}
|
|
|
|
effect = 2;
|
|
|
|
}
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
} while (gBattleCommunication[MULTIUSE_STATE] != 2 && effect == 0);
|
|
|
|
|
|
|
|
if (effect == 2)
|
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
gActiveBattler = battlerId;
|
2018-02-06 20:48:02 +01:00
|
|
|
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2017-11-12 16:39:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return effect;
|
|
|
|
}
|