AI knows Party mons

This commit is contained in:
DizzyEggg 2022-08-23 11:58:17 +02:00
parent 327782646b
commit 05ec8fb182
10 changed files with 82 additions and 15 deletions

Binary file not shown.

View File

@ -254,9 +254,10 @@ struct AiPartyMon
u16 gender;
u16 level;
u16 moves[MAX_MON_MOVES];
u32 status;
bool8 isFainted;
u8 switchInCount; // Counts how many times this Pokemon has been sent out or switched into in a battle.
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.

View File

@ -26,6 +26,7 @@ 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

@ -30,6 +30,7 @@ extern u8 gBattlePartyCurrentOrder[PARTY_SIZE / 2];
extern void (*gItemUseCB)(u8, TaskFunc);
extern const u16 gTutorMoves[];
extern const struct SpriteTemplate gSpriteTemplate_StatusIcons;
void AnimatePartySlot(u8 slot, u8 animNum);
bool8 IsMultiBattle(void);
@ -47,6 +48,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_ReduceEV(u8 taskId, TaskFunc task);

View File

@ -245,6 +245,7 @@ static void CopyBattlerDataToAIParty(u32 bPosition, u32 side)
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;
@ -253,6 +254,8 @@ static void CopyBattlerDataToAIParty(u32 bPosition, u32 side)
void Ai_InitPartyStruct(void)
{
u32 i;
AI_PARTY->count[B_SIDE_PLAYER] = gPlayerPartyCount;
AI_PARTY->count[B_SIDE_OPPONENT] = gEnemyPartyCount;
@ -267,6 +270,13 @@ void Ai_InitPartyStruct(void)
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)
@ -287,6 +297,8 @@ void Ai_UpdateSwitchInData(u32 battler)
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.
{
@ -297,6 +309,15 @@ void Ai_UpdateSwitchInData(u32 battler)
}
}
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);

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"
@ -883,7 +885,7 @@ static void PutAiInfoText(struct BattleDebugMenu *data)
static void PutAiPartyText(struct BattleDebugMenu *data)
{
u32 i, j, count, maxWidth;
u32 i, j, count;
u8 *text = malloc(0x50), *txtPtr;
struct AiPartyMon *aiMons = AI_PARTY->mons[GET_BATTLER_SIDE(data->aiBattlerId)];
@ -891,15 +893,37 @@ static void PutAiPartyText(struct BattleDebugMenu *data)
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, 0, 0, NULL, 0, 0);
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, 20 + j * 15, 0, NULL, 0, 0);
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);
@ -984,9 +1008,11 @@ static void Task_ShowAiKnowledge(u8 taskId)
}
}
#define sConditionSpriteId data[1]
static void Task_ShowAiParty(u8 taskId)
{
u32 i;
u32 i, ailment;
struct WindowTemplate winTemplate;
struct AiPartyMon *aiMons;
struct BattleDebugMenu *data = GetStructPtr(taskId);
@ -998,6 +1024,7 @@ static void Task_ShowAiParty(u8 taskId)
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++)
@ -1005,7 +1032,18 @@ static void Task_ShowAiParty(u8 taskId)
u16 species = SPECIES_OLD_UNOWN_B; // Question mark
if (aiMons[i].wasSentInBattle && aiMons[i].species)
species = aiMons[i].species;
data->spriteIds.aiPartyIcons[i] = CreateMonIcon(species, SpriteCallbackDummy, (i * 41) - 5 + 20, 7, 0, 0, FALSE);
data->spriteIds.aiPartyIcons[i] = CreateMonIcon(species, SpriteCallbackDummy, (i * 41) + 15, 7, 1, 0, FALSE);
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;
@ -1013,7 +1051,7 @@ static void Task_ShowAiParty(u8 taskId)
break;
// Put text
case 1:
winTemplate = CreateWindowTemplate(1, 0, 4, 30, 14, 15, 0x200);
winTemplate = CreateWindowTemplate(1, 0, 3, 29, 16, 15, 0x150);
data->aiMovesWindowId = AddWindow(&winTemplate);
PutWindowTilemap(data->aiMovesWindowId);
PutAiPartyText(data);
@ -1053,13 +1091,19 @@ static void SwitchToDebugViewFromAiParty(u8 taskId)
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;
@ -1072,6 +1116,7 @@ static void SwitchToDebugView(u8 taskId)
FreeAndDestroyMonIconSprite(&gSprites[data->spriteIds.aiIconSpriteIds[i]]);
}
FreeAndDestroyMonPicSprite(data->aiMonSpriteId);
ClearWindowTilemap(data->aiMovesWindowId);
RemoveWindow(data->aiMovesWindowId);
gTasks[taskId].func = Task_DebugMenuProcessInput;

View File

@ -3210,9 +3210,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]);

View File

@ -1143,7 +1143,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

@ -165,7 +165,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);
@ -4107,7 +4106,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);
}
}
@ -4116,7 +4115,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;
}
@ -4142,7 +4141,7 @@ static void UpdatePartyMonAilmentGfx(u8 status, struct PartyMenuBox *menuBox)
}
}
static void LoadPartyMenuAilmentGfx(void)
void LoadPartyMenuAilmentGfx(void)
{
LoadCompressedSpriteSheet(&sSpriteSheet_StatusIcons);
LoadCompressedSpritePalette(&sSpritePalette_StatusIcons);

Binary file not shown.