Merge pull request #2230 from DizzyEggg/AI

AI remembers Party mons
This commit is contained in:
Eduardo Quezada D'Ottone 2022-09-24 11:36:25 -03:00 committed by GitHub
commit ba9f085782
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 295 additions and 29 deletions

View file

@ -246,6 +246,27 @@ struct AI_SavedBattleMon
u16 species;
};
struct AiPartyMon
{
u16 species;
u16 item;
u16 heldEffect;
u16 ability;
u16 gender;
u16 level;
u16 moves[MAX_MON_MOVES];
u32 status;
bool8 isFainted;
bool8 wasSentInBattle;
u8 switchInCount; // Counts how many times this Pokemon has been sent out or switched into in a battle.
};
struct AIPartyData // Opposing battlers - party mons.
{
struct AiPartyMon mons[2][PARTY_SIZE]; // 2 parties(player, opponent). Used to save information on opposing party.
u8 count[2];
};
struct AiLogicData
{
u16 abilities[MAX_BATTLERS_COUNT];
@ -314,6 +335,7 @@ struct BattleResources
struct StatsArray* beforeLvlUp;
struct AI_ThinkingStruct *ai;
struct AiLogicData *aiData;
struct AIPartyData *aiParty;
struct BattleHistory *battleHistory;
u8 bufferA[MAX_BATTLERS_COUNT][0x200];
u8 bufferB[MAX_BATTLERS_COUNT][0x200];
@ -321,6 +343,7 @@ struct BattleResources
#define AI_THINKING_STRUCT ((struct AI_ThinkingStruct *)(gBattleResources->ai))
#define AI_DATA ((struct AiLogicData *)(gBattleResources->aiData))
#define AI_PARTY ((struct AIPartyData *)(gBattleResources->aiParty))
#define BATTLE_HISTORY ((struct BattleHistory *)(gBattleResources->battleHistory))
struct BattleResults

View file

@ -24,6 +24,9 @@ void BattleAI_SetupItems(void);
void BattleAI_SetupFlags(void);
void BattleAI_SetupAIData(u8 defaultScoreMoves);
u8 BattleAI_ChooseMoveOrAction(void);
void Ai_InitPartyStruct(void);
void Ai_UpdateSwitchInData(u32 battler);
void Ai_UpdateFaintData(u32 battler);
void GetAiLogicData(void);
extern u8 sBattler_AI;

View file

@ -28,6 +28,7 @@ extern u8 gSelectedOrderFromParty[MAX_FRONTIER_PARTY_SIZE];
extern u8 gBattlePartyCurrentOrder[PARTY_SIZE / 2];
extern void (*gItemUseCB)(u8, TaskFunc);
extern const struct SpriteTemplate gSpriteTemplate_StatusIcons;
void AnimatePartySlot(u8 slot, u8 animNum);
bool8 IsMultiBattle(void);
@ -45,6 +46,7 @@ bool8 FieldCallback_PrepareFadeInFromMenu(void);
void CB2_ReturnToPartyMenuFromFlyMap(void);
void LoadHeldItemIcons(void);
void DrawHeldItemIconsForTrade(u8 *partyCounts, u8 *partySpriteIds, u8 whichParty);
void LoadPartyMenuAilmentGfx(void);
void CB2_ShowPartyMenuForItemUse(void);
void ItemUseCB_Medicine(u8 taskId, TaskFunc task);
void ItemUseCB_AbilityCapsule(u8 taskId, TaskFunc task);

View file

@ -239,6 +239,87 @@ u8 ComputeBattleAiScores(u8 battler)
return BattleAI_ChooseMoveOrAction();
}
static void CopyBattlerDataToAIParty(u32 bPosition, u32 side)
{
u32 battler = GetBattlerAtPosition(bPosition);
struct AiPartyMon *aiMon = &AI_PARTY->mons[side][gBattlerPartyIndexes[battler]];
struct BattlePokemon *bMon = &gBattleMons[battler];
aiMon->species = bMon->species;
aiMon->level = bMon->level;
aiMon->status = bMon->status1;
aiMon->gender = GetGenderFromSpeciesAndPersonality(bMon->species, bMon->personality);
aiMon->isFainted = FALSE;
aiMon->wasSentInBattle = TRUE;
aiMon->switchInCount++;
}
void Ai_InitPartyStruct(void)
{
u32 i;
AI_PARTY->count[B_SIDE_PLAYER] = gPlayerPartyCount;
AI_PARTY->count[B_SIDE_OPPONENT] = gEnemyPartyCount;
// Save first 2 or 4(in doubles) mons
CopyBattlerDataToAIParty(B_POSITION_PLAYER_LEFT, B_SIDE_PLAYER);
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
CopyBattlerDataToAIParty(B_POSITION_PLAYER_RIGHT, B_SIDE_PLAYER);
// If player's partner is AI, save opponent mons
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
{
CopyBattlerDataToAIParty(B_POSITION_OPPONENT_LEFT, B_SIDE_OPPONENT);
CopyBattlerDataToAIParty(B_POSITION_OPPONENT_RIGHT, B_SIDE_OPPONENT);
}
// Find fainted mons
for (i = 0; i < AI_PARTY->count[B_SIDE_PLAYER]; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0)
AI_PARTY->mons[B_SIDE_PLAYER][i].isFainted = TRUE;
}
}
void Ai_UpdateSwitchInData(u32 battler)
{
u32 i;
u32 side = GetBattlerSide(battler);
struct AiPartyMon *aiMon = &AI_PARTY->mons[side][gBattlerPartyIndexes[battler]];
// See if the switched-in mon has been already in battle
if (aiMon->wasSentInBattle)
{
if (aiMon->ability)
BATTLE_HISTORY->abilities[battler] = aiMon->ability;
if (aiMon->heldEffect)
BATTLE_HISTORY->itemEffects[battler] = aiMon->heldEffect;
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (aiMon->moves[i])
BATTLE_HISTORY->usedMoves[battler][i] = aiMon->moves[i];
}
aiMon->switchInCount++;
aiMon->status = gBattleMons[battler].status1; // Copy status, because it could've been changed in battle.
}
else // If not, copy the newly switched-in mon in battle and clear battle history.
{
ClearBattlerMoveHistory(battler);
ClearBattlerAbilityHistory(battler);
ClearBattlerItemEffectHistory(battler);
CopyBattlerDataToAIParty(GetBattlerPosition(battler), side);
}
}
void Ai_UpdateFaintData(u32 battler)
{
struct AiPartyMon *aiMon = &AI_PARTY->mons[GET_BATTLER_SIDE(battler)][gBattlerPartyIndexes[battler]];
ClearBattlerMoveHistory(battler);
ClearBattlerAbilityHistory(battler);
ClearBattlerItemEffectHistory(battler);
aiMon->isFainted = TRUE;
}
static void SetBattlerAiData(u8 battlerId)
{
AI_DATA->abilities[battlerId] = AI_GetAbility(battlerId);
@ -258,8 +339,7 @@ void GetAiLogicData(void)
memset(AI_DATA, 0, sizeof(struct AiLogicData));
if (!(gBattleTypeFlags & BATTLE_TYPE_HAS_AI)
&& !IsWildMonSmart())
if (!(gBattleTypeFlags & BATTLE_TYPE_HAS_AI) && !IsWildMonSmart())
return;
// get/assume all battler data

View file

@ -499,6 +499,7 @@ void RecordKnownMove(u8 battlerId, u32 move)
if (BATTLE_HISTORY->usedMoves[battlerId][i] == MOVE_NONE)
{
BATTLE_HISTORY->usedMoves[battlerId][i] = move;
AI_PARTY->mons[GetBattlerSide(battlerId)][gBattlerPartyIndexes[battlerId]].moves[i] = move;
break;
}
}
@ -507,6 +508,7 @@ void RecordKnownMove(u8 battlerId, u32 move)
void RecordAbilityBattle(u8 battlerId, u16 abilityId)
{
BATTLE_HISTORY->abilities[battlerId] = abilityId;
AI_PARTY->mons[GetBattlerSide(battlerId)][gBattlerPartyIndexes[battlerId]].ability = abilityId;
}
void ClearBattlerAbilityHistory(u8 battlerId)
@ -517,6 +519,7 @@ void ClearBattlerAbilityHistory(u8 battlerId)
void RecordItemEffectBattle(u8 battlerId, u8 itemEffect)
{
BATTLE_HISTORY->itemEffects[battlerId] = itemEffect;
AI_PARTY->mons[GetBattlerSide(battlerId)][gBattlerPartyIndexes[battlerId]].heldEffect = itemEffect;
}
void ClearBattlerItemEffectHistory(u8 battlerId)

View file

@ -7,6 +7,7 @@
#include "menu_helpers.h"
#include "scanline_effect.h"
#include "palette.h"
#include "party_menu.h"
#include "pokemon_icon.h"
#include "sprite.h"
#include "item.h"
@ -30,6 +31,7 @@
#include "reset_rtc_screen.h"
#include "reshow_battle_screen.h"
#include "constants/abilities.h"
#include "constants/party_menu.h"
#include "constants/moves.h"
#include "constants/items.h"
#include "constants/rgb.h"
@ -43,8 +45,8 @@ struct BattleDebugModifyArrows
u16 minValue;
u16 maxValue;
int currValue;
u8 currentDigit;
u8 maxDigits;
u8 currentDigit:4;
u8 maxDigits:4;
u8 charDigits[MAX_MODIFY_DIGITS];
void *modifiedValPtr;
u8 typeOfVal;
@ -52,7 +54,9 @@ struct BattleDebugModifyArrows
struct BattleDebugMenu
{
u8 battlerId;
u8 battlerId:2;
u8 aiBattlerId:2;
u8 battlerWindowId;
u8 mainListWindowId;
@ -72,11 +76,16 @@ struct BattleDebugMenu
const struct BitfieldInfo *bitfield;
bool8 battlerWasChanged[MAX_BATTLERS_COUNT];
u8 aiBattlerId;
u8 aiViewState;
u8 aiIconSpriteIds[MAX_BATTLERS_COUNT];
u8 aiMonSpriteId;
u8 aiMovesWindowId;
union
{
u8 aiIconSpriteIds[MAX_BATTLERS_COUNT];
u8 aiPartyIcons[PARTY_SIZE];
} spriteIds;
};
struct __attribute__((__packed__)) BitfieldInfo
@ -102,6 +111,7 @@ enum
LIST_ITEM_AI,
LIST_ITEM_AI_MOVES_PTS,
LIST_ITEM_AI_INFO,
LIST_ITEM_AI_PARTY,
LIST_ITEM_VARIOUS,
LIST_ITEM_COUNT
};
@ -234,6 +244,7 @@ static const u8 sText_Unknown[] = _("Unknown");
static const u8 sText_InLove[] = _("In Love");
static const u8 sText_AIMovePts[] = _("AI Pts/Dmg");
static const u8 sText_AiKnowledge[] = _("AI Info");
static const u8 sText_AiParty[] = _("AI Party");
static const u8 sText_EffectOverride[] = _("Effect Override");
static const u8 sText_EmptyString[] = _("");
@ -340,6 +351,7 @@ static const struct ListMenuItem sMainListItems[] =
{sText_AI, LIST_ITEM_AI},
{sText_AIMovePts, LIST_ITEM_AI_MOVES_PTS},
{sText_AiKnowledge, LIST_ITEM_AI_INFO},
{sText_AiParty, LIST_ITEM_AI_PARTY},
{sText_Various, LIST_ITEM_VARIOUS},
};
@ -610,6 +622,7 @@ static void UpdateMonData(struct BattleDebugMenu *data);
static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, bool32 statusTrue);
static bool32 TryMoveDigit(struct BattleDebugModifyArrows *modArrows, bool32 moveUp);
static void SwitchToDebugView(u8 taskId);
static void SwitchToDebugViewFromAiParty(u8 taskId);
// code
static struct BattleDebugMenu *GetStructPtr(u8 taskId)
@ -725,9 +738,9 @@ static void PutMovesPointsText(struct BattleDebugMenu *data)
AddTextPrinterParameterized(data->aiMovesWindowId, 1, text, 0, i * 15, 0, NULL);
for (count = 0, j = 0; j < MAX_BATTLERS_COUNT; j++)
{
if (data->aiIconSpriteIds[j] == 0xFF)
if (data->spriteIds.aiIconSpriteIds[j] == 0xFF)
continue;
battlerDef = gSprites[data->aiIconSpriteIds[j]].data[0];
battlerDef = gSprites[data->spriteIds.aiIconSpriteIds[j]].data[0];
ConvertIntToDecimalStringN(text,
gBattleStruct->aiFinalScore[data->aiBattlerId][battlerDef][i],
STR_CONV_MODE_RIGHT_ALIGN, 3);
@ -771,15 +784,15 @@ static void Task_ShowAiPoints(u8 taskId)
{
if (i != data->aiBattlerId && IsBattlerAlive(i))
{
data->aiIconSpriteIds[i] = CreateMonIcon(gBattleMons[i].species,
data->spriteIds.aiIconSpriteIds[i] = CreateMonIcon(gBattleMons[i].species,
SpriteCallbackDummy,
95 + (count * 60), 17, 0, 0);
gSprites[data->aiIconSpriteIds[i]].data[0] = i; // battler id
gSprites[data->spriteIds.aiIconSpriteIds[i]].data[0] = i; // battler id
count++;
}
else
{
data->aiIconSpriteIds[i] = 0xFF;
data->spriteIds.aiIconSpriteIds[i] = 0xFF;
}
}
data->aiMonSpriteId = CreateMonPicSprite(gBattleMons[data->aiBattlerId].species,
@ -823,6 +836,7 @@ static const u8 *const sAiInfoItemNames[] =
sText_HeldItem,
sText_HoldEffect,
};
static void PutAiInfoText(struct BattleDebugMenu *data)
{
u32 i, j, count;
@ -855,6 +869,53 @@ static void PutAiInfoText(struct BattleDebugMenu *data)
free(text);
}
static void PutAiPartyText(struct BattleDebugMenu *data)
{
u32 i, j, count;
u8 *text = malloc(0x50), *txtPtr;
struct AiPartyMon *aiMons = AI_PARTY->mons[GET_BATTLER_SIDE(data->aiBattlerId)];
FillWindowPixelBuffer(data->aiMovesWindowId, 0x11);
count = AI_PARTY->count[GET_BATTLER_SIDE(data->aiBattlerId)];
for (i = 0; i < count; i++)
{
if (aiMons[i].wasSentInBattle)
{
text[0] = CHAR_LV;
txtPtr = ConvertIntToDecimalStringN(text + 1, aiMons[i].level, STR_CONV_MODE_LEFT_ALIGN, 3);
*txtPtr++ = CHAR_SPACE;
if (aiMons[i].gender == MON_MALE)
*txtPtr++ = CHAR_MALE;
else if (aiMons[i].gender == MON_FEMALE)
*txtPtr++ = CHAR_FEMALE;
*txtPtr = EOS;
AddTextPrinterParameterized5(data->aiMovesWindowId, FONT_SMALL_NARROW, text, i * 41, 0, 0, NULL, 0, 0);
}
txtPtr = StringCopyN(text, gAbilityNames[aiMons[i].ability], 7); // The screen is too small to fit the whole string, so we need to drop the last letters.
*txtPtr = EOS;
AddTextPrinterParameterized5(data->aiMovesWindowId, FONT_SMALL_NARROW, text, i * 41, 15, 0, NULL, 0, 0);
for (j = 0; j < MAX_MON_MOVES; j++)
{
txtPtr = StringCopyN(text, gMoveNames[aiMons[i].moves[j]], 8);
*txtPtr = EOS;
AddTextPrinterParameterized5(data->aiMovesWindowId, FONT_SMALL_NARROW, text, i * 41, 35 + j * 15, 0, NULL, 0, 0);
}
txtPtr = StringCopyN(text, GetHoldEffectName(aiMons[i].heldEffect), 7);
*txtPtr = EOS;
AddTextPrinterParameterized5(data->aiMovesWindowId, FONT_SMALL_NARROW, text, i * 41, 35 + j * 15, 0, NULL, 0, 0);
txtPtr = ConvertIntToDecimalStringN(text, aiMons[i].switchInCount, STR_CONV_MODE_LEFT_ALIGN, 2);
*txtPtr = EOS;
AddTextPrinterParameterized5(data->aiMovesWindowId, FONT_SMALL_NARROW, text, i * 41, 35 + (j + 1) * 15, 0, NULL, 0, 0);
}
CopyWindowToVram(data->aiMovesWindowId, 3);
free(text);
}
static void Task_ShowAiKnowledge(u8 taskId)
{
u32 i, count;
@ -880,15 +941,15 @@ static void Task_ShowAiKnowledge(u8 taskId)
{
if (GET_BATTLER_SIDE(i) == B_SIDE_PLAYER && IsBattlerAlive(i))
{
data->aiIconSpriteIds[i] = CreateMonIcon(gBattleMons[i].species,
data->spriteIds.aiIconSpriteIds[i] = CreateMonIcon(gBattleMons[i].species,
SpriteCallbackDummy,
95 + (count * 80), 17, 0, 0);
gSprites[data->aiIconSpriteIds[i]].data[0] = i; // battler id
gSprites[data->spriteIds.aiIconSpriteIds[i]].data[0] = i; // battler id
count++;
}
else
{
data->aiIconSpriteIds[i] = 0xFF;
data->spriteIds.aiIconSpriteIds[i] = 0xFF;
}
}
data->aiMonSpriteId = CreateMonPicSprite(gBattleMons[data->aiBattlerId].species,
@ -919,12 +980,102 @@ static void Task_ShowAiKnowledge(u8 taskId)
}
}
#define sConditionSpriteId data[1]
static void Task_ShowAiParty(u8 taskId)
{
u32 i, ailment;
struct WindowTemplate winTemplate;
struct AiPartyMon *aiMons;
struct BattleDebugMenu *data = GetStructPtr(taskId);
switch (data->aiViewState)
{
case 0:
HideBg(0);
ShowBg(1);
LoadMonIconPalettes();
LoadPartyMenuAilmentGfx();
data->aiBattlerId = data->battlerId;
aiMons = AI_PARTY->mons[GET_BATTLER_SIDE(data->aiBattlerId)];
for (i = 0; i < AI_PARTY->count[GET_BATTLER_SIDE(data->aiBattlerId)]; i++)
{
u16 species = SPECIES_NONE; // Question mark
if (aiMons[i].wasSentInBattle && aiMons[i].species)
species = aiMons[i].species;
data->spriteIds.aiPartyIcons[i] = CreateMonIcon(species, SpriteCallbackDummy, (i * 41) + 15, 7, 1, 0);
gSprites[data->spriteIds.aiPartyIcons[i]].oam.priority = 0;
gSprites[data->spriteIds.aiPartyIcons[i]].sConditionSpriteId = CreateSprite(&gSpriteTemplate_StatusIcons, (i * 41) + 15, 7, 0);
gSprites[gSprites[data->spriteIds.aiPartyIcons[i]].sConditionSpriteId].oam.priority = 0;
if (aiMons[i].isFainted)
ailment = AILMENT_FNT;
else if (aiMons[i].status)
ailment = GetAilmentFromStatus(aiMons[i].status);
else
ailment = AILMENT_FNT + 1; // blank
StartSpriteAnim(&gSprites[gSprites[data->spriteIds.aiPartyIcons[i]].sConditionSpriteId], ailment - 1);
}
for (; i < PARTY_SIZE; i++)
data->spriteIds.aiPartyIcons[i] = 0xFF;
data->aiViewState++;
break;
// Put text
case 1:
winTemplate = CreateWindowTemplate(1, 0, 3, 29, 16, 15, 0x150);
data->aiMovesWindowId = AddWindow(&winTemplate);
PutWindowTilemap(data->aiMovesWindowId);
PutAiPartyText(data);
data->aiViewState++;
break;
// Input
case 2:
if (gMain.newKeys & (SELECT_BUTTON | B_BUTTON))
{
SwitchToDebugViewFromAiParty(taskId);
HideBg(1);
ShowBg(0);
return;
}
break;
}
}
static void SwitchToAiInfoView(u8 taskId)
{
gTasks[taskId].func = Task_ShowAiKnowledge;
GetStructPtr(taskId)->aiViewState = 0;
}
static void SwitchToAiPartyView(u8 taskId)
{
gTasks[taskId].func = Task_ShowAiParty;
GetStructPtr(taskId)->aiViewState = 0;
}
static void SwitchToDebugViewFromAiParty(u8 taskId)
{
u32 i;
struct BattleDebugMenu *data = GetStructPtr(taskId);
FreeMonIconPalettes();
for (i = 0; i < PARTY_SIZE; i++)
{
if (data->spriteIds.aiPartyIcons[i] != 0xFF)
{
DestroySpriteAndFreeResources(&gSprites[gSprites[data->spriteIds.aiPartyIcons[i]].sConditionSpriteId]);
FreeAndDestroyMonIconSprite(&gSprites[data->spriteIds.aiPartyIcons[i]]);
}
}
ClearWindowTilemap(data->aiMovesWindowId);
RemoveWindow(data->aiMovesWindowId);
gTasks[taskId].func = Task_DebugMenuProcessInput;
}
#undef sConditionSpriteId
static void SwitchToDebugView(u8 taskId)
{
u32 i;
@ -933,10 +1084,11 @@ static void SwitchToDebugView(u8 taskId)
FreeMonIconPalettes();
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (data->aiIconSpriteIds[i] != 0xFF)
FreeAndDestroyMonIconSprite(&gSprites[data->aiIconSpriteIds[i]]);
if (data->spriteIds.aiIconSpriteIds[i] != 0xFF)
FreeAndDestroyMonIconSprite(&gSprites[data->spriteIds.aiIconSpriteIds[i]]);
}
FreeAndDestroyMonPicSprite(data->aiMonSpriteId);
ClearWindowTilemap(data->aiMovesWindowId);
RemoveWindow(data->aiMovesWindowId);
gTasks[taskId].func = Task_DebugMenuProcessInput;
@ -991,6 +1143,11 @@ static void Task_DebugMenuProcessInput(u8 taskId)
SwitchToAiInfoView(taskId);
return;
}
else if (listItemId == LIST_ITEM_AI_PARTY && gMain.newKeys & A_BUTTON)
{
SwitchToAiPartyView(taskId);
return;
}
data->currentMainListItemId = listItemId;
// Create the secondary menu list.

View file

@ -3127,9 +3127,7 @@ void SwitchInClearSetData(void)
gSpecialStatuses[gActiveBattler].physicalDmg = 0;
gSpecialStatuses[gActiveBattler].specialDmg = 0;
ClearBattlerMoveHistory(gActiveBattler);
ClearBattlerAbilityHistory(gActiveBattler);
ClearBattlerItemEffectHistory(gActiveBattler);
Ai_UpdateSwitchInData(gActiveBattler);
}
void FaintClearSetData(void)
@ -3225,9 +3223,7 @@ void FaintClearSetData(void)
gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2;
gBattleMons[gActiveBattler].type3 = TYPE_MYSTERY;
ClearBattlerMoveHistory(gActiveBattler);
ClearBattlerAbilityHistory(gActiveBattler);
ClearBattlerItemEffectHistory(gActiveBattler);
Ai_UpdateFaintData(gActiveBattler);
UndoFormChange(gBattlerPartyIndexes[gActiveBattler], GET_BATTLER_SIDE(gActiveBattler), FALSE);
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]);
@ -3590,7 +3586,8 @@ static void DoBattleIntro(void)
gBattleStruct->switchInAbilitiesCounter = 0;
gBattleStruct->switchInItemsCounter = 0;
gBattleStruct->overworldWeatherDone = FALSE;
GetAiLogicData(); // get assumed abilities, hold effects, etc of all battlers
Ai_InitPartyStruct(); // Save mons party counts, and first 2/4 mons on the battlefield.
gBattleMainFunc = TryDoEventsBeforeFirstTurn;
}
break;

View file

@ -27,6 +27,7 @@ void AllocateBattleResources(void)
gBattleResources->beforeLvlUp = AllocZeroed(sizeof(*gBattleResources->beforeLvlUp));
gBattleResources->ai = AllocZeroed(sizeof(*gBattleResources->ai));
gBattleResources->aiData = AllocZeroed(sizeof(*gBattleResources->aiData));
gBattleResources->aiParty = AllocZeroed(sizeof(*gBattleResources->aiParty));
gBattleResources->battleHistory = AllocZeroed(sizeof(*gBattleResources->battleHistory));
gLinkBattleSendBuffer = AllocZeroed(BATTLE_BUFFER_LINK_SIZE);
@ -59,6 +60,7 @@ void FreeBattleResources(void)
FREE_AND_SET_NULL(gBattleResources->beforeLvlUp);
FREE_AND_SET_NULL(gBattleResources->ai);
FREE_AND_SET_NULL(gBattleResources->aiData);
FREE_AND_SET_NULL(gBattleResources->aiParty);
FREE_AND_SET_NULL(gBattleResources->battleHistory);
FREE_AND_SET_NULL(gBattleResources);

View file

@ -1082,7 +1082,7 @@ static const struct CompressedSpritePalette sSpritePalette_StatusIcons =
gStatusPal_Icons, TAG_STATUS_ICONS
};
static const struct SpriteTemplate sSpriteTemplate_StatusIcons =
const struct SpriteTemplate gSpriteTemplate_StatusIcons =
{
.tileTag = TAG_STATUS_ICONS,
.paletteTag = TAG_STATUS_ICONS,

View file

@ -241,7 +241,6 @@ static bool8 AllocPartyMenuBgGfx(void);
static void InitPartyMenuWindows(u8);
static void InitPartyMenuBoxes(u8);
static void LoadPartyMenuPokeballGfx(void);
static void LoadPartyMenuAilmentGfx(void);
static bool8 CreatePartyMonSpritesLoop(void);
static bool8 RenderPartyMenuBoxes(void);
static void CreateCancelConfirmPokeballSprites(void);
@ -4168,7 +4167,7 @@ static void CreatePartyMonStatusSprite(struct Pokemon *mon, struct PartyMenuBox
{
if (GetMonData(mon, MON_DATA_SPECIES) != SPECIES_NONE)
{
menuBox->statusSpriteId = CreateSprite(&sSpriteTemplate_StatusIcons, menuBox->spriteCoords[4], menuBox->spriteCoords[5], 0);
menuBox->statusSpriteId = CreateSprite(&gSpriteTemplate_StatusIcons, menuBox->spriteCoords[4], menuBox->spriteCoords[5], 0);
SetPartyMonAilmentGfx(mon, menuBox);
}
}
@ -4177,7 +4176,7 @@ static void CreatePartyMonStatusSpriteParameterized(u16 species, u8 status, stru
{
if (species != SPECIES_NONE)
{
menuBox->statusSpriteId = CreateSprite(&sSpriteTemplate_StatusIcons, menuBox->spriteCoords[4], menuBox->spriteCoords[5], 0);
menuBox->statusSpriteId = CreateSprite(&gSpriteTemplate_StatusIcons, menuBox->spriteCoords[4], menuBox->spriteCoords[5], 0);
UpdatePartyMonAilmentGfx(status, menuBox);
gSprites[menuBox->statusSpriteId].oam.priority = 0;
}
@ -4203,7 +4202,7 @@ static void UpdatePartyMonAilmentGfx(u8 status, struct PartyMenuBox *menuBox)
}
}
static void LoadPartyMenuAilmentGfx(void)
void LoadPartyMenuAilmentGfx(void)
{
LoadCompressedSpriteSheet(&sSpriteSheet_StatusIcons);
LoadCompressedSpritePalette(&sSpritePalette_StatusIcons);