pokeemerald/src/battle_util2.c

213 lines
7.8 KiB
C
Raw Normal View History

2017-11-12 16:39:21 +01:00
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
2017-11-12 16:39:21 +01:00
#include "battle_controllers.h"
#include "malloc.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"
#include "random.h"
2017-12-02 14:08:55 +01:00
#include "battle_scripts.h"
#include "constants/battle_string_ids.h"
2017-11-12 16:39:21 +01:00
void AllocateBattleResources(void)
{
gBattleResources = gBattleResources; // something dumb needed to match
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);
2021-10-04 16:21:03 +02:00
gBattleAnimBgTileBuffer = AllocZeroed(0x2000);
gBattleAnimBgTilemapBuffer = AllocZeroed(0x1000);
2017-11-12 16:39:21 +01:00
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);
2021-10-04 16:21:03 +02:00
FREE_AND_SET_NULL(gBattleAnimBgTileBuffer);
FREE_AND_SET_NULL(gBattleAnimBgTilemapBuffer);
2017-11-12 16:39:21 +01:00
}
}
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)
2020-02-02 19:28:54 +01:00
AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[battlerId]], FRIENDSHIP_EVENT_FAINT_LARGE);
2017-11-12 16:39:21 +01:00
else
2020-02-02 19:28:54 +01:00
AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[battlerId]], FRIENDSHIP_EVENT_FAINT_SMALL);
2017-11-12 16:39:21 +01:00
}
else
{
2020-02-02 19:28:54 +01:00
AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[battlerId]], FRIENDSHIP_EVENT_FAINT_SMALL);
2017-11-12 16:39:21 +01:00
}
}
2019-10-26 03:55:01 +02:00
void SwitchPartyOrderInGameMulti(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;
2019-10-18 01:22:03 +02:00
for (i = 0; i < (int)ARRAY_COUNT(gBattlePartyCurrentOrder); i++)
gBattlePartyCurrentOrder[i] = *(0 * 3 + i + (u8*)(gBattleStruct->battlerPartyOrders));
2017-11-12 16:39:21 +01:00
2019-10-26 03:55:01 +02:00
SwitchPartyMonSlots(GetPartyIdFromBattlePartyId(gBattlerPartyIndexes[battlerId]), GetPartyIdFromBattlePartyId(arg1));
2017-11-12 16:39:21 +01:00
2019-10-18 01:22:03 +02:00
for (i = 0; i < (int)ARRAY_COUNT(gBattlePartyCurrentOrder); i++)
*(0 * 3 + i + (u8*)(gBattleStruct->battlerPartyOrders)) = gBattlePartyCurrentOrder[i];
2017-11-12 16:39:21 +01:00
}
}
2021-09-24 20:30:15 +02:00
// Called when a Pokémon is unable to attack during a Battle Palace battle.
// Check if it was because they are frozen/asleep, and if so try to cure the status.
u32 BattlePalace_TryEscapeStatus(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
{
2021-09-24 20:30:15 +02:00
// Wake up from Uproar
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] = B_MSG_WOKE_UP_UPROAR;
2017-11-12 16:39:21 +01:00
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;
2021-09-24 20:30:15 +02:00
// Reduce number of sleep turns
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
{
2021-09-24 20:30:15 +02:00
// Still asleep
2017-11-12 16:39:21 +01:00
gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep;
effect = 2;
}
else
{
2021-09-24 20:30:15 +02:00
// Wake up
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] = B_MSG_WOKE_UP;
2017-11-12 16:39:21 +01:00
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)
{
2021-09-24 20:30:15 +02:00
// Still frozen
2017-11-12 16:39:21 +01:00
gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen;
}
else
{
2021-09-24 20:30:15 +02:00
// Unfreeze
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] = B_MSG_DEFROSTED;
2017-11-12 16:39:21 +01:00
}
effect = 2;
}
gBattleCommunication[MULTIUSE_STATE]++;
break;
case 2:
break;
}
2021-09-24 20:30:15 +02:00
// Loop until reaching the final state, or stop early if Pokémon was Asleep/Frozen
2017-11-12 16:39:21 +01:00
} while (gBattleCommunication[MULTIUSE_STATE] != 2 && effect == 0);
if (effect == 2)
{
2018-02-08 11:17:41 +01:00
gActiveBattler = battlerId;
BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec(gActiveBattler);
2017-11-12 16:39:21 +01:00
}
return effect;
}