Split pokemon summary window and pokemon evolution

This commit is contained in:
DizzyEggg 2025-06-08 13:47:30 +02:00
parent 3f5201a72a
commit 1c2bec003e
19 changed files with 696 additions and 733 deletions

View File

@ -3,53 +3,7 @@
.align 2,0
@ pokemon_3 #2
.string "pksdir0\0"
@ pokemon_3 #3
.string "pksdir0\0"
.global gUnknown_8107754
gUnknown_8107754: @ 8107754
.string "Stats\0"
.align 2,0
.global gUnknown_810775C
gUnknown_810775C: @ 810775C
.string "Features\0"
.align 2,0
.global gUnknown_8107768
gUnknown_8107768: @ 8107768
.string "Type:\0"
.align 2,0
.global gUnknown_8107770
gUnknown_8107770: @ 8107770
.string "Special Abilities:\0"
.align 2,0
.global gUnknown_8107784
gUnknown_8107784: @ 8107784
.string "{MOVE_ITEM_1}\0"
.align 2,0
.global gUnknown_8107788
gUnknown_8107788: @ 8107788
.byte 0x87, 0x42, 0x00, 0x00
.global gUnknown_810778C
gUnknown_810778C: @ 810778C
.byte 0x87, 0x40, 0x00, 0x00
.global gUnknown_8107790
gUnknown_8107790: @ 8107790
.string "{MOVE_ITEM_0}{MOVE_ITEM_1}\0"
.align 2,0
.global gUnknown_8107798
gUnknown_8107798: @ 8107798
.string "Info\0"
.align 2,0
@ dungeon
.string "pksdir0\0"
.align 2,0

View File

@ -2,9 +2,8 @@
#define GUARD_CODE_8024458_H
#include "structs/menu.h"
#include "structs/str_text.h"
#include "pokemon_3.h"
#include "pokemon_summary_window.h"
struct unkStruct_203B2AC
{
@ -12,7 +11,7 @@ struct unkStruct_203B2AC
u32 unk34[3];
u8 unk40[0x48 - 0x40];
s16 speciesNum;
struct unkStruct_808FF20 unk4C;
struct MonSummaryInfo unk4C;
struct UnkInfoTabStruct unkB0;
u32 unkE0;
WindowTemplate *unkE4;

View File

@ -4,7 +4,7 @@
#include "structs/dungeon_entity.h"
#include "structs/str_moves.h"
#include "structs/str_pokemon.h"
#include "pokemon_3.h"
#include "pokemon_summary_window.h"
struct unkStruct_8069D4C
{
@ -42,7 +42,7 @@ Entity * sub_8069660(Entity *target);
Entity * sub_80696A8(Entity *target);
Entity * sub_80696FC(Entity *target);
Entity * sub_806977C(Entity *target);
void sub_8069844(struct unkStruct_808FF20 *param_1, Entity *target);
void SetMonSummaryInfoFromEntity(struct MonSummaryInfo *param_1, Entity *target);
bool8 sub_8069D18(DungeonPos *pos,Entity *entity);
void sub_8069D4C(struct unkStruct_8069D4C *r0, Entity *target);
void TargetTileInFront(Entity *pokemon);

View File

@ -4,7 +4,7 @@
#include "file_system.h"
#include "items.h"
#include "structs/menu.h"
#include "pokemon_3.h"
#include "pokemon_evolution.h"
#include "structs/str_text.h"
// size: 0x174

View File

@ -74,7 +74,7 @@ s16 GetRecruitRate(s16 index);
s16 GetAlphabetParentNo(s16 index, s32 r1);
s16 GetInternalNo(s16 index);
s32 CalculateEXPGain(s16 index, s32 level);
s16 GetPokemonEvolveConditons(s16 index, unkEvolve *);
s16 GetPokemonEvolveConditions(s16 index, unkEvolve *r1);
u8 GetPokemonOverworldPalette(s16 index, bool32 recolorShopKecleon);
bool8 IsPokemonDialogueSpriteAvail(s16 index, s32 spriteId);
OpenedFile *OpenPokemonDialogueSpriteFile(s16 index);

View File

@ -4,58 +4,6 @@
#include "pokemon.h"
#include "structs/str_spawn_pokemon_data.h"
// size: 0x8
typedef struct EvolveStatus
{
/* 0x0 */ u8 evoItem1;
/* 0x1 */ u8 evoItem2;
// This value is set to a random number in the range [0, 254].
// Even values produce Silcoon while odd values produce Cascoon.
/* 0x2 */ u8 wurmpleVal;
/* 0x4 */ u16 evolutionConditionStatus;
/* 0x6 */ s16 targetEvolveSpecies;
} EvolveStatus;
struct unkStruct_808FF20
{
// size: 0x64
s16 species;
u8 nameBuffer[0x14];
u8 types[2]; // 0x16
u8 abilities[2]; // 0x18
u8 fill1A[0x1C - 0x1A];
DungeonLocation dungeonLocation; // 0x1C
Item item; // 0x20
s32 HP1;
s32 HP2;
s32 level;
u32 exp;
Offense offense;
bool8 isTeamLeader;
u8 atkBoost;
u8 spAtkBoost;
u8 defBoost;
u8 spDefBoost;
u8 fill3D;
s16 IQ; // 0x3E
s16 unk40;
s16 fill42;
struct unkPokeSubStruct_C unk44[2];
u8 unk4C;
u8 fill4D[3];
IqSkillFlags IQSkills; // 0x50
u8 tactic;
u8 fill55[1];
s16 unk56;
u8 unk58[12];
};
struct UnkInfoTabStruct
{
u8 unk0[0xC];
s32 unkC[9];
};
bool8 HasRecruitedMon(s16 species);
s16 GetBaseSpecies(s16 index);
s16 GetBaseSpeciesNoUnown(s16 index);
@ -70,16 +18,10 @@ void ToggleIQSkill(IqSkillFlags *iq, u32 skillIndex);
void SetIQSkill(IqSkillFlags *iq, u32 skillIndex);
bool8 IsIQSkillSet(IqSkillFlags *iq, u32 IQSkillBit);
void SetDefaultIQSkills(IqSkillFlags *iq, bool8 enableSelfCurer);
void sub_808F468(PokemonStruct1 *param_1, EvolveStatus *evolveStatus, bool8 param_3);
s32 sub_808F700(PokemonStruct1 *pokemon);
PokemonStruct1 *sub_808F734(PokemonStruct1 *pokemon, s16 _species);
s16 ExtractSpeciesIndex(SpawnPokemonData *data);
void SetSpeciesToExtract(SpawnPokemonData *data, s32 species_);
void SetSpeciesLevelToExtract(SpawnPokemonData *data, s32 level, s32 species_);
s32 ExtractLevel(SpawnPokemonData *data);
PokemonStruct1 *sub_808F798(PokemonStruct1 *pokemon, short _species);
void CreatePokemonInfoTabScreen(s32 param_1, s32 param_2, struct unkStruct_808FF20 *mon, struct UnkInfoTabStruct *param_4, u32 windowId);
void sub_808FF20(struct unkStruct_808FF20 *param_1, struct PokemonStruct1 *pokemon, bool8 param_3);
void sub_808ED00(void);

View File

@ -0,0 +1,23 @@
#ifndef GUARD_POKEMON_EVOLUTION_H
#define GUARD_POKEMON_EVOLUTION_H
#include "structs/str_pokemon.h"
// size: 0x8
typedef struct EvolveStatus
{
/* 0x0 */ u8 evoItem1;
/* 0x1 */ u8 evoItem2;
// This value is set to a random number in the range [0, 254].
// Even values produce Silcoon while odd values produce Cascoon.
/* 0x2 */ u8 wurmpleVal;
/* 0x4 */ u16 evolutionConditionStatus;
/* 0x6 */ s16 targetEvolveSpecies;
} EvolveStatus;
void sub_808F468(struct PokemonStruct1 *pokemon, EvolveStatus *evolveStatus,bool8 param_3);
s32 sub_808F700(PokemonStruct1 *pokemon);
PokemonStruct1 *sub_808F734(PokemonStruct1 *pokemon, s16 _species);
PokemonStruct1 *sub_808F798(PokemonStruct1 *pokemon, s16 _species);
#endif // GUARD_POKEMON_EVOLUTION_H

View File

@ -0,0 +1,60 @@
#ifndef GUARD_POKEMON_SUMMARY_WINDOW_H
#define GUARD_POKEMON_SUMMARY_WINDOW_H
#include "structs/str_dungeon_location.h"
#include "structs/str_pokemon.h"
enum
{
SUB_WINDOW_NONE,
SUB_WINDOW_STATUS,
SUB_WINDOW_STATS,
SUB_WINDOW_FEATUERS,
SUB_WINDOW_IQ,
SUB_WINDOW_INFO,
};
struct MonSummaryInfo
{
// size: 0x64
s16 species;
u8 nameBuffer[0x14];
u8 types[2]; // 0x16
u8 abilities[2]; // 0x18
u8 fill1A[0x1C - 0x1A];
DungeonLocation dungeonLocation; // 0x1C
Item item; // 0x20
s32 HP1;
s32 HP2;
s32 level;
u32 exp;
Offense offense;
bool8 isTeamLeader;
u8 atkBoost;
u8 spAtkBoost;
u8 defBoost;
u8 spDefBoost;
u8 fill3D;
s16 IQ; // 0x3E
s16 unk40;
s16 fill42;
struct unkPokeSubStruct_C unk44[2];
u8 unk4C;
u8 fill4D[3];
IqSkillFlags IQSkills; // 0x50
u8 tactic;
u8 fill55[1];
s16 unk56;
u8 unk58[12];
};
struct UnkInfoTabStruct
{
u8 unk0[0xC];
s32 unkC[9];
};
void ShowPokemonSummaryWindow(s32 which, s32 currSubWindowId, struct MonSummaryInfo *monInfo, struct UnkInfoTabStruct *param_4, u32 windowId);
void SetMonSummaryInfo(struct MonSummaryInfo *dst, struct PokemonStruct1 *pokemon, bool8 param_3);
#endif // GUARD_POKEMON_SUMMARY_WINDOW_H

View File

@ -306,6 +306,8 @@ SECTIONS {
src/dungeon_portrait_placement.o(.text);
src/pokemon.o(.text);
src/pokemon_3.o(.text);
src/pokemon_evolution.o(.text);
src/pokemon_summary_window.o(.text);
src/dungeon.o(.text);
src/items.o(.text);
src/rescue_team_info.o(.text);
@ -672,6 +674,8 @@ SECTIONS {
src/dungeon_portrait_placement.o(.rodata);
src/pokemon.o(.rodata);
src/pokemon_3.o(.rodata);
src/pokemon_evolution.o(.rodata);
src/pokemon_summary_window.o(.rodata);
data/data_81076E4.o(.rodata);
src/game_options.o(.rodata);
src/random_mersenne_twister.o(.rodata);

View File

@ -8,7 +8,7 @@
#include "memory.h"
#include "menu_input.h"
#include "pokemon.h"
#include "pokemon_3.h"
#include "pokemon_summary_window.h"
#include "text_1.h"
static EWRAM_INIT struct unkStruct_203B2AC *sUnknown_203B2AC = {NULL};
@ -83,13 +83,13 @@ static void sub_8024588(void)
static void sub_80245D0(void)
{
CreatePokemonInfoTabScreen(sUnknown_203B2AC->unk34[sUnknown_203B2AC->input.unk1E], sUnknown_203B2AC->input.unk1E, &sUnknown_203B2AC->unk4C, &sUnknown_203B2AC->unkB0, sUnknown_203B2AC->unkE0);
ShowPokemonSummaryWindow(sUnknown_203B2AC->unk34[sUnknown_203B2AC->input.unk1E], sUnknown_203B2AC->input.unk1E, &sUnknown_203B2AC->unk4C, &sUnknown_203B2AC->unkB0, sUnknown_203B2AC->unkE0);
}
static void sub_8024604(void)
{
PokemonStruct1 *pokeStruct;
struct unkStruct_808FF20 *iVar3;
struct MonSummaryInfo *iVar3;
sUnknown_203B2AC->unk34[0] = 2;
sUnknown_203B2AC->unk34[1] = 3;
@ -98,5 +98,5 @@ static void sub_8024604(void)
sub_8013818(&sUnknown_203B2AC->input, 3, 1, sUnknown_203B2AC->unkE0);
iVar3 = &sUnknown_203B2AC->unk4C;
pokeStruct = &gRecruitedPokemonRef->pokemon[sUnknown_203B2AC->speciesNum];
sub_808FF20(iVar3, pokeStruct, sub_80023E4(7));
SetMonSummaryInfo(iVar3, pokeStruct, sub_80023E4(7));
}

View File

@ -388,7 +388,7 @@ void sub_8067F00(u8 a0, PokemonStruct1 **a1, s32 a2_, s32 a3, s32 a4)
void sub_806806C(PokemonStruct1 *a0)
{
struct unkStruct_808FF20 unkStruct;
struct MonSummaryInfo unkStruct;
struct UnkInfoTabStruct var_C8;
WindowTemplates spTxtStruct = {0};
s32 r7;
@ -431,8 +431,8 @@ void sub_806806C(PokemonStruct1 *a0)
sub_801317C(&gDungeonMenu.unk28);
DungeonShowWindows(&spTxtStruct, 1);
sub_808FF20(&unkStruct, a0, gDungeon->unk644.unk16);
CreatePokemonInfoTabScreen(spF8[r7], r7, &unkStruct, &var_C8, 0);
SetMonSummaryInfo(&unkStruct, a0, gDungeon->unk644.unk16);
ShowPokemonSummaryWindow(spF8[r7], r7, &unkStruct, &var_C8, 0);
gDungeonMenu.unkC = (gWindows[0].x + 15) * 8;
gDungeonMenu.unkE = ((gWindows[0].y + 1) * 8) - 2;

View File

@ -10,6 +10,8 @@
#include "string_format.h"
#include "code_80958E8.h"
#include "mailbox.h"
#include "items.h"
#include "pokemon.h"
#include "structs/str_dungeon.h"
#include "constants/dungeon.h"

View File

@ -106,7 +106,6 @@ extern void sub_8045064(void);
extern void sub_8070968(u8 *buffer, EntityInfo *entityInfo, s32 colorNum);
extern bool8 CanLeaderSwitch(u8 dungeon);
extern void GetAvailTacticsforLvl(u8 *tacticsBuffer, s32 pokeLevel);
extern void sub_8069844(struct unkStruct_808FF20 *param_1, Entity *target);
extern u32 sub_8014140(s32 a0, const void *a1);
extern char* sub_808E4FC(s32 a1);
extern char* sub_808E51C(s32 a1);
@ -712,21 +711,11 @@ static void PrintMonTactics(s32 firstId, u8 *tacticIds, EntityInfo *mon, s32 win
sub_80073E0(windowId);
}
enum
{
SUB_WINDOW_NONE,
SUB_WINDOW_STATUS,
SUB_WINDOW_STATS,
SUB_WINDOW_FEATUERS,
SUB_WINDOW_IQ,
SUB_WINDOW_INFO,
};
// The way this function was written, it seems that they planned to put IQ skills in the Summary Menu first, but later decided to create a separate menu for it.
void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
{
s32 subWindowIds[6];
struct unkStruct_808FF20 unkMonStruct;
struct MonSummaryInfo monSummaryInfo;
struct UnkInfoTabStruct unkInfoTabStruct;
WindowTemplates windows = {
.id = {
@ -783,8 +772,8 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
totalSubWindows = 4;
}
unkMonStruct.unk40 = 0;
unkMonStruct.unk56 = 0;
monSummaryInfo.unk40 = 0;
monSummaryInfo.unk56 = 0;
gDungeonMenu.menuIndex = 0;
while (1) {
@ -799,8 +788,8 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
sTeamWindowHeader.width = 10;
sTeamWindowHeader.f3 = 0;
DungeonShowWindows(&windows, TRUE);
sub_8069844(&unkMonStruct, entity);
CreatePokemonInfoTabScreen(subWindowIds[currSubWindowId], currSubWindowId, &unkMonStruct, &unkInfoTabStruct, 0);
SetMonSummaryInfoFromEntity(&monSummaryInfo, entity);
ShowPokemonSummaryWindow(subWindowIds[currSubWindowId], currSubWindowId, &monSummaryInfo, &unkInfoTabStruct, 0);
gDungeonMenu.unk1E = currSubWindowId;
gDungeonMenu.unk20 = totalSubWindows;
gDungeonMenu.unkC = (mainWindow->x + 15) * 8;
@ -862,7 +851,7 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
r5 = TRUE;
ShowDownArrowSprite();
}
if (unkMonStruct.unk40 != 0) {
if (monSummaryInfo.unk40 != 0) {
r6 = TRUE;
ShowUpArrowSprite();
}
@ -872,7 +861,7 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
r5 = TRUE;
ShowDownArrowSprite();
}
if (unkMonStruct.unk56 != 0) {
if (monSummaryInfo.unk56 != 0) {
r6 = TRUE;
ShowUpArrowSprite();
}
@ -910,7 +899,7 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
ScrollDownWindowFunc(0);
DungeonRunFrameActions(28);
}
unkMonStruct.unk56++;
monSummaryInfo.unk56++;
}
r8 = 7;
break;
@ -924,7 +913,7 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
ScrollDownWindowFunc(0);
DungeonRunFrameActions(28);
}
unkMonStruct.unk56++;
monSummaryInfo.unk56++;
}
r8 = 7;
break;
@ -935,13 +924,13 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
}
if (unkVar == 1 && r6) {
if (unkMonStruct.unk56 != 0) {
if (monSummaryInfo.unk56 != 0) {
s32 i;
for (i = 0; i < 6; i++) {
ScrollUpWindowFunc(0);
DungeonRunFrameActions(28);
}
unkMonStruct.unk56--;
monSummaryInfo.unk56--;
}
r8 = 0;
break;
@ -949,13 +938,13 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
if (gRealInputs.repeated & DPAD_UP) {
PlayDungeonCursorSE(1);
if (gDungeonMenu.menuIndex == 0) {
if (unkMonStruct.unk56 != 0) {
if (monSummaryInfo.unk56 != 0) {
s32 i;
for (i = 0; i < 6; i++) {
ScrollUpWindowFunc(0);
DungeonRunFrameActions(28);
}
unkMonStruct.unk56--;
monSummaryInfo.unk56--;
}
r8 = 0;
break;
@ -973,7 +962,7 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
ScrollDownWindowFunc(0);
DungeonRunFrameActions(28);
}
unkMonStruct.unk40++;
monSummaryInfo.unk40++;
}
r8 = 7;
break;
@ -987,7 +976,7 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
ScrollDownWindowFunc(0);
DungeonRunFrameActions(28);
}
unkMonStruct.unk40++;
monSummaryInfo.unk40++;
}
r8 = 7;
break;
@ -998,13 +987,13 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
}
if (unkVar == 1 && r6) {
if (unkMonStruct.unk40 != 0) {
if (monSummaryInfo.unk40 != 0) {
s32 i;
for (i = 0; i < 6; i++) {
ScrollUpWindowFunc(0);
DungeonRunFrameActions(28);
}
unkMonStruct.unk40--;
monSummaryInfo.unk40--;
}
r8 = 0;
break;
@ -1012,13 +1001,13 @@ void ShowDungeonSummaryOrIQMenu(ActionContainer *a0, bool8 showIq)
if (gRealInputs.repeated & DPAD_UP) {
PlayDungeonCursorSE(1);
if (gDungeonMenu.menuIndex == 0) {
if (unkMonStruct.unk40 != 0) {
if (monSummaryInfo.unk40 != 0) {
s32 i;
for (i = 0; i < 6; i++) {
ScrollUpWindowFunc(0);
DungeonRunFrameActions(28);
}
unkMonStruct.unk40--;
monSummaryInfo.unk40--;
}
r8 = 0;
break;

View File

@ -8,6 +8,7 @@
#include "file_system.h"
#include "pokemon.h"
#include "pokemon_3.h"
#include "pokemon_evolution.h"
#include "moves.h"
#include "string_format.h"
#include "friend_area.h"
@ -831,7 +832,7 @@ Entity * sub_806977C(Entity *target)
return NULL;
}
void sub_8069844(struct unkStruct_808FF20 *param_1, Entity *target)
void SetMonSummaryInfoFromEntity(struct MonSummaryInfo *param_1, Entity *target)
{
int index;
u8 *atkPtr;

View File

@ -20,6 +20,7 @@
#include "string_format.h"
#include "text_1.h"
#include "text_util.h"
#include "pokemon_evolution.h"
enum
{

View File

@ -25,6 +25,7 @@
#include "dungeon_random.h"
#include "dungeon_misc.h"
#include "dungeon_spawns.h"
#include "pokemon_3.h"
extern u32 gUnknown_8106A4C;

View File

@ -1,16 +1,12 @@
#include "global.h"
#include "globaldata.h"
#include "constants/ability.h"
#include "constants/colors.h"
#include "constants/dungeon.h"
#include "constants/evolve_type.h"
#include "constants/evolution_status.h"
#include "constants/iq_skill.h"
#include "constants/tactic.h"
#include "constants/type.h"
#include "structs/sprite_oam.h"
#include "structs/str_pokemon.h"
#include "code_8097670.h"
#include "dungeon.h"
#include "friend_area.h"
#include "luminous_cave.h"
@ -35,20 +31,6 @@ struct UnusedOffenseStruct
};
extern SpriteOAM gShadowSprites[3]; // Shadow sprites of some kind
extern const s16 gUnknown_810AC60; // 0xC
extern const s16 gUnknown_810AC62; // 0xC
extern const s16 gUnknown_810AC68; // 0x8
extern const s16 gUnknown_810AC64; // 0x8
extern const s16 gUnknown_810AC66; // 0x8
extern u8 gUnknown_8107754[];
extern u8 gUnknown_810775C[];
extern u8 gUnknown_8107768[];
extern u8 gUnknown_8107770[];
extern u8 gUnknown_8107784[];
extern u8 gUnknown_8107788[];
extern u8 gUnknown_810778C[];
extern u8 gUnknown_8107790[];
extern u8 gUnknown_8107798[];
extern void WriteDungeonLocationBits(DataSerializer*, DungeonLocation*);
extern void WritePoke1LevelBits(DataSerializer*, struct unkPokeSubStruct_C*);
@ -324,11 +306,7 @@ UNUSED static void GetMonOffenseStats(PokemonStruct1 *mon, struct UnusedOffenseS
}
}
// TODO: File boundary?
// NOTE: File boundary is here in Blue, however pksdir string is missing, so we can't split here.
const u8 *GetIQSkillName(u8 skill)
{
return gIQSkillNames[skill];
@ -522,59 +500,51 @@ bool8 IsIQSkillSet(IqSkillFlags *iq, u32 IQSkillBit)
}
}
u32 sub_808ECFC(void)
UNUSED static u32 sub_808ECFC(void)
{
return 0;
}
// This function does nothing in Blue
void sub_808ED00(void)
{
s32 team[4];
s32 i;
s32 length = sub_808D580(team);
if (GAME_VERSION == VERSION_RED) {
s32 team[4];
s32 i;
s32 length = sub_808D580(team);
for (i = 0; i < length; i++) {
gRecruitedPokemonRef->team[i] = gRecruitedPokemonRef->pokemon[team[i]];
}
for (i = 0; i < length; i++) {
gRecruitedPokemonRef->team[i] = gRecruitedPokemonRef->pokemon[team[i]];
}
for (; i < MAX_TEAM_MEMBERS; i++) {
gRecruitedPokemonRef->team[i].unk0 = FLAG_NONE;
for (; i < MAX_TEAM_MEMBERS; i++) {
gRecruitedPokemonRef->team[i].unk0 = FLAG_NONE;
}
}
}
// File boundary here
// arm9.bin::0205CC54
s32 SaveRecruitedPokemon(u8 *a1, s32 a2)
{
u16 sixMons[6];
s16 sixMons[6];
DataSerializer backup;
u8 data_u8;
s16 teamLeader;
s32 minus1;
s32 count;
s32 i;
PokemonStruct1 *pokemon;
InitBitWriter(&backup, a1, a2);
for (i = 0; i < 6; i++)
sixMons[i] = -1;
teamLeader = 1; // Maybe fakematch, should be -1
teamLeader = -teamLeader;
// s16 memes
minus1 = -1;
teamLeader = minus1;
count = 0;
for (i = 0; i < NUM_MONSTERS; i++) {
// Fakematch, probably need the PokemonFlag2 inline
if (i) {
u8 unk = -unk;
}
pokemon = &gRecruitedPokemonRef->pokemon[i];
PokemonStruct1 *pokemon = &gRecruitedPokemonRef->pokemon[i];
if (PokemonFlag1(pokemon)) {
if (pokemon->unk0 & FLAG_ON_TEAM)
@ -591,6 +561,7 @@ s32 SaveRecruitedPokemon(u8 *a1, s32 a2)
// Team members
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
u8 data_u8;
if (PokemonFlag1(&gRecruitedPokemonRef->team[i]))
data_u8 = 0xFF;
else
@ -824,538 +795,3 @@ void WriteHiddenPowerBits(DataSerializer* a1, HiddenPower* a2)
WriteBits(a1, &a2->hiddenPowerBasePower, 10);
WriteBits(a1, &a2->hiddenPowerType, 5);
}
// File Boundary here
void sub_808F468(struct PokemonStruct1 *pokemon,struct EvolveStatus *evolveStatus,bool8 param_3)
{
struct FriendAreaCapacity friendAreaCapacity;
struct unkEvolve evolveConditions;
s32 index;
evolveStatus->evolutionConditionStatus = 0;
for (index = MONSTER_BULBASAUR; index < MONSTER_MAX; index++) {
s32 speciesId = (s16) index;
if (speciesId == MONSTER_ALAKAZAM) {
GetPokemonEvolveConditions(MONSTER_ALAKAZAM,&evolveConditions);
}
else {
GetPokemonEvolveConditions(speciesId,&evolveConditions);
}
if (evolveConditions.preEvolution.evolveType != 0 && pokemon->speciesNum == evolveConditions.preEvolution.evolveFrom)
break;
};
if (index == MONSTER_MAX) {
evolveStatus->evolutionConditionStatus = EVOLUTION_NO_MORE;
return;
}
for (index = MONSTER_BULBASAUR; index < MONSTER_MAX; index++) {
u8 evolvedMonFriendArea, monFriendArea;
bool8 cannotEvolve = FALSE;
s32 speciesId = (s16) (index);
GetPokemonEvolveConditions(speciesId, &evolveConditions);
if (evolveConditions.preEvolution.evolveType == 0 || pokemon->speciesNum != evolveConditions.preEvolution.evolveFrom)
continue;
evolvedMonFriendArea = GetFriendArea(speciesId);
monFriendArea = GetFriendArea(pokemon->speciesNum);
GetFriendAreaCapacity2(evolvedMonFriendArea,&friendAreaCapacity,0,0);
if (!friendAreaCapacity.hasFriendArea) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_FRIEND_AREA;
cannotEvolve = TRUE;
}
else {
s32 currMonsNo = friendAreaCapacity.currNoPokemon;
if (evolvedMonFriendArea == monFriendArea) {
currMonsNo--;
}
if (friendAreaCapacity.maxPokemon <= currMonsNo) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ROOM;
cannotEvolve = TRUE;
}
}
if (evolveConditions.preEvolution.evolveType == EVOLVE_TYPE_LEVEL) {
if (evolveStatus->evolutionConditionStatus & 1)
continue;
if (pokemon->level < evolveConditions.evolutionRequirements.mainRequirement) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_LEVEL;
cannotEvolve = TRUE;
}
}
else if (evolveConditions.preEvolution.evolveType == EVOLVE_TYPE_IQ) {
if (pokemon->IQ < evolveConditions.evolutionRequirements.mainRequirement) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_IQ;
cannotEvolve = TRUE;
}
}
else if (evolveConditions.preEvolution.evolveType == EVOLVE_TYPE_ITEM) {
if (param_3) {
if ((evolveStatus->evoItem1 != evolveConditions.evolutionRequirements.mainRequirement) &&
(evolveStatus->evoItem2 != evolveConditions.evolutionRequirements.mainRequirement))
{
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (FindItemInInventory(evolveConditions.evolutionRequirements.mainRequirement) < 0) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
if (evolveConditions.evolutionRequirements.additionalRequirement == 4) {
if (param_3) {
if ((evolveStatus->evoItem1 != ITEM_LINK_CABLE) && (evolveStatus->evoItem2 != ITEM_LINK_CABLE)) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (FindItemInInventory(ITEM_LINK_CABLE) < 0) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 5) {
if (pokemon->offense.att[0] <= pokemon->offense.def[0]) {
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 6) {
if (pokemon->offense.att[0] >= pokemon->offense.def[0]) {
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 7) {
if (pokemon->offense.att[0] != pokemon->offense.def[0]) {
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 8) {
if (param_3) {
if ((evolveStatus->evoItem1 != ITEM_SUN_RIBBON) && (evolveStatus->evoItem2 != ITEM_SUN_RIBBON)) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (FindItemInInventory(ITEM_SUN_RIBBON) < 0) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 9) {
if (param_3) {
if ((evolveStatus->evoItem1 != ITEM_LUNAR_RIBBON) && (evolveStatus->evoItem2 != ITEM_LUNAR_RIBBON)) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (FindItemInInventory(ITEM_LUNAR_RIBBON) < 0) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 0xb) {
if ((evolveStatus->wurmpleVal & 1)) {
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 0xc) {
if (!(evolveStatus->wurmpleVal & 1)) {
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 10) {
if (param_3 != 0) {
if ((evolveStatus->evoItem1 != ITEM_BEAUTY_SCARF) && (evolveStatus->evoItem2 != ITEM_BEAUTY_SCARF)) {
cannotEvolve = TRUE;
}
}
else {
if (FindItemInInventory(ITEM_BEAUTY_SCARF) < 0) {
cannotEvolve = TRUE;
}
}
}
if (!cannotEvolve) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_GOOD;
evolveStatus->targetEvolveSpecies = speciesId;
}
}
}
s32 sub_808F700(PokemonStruct1 *pokemon)
{
EvolveStatus evolveStatus;
sub_808F468(pokemon, &evolveStatus, 0);
if ((evolveStatus.evolutionConditionStatus & EVOLUTION_GOOD)) {
return 1;
}
else if ((evolveStatus.evolutionConditionStatus & EVOLUTION_NO_MORE)) {
return 2;
}
else {
return 0;
}
}
PokemonStruct1 *sub_808F734(PokemonStruct1 *pokemon, s16 _species)
{
PokemonStruct1 *uVar1;
PokemonStruct1 *iVar3;
PokemonStruct1 pokeStruct;
s32 species = _species;
iVar3 = NULL;
pokeStruct = *pokemon;
uVar1 = sub_808F798(pokemon, species);
if (species == MONSTER_NINJASK) {
pokeStruct.isTeamLeader = FALSE;
pokeStruct.heldItem.id = ITEM_NOTHING;
BoundedCopyStringtoBuffer(pokeStruct.name, GetMonSpecies(MONSTER_SHEDINJA),POKEMON_NAME_LENGTH);
iVar3 = sub_808F798(&pokeStruct,MONSTER_SHEDINJA);
}
if (iVar3 != NULL) {
IncrementAdventureNumJoined();
}
return uVar1;
}
PokemonStruct1 *sub_808F798(PokemonStruct1 *pokemon, short _species)
{
s32 r6;
s32 index;
PokemonStruct1 pokeStruct;
LevelData levelData;
u8 buffer [64];
s32 species = _species;
bool32 flag = TRUE;
pokeStruct = *pokemon;
r6 = pokeStruct.speciesNum;
GetPokemonLevelData(&levelData,species,pokeStruct.level);
pokeStruct.currExp = levelData.expRequired;
pokemon->unk0 = 0;
pokeStruct.speciesNum = species;
if (pokeStruct.unkC[0].level == 0) {
pokeStruct.unkC[0].level = pokeStruct.level;
}
else if (pokeStruct.unkC[1].level == 0) {
pokeStruct.unkC[1].level = pokeStruct.level;
}
CopyStringtoBuffer(buffer, GetMonSpecies(r6));
index = 0;
goto _start;
do
{
index++;
_start:
if (index >= POKEMON_NAME_LENGTH) break;
if (buffer[index] != pokeStruct.name[index]) goto _end;
if (buffer[index] == 0) break;
} while(TRUE);
if (flag)
BoundedCopyStringtoBuffer(pokeStruct.name, GetMonSpecies(species), POKEMON_NAME_LENGTH);
_end:
return sub_808D1DC(&pokeStruct);
}
UNUSED void sub_808F83C(PokemonStruct1 *pokemon, s16 species, u8 *r2)
{
*r2 = 0;
}
void CreatePokemonInfoTabScreen(s32 param_1, s32 param_2, struct unkStruct_808FF20 *mon, struct UnkInfoTabStruct *param_4, u32 windowId)
{
s32 i, y;
s32 j;
sub_80073B8(windowId);
strncpy(gFormatBuffer_Monsters[0],mon->nameBuffer,0x14);
y = 0x20;
switch (param_1) {
case 0:
break;
case 2: {
const u8 *str;
s32 iVar8;
LevelData levelData;
PrintFormattedStringOnWindow(param_2 * 8 + 0x10,0,gUnknown_8107754,windowId,'\0');
gFormatArgs[0] = mon->level;
gFormatArgs[1] = mon->exp;
PrintFormattedStringOnWindow(4,y,gText_LevelUnkMacro,windowId,'\0');
y += 0xA;
PrintFormattedStringOnWindow(4,y,gText_ExpPtsUnkMacro,windowId,'\0');
y += 0xA;
if (mon->level < 100) {
GetPokemonLevelData(&levelData,mon->species,mon->level + 1);
gFormatArgs[0] = levelData.expRequired - mon->exp;
PrintFormattedStringOnWindow(4,y,gText_ToNextLevel,windowId,'\0');
}
y += 0xC;
gFormatArgs[0] = mon->HP1;
gFormatArgs[1] = mon->HP2;
PrintFormattedStringOnWindow(4,y,gUnknown_810DDD0,windowId,'\0');
y += 0xA;
PrintFormattedStringOnWindow(4,y,gUnknown_810DDE4,windowId,'\0');
str = gUnknown_810DE0C;
gFormatArgs[0] = mon->offense.att[0];
if (mon->atkBoost != 0) {
gFormatArgs[0] = gFormatArgs[0] + mon->atkBoost;
str = gUnknown_810DE20;
}
PrintFormattedStringOnWindow(4,y,str,windowId,'\0');
if (mon->defBoost != 0) {
gFormatArgs[0] = mon->offense.def[0] + mon->defBoost;
PrintFormattedStringOnWindow(4,y,gUnknown_810DE4C,windowId,'\0');
}
else {
gFormatArgs[0] = mon->offense.def[0];
PrintFormattedStringOnWindow(4,y,gUnknown_810DE38,windowId,'\0');
}
y += 0xA;
PrintFormattedStringOnWindow(4,y,gUnknown_810DDFC,windowId,'\0');
str = gUnknown_810DE24;
gFormatArgs[0] = mon->offense.att[1];
if (mon->spAtkBoost != 0) {
gFormatArgs[0] = gFormatArgs[0] + mon->spAtkBoost;
str = gUnknown_810DE28;
}
PrintFormattedStringOnWindow(4,y,str,windowId,'\0');
if (mon->spDefBoost != 0) {
gFormatArgs[0] = mon->offense.def[1] + mon->spDefBoost;
PrintFormattedStringOnWindow(4,y,gUnknown_810DE54,windowId,'\0');
}
else {
gFormatArgs[0] = mon->offense.def[1];
PrintFormattedStringOnWindow(4,y,gUnknown_810DE50,windowId,'\0');
}
y += 0xA;
if (ItemExists(&mon->item)) {
sub_8090E14(gFormatBuffer_Items[0],&mon->item,0);
}
else {
strcpy(gFormatBuffer_Items[0],gUnknown_810DE58);
}
PrintFormattedStringOnWindow(4,y,gUnknown_810DE6C,windowId,'\0');
y += 0xC;
gFormatArgs[0] = mon->IQ;
iVar8 = mon->IQ / 10;
if (iVar8 < 0) {
iVar8 = 0;
}
if (0x62 < iVar8) {
iVar8 = 99;
}
InlineStrcpy(gFormatBuffer_Monsters[0],gUnknown_8115718[iVar8]);
PrintFormattedStringOnWindow(4,y,gUnknown_810DE80,windowId,'\0');
y += 0xA;
if (!mon->isTeamLeader)
{
CopyTacticsNameToBuffer(gFormatBuffer_Monsters[0],mon->tactic);
PrintFormattedStringOnWindow(4,y,gUnknown_810DE98,windowId,'\0');
}
y += 0xA;
break;
}
case 3: {
PrintFormattedStringOnWindow(param_2 * 8 + 0x10,0,gUnknown_810775C,windowId,'\0');
PrintFormattedStringOnWindow(4,y,gUnknown_8107768,windowId,'\0');
PrintFormattedStringOnWindow(0x38,y,GetFormattedTypeString(mon->types[0]),windowId,'\0');
if (mon->types[1] != TYPE_NONE) {
PrintFormattedStringOnWindow(0x60,y,GetFormattedTypeString(mon->types[1]),windowId,'\0');
}
y += 0xC;
PrintFormattedStringOnWindow(4,y,gUnknown_8107770,windowId,'\0');
y += 0xC;
PrintFormattedStringOnWindow2(4,y,GetAbilityDescription(mon->abilities[0]),windowId,'\0',0xb);
y += 0x21;
if (mon->abilities[1] != ABILITY_UNKNOWN) {
PrintFormattedStringOnWindow2(4,y,GetAbilityDescription(mon->abilities[1]),windowId,'\0',0xb);
}
break;
}
case 1: {
s32 iVar11;
bool8 bVar10;
PrintFormattedStringOnWindow(param_2 * 8 + 0x10,0,gUnknown_810DD58,windowId,'\0');
iVar11 = mon->unk56 - 1;
y -= 0xC;
bVar10 = FALSE;
for (i = 0; i < 9; i++) {
param_4->unkC[i] = 0;
}
for (j = 0; j < 10; j++, iVar11++, y += 0xC) {
if (-1 < iVar11) {
if (0xb < iVar11)
break;
if (mon->unk58[iVar11] != 0) {
bVar10 = TRUE;
InlineStrncpy(gFormatBuffer_Items[1],gStatusNames[mon->unk58[iVar11]],0x50);
PrintFormattedStringOnWindow(0xc,y,gUnknown_8107784,windowId,'\0');
if (0 < j) {
param_4->unkC[j - 1] = mon->unk58[iVar11];
}
}
}
}
if (!bVar10) {
PrintFormattedStringOnWindow(0xc,0x20,gUnknown_810DF78,windowId,'\0');
}
break;
}
case 4: {
s32 iVar13;
bool8 bVar11;
u8 iqSkillBuffer[24];
PrintFormattedStringOnWindow(param_2 * 8 + 0x10,0,gText_IqSkills,windowId,'\0');
GetNumAvailableIQSkills(iqSkillBuffer,mon->IQ);
iVar13 = mon->unk40 - 1;
for (i = 0; i < 9; i++) {
param_4->unk0[i] = 0;
}
y -= 0xC;
bVar11 = FALSE;
for(j = 0; j < 10; j++, iVar13++, y += 0xC) {
if (-1 < iVar13) {
if (0x17 < iVar13)
break;
if (iqSkillBuffer[iVar13] != 0) {
const u8 *iqSkillName;
bVar11 = TRUE;
iqSkillName = GetIQSkillName(iqSkillBuffer[iVar13]);
strncpy(gFormatBuffer_Items[1],iqSkillName,0x50);
if (IsIQSkillSet(&mon->IQSkills,1 << iqSkillBuffer[iVar13])) {
strcpy(gFormatBuffer_Items[0],gUnknown_8107788);
}
else {
strcpy(gFormatBuffer_Items[0],gUnknown_810778C);
}
if (j >= 1) {
param_4->unk0[j - 1] = iqSkillBuffer[iVar13];
}
PrintFormattedStringOnWindow(0xc,y,gUnknown_8107790,windowId,'\0');
}
}
}
if (!bVar11) {
PrintFormattedStringOnWindow(0xc,0x20,gUnknown_810DF84,windowId,'\0');
}
break;
}
case 5: {
PrintFormattedStringOnWindow(param_2 * 8 + 0x10,0,gUnknown_8107798,windowId,'\0');
CopyMonsterNameToBuffer(gFormatBuffer_Monsters[0],mon->species);
gFormatArgs[0] = mon->species;
PrintFormattedStringOnWindow(4,y,gUnknown_810DEB4,windowId,'\0');
y += 0xA;
InlineStrncpy(gFormatBuffer_Items[0],GetFriendAreaName(GetFriendArea(mon->species)),0x50);
PrintFormattedStringOnWindow(4,y,gUnknown_810DEC8,windowId,'\0');
y += 0xA;
PrintFormattedStringOnWindow(4,y,gUnknown_810DEDC,windowId,'\0');
y += 0xD;
PrintFormattedStringOnWindow(4,y,gUnknown_810DFB4,windowId,'\0');
y += 0xA;
PrintYellowDungeonNametoBuffer(gFormatBuffer_Items[0],&mon->dungeonLocation);
PrintFormattedStringOnWindow(4,y,gUnknown_810DFC8,windowId,'\0');
y += 0xD;
strncpy(gFormatBuffer_Monsters[0],GetCategoryString(mon->species),0x14);
PrintFormattedStringOnWindow(4,y,gUnknown_810DEF4,windowId,'\0');
y += 0xD;
strcpy(gFormatBuffer_Monsters[0],gUnknown_810E02C[GetBodySize(mon->species)]);
PrintFormattedStringOnWindow(4,y,gUnknown_810DF98,windowId,'\0');
y += 0xD;
PrintFormattedStringOnWindow(4,y,gEvolutionStrings[mon->unk4C],windowId,'\0');
break;
}
}
sub_80073E0(windowId);
}
void sub_808FF20(struct unkStruct_808FF20 *param_1, struct PokemonStruct1 *pokemon, bool8 param_3)
{
s32 index;
PrintColoredPokeNameToBuffer(param_1->nameBuffer, pokemon, COLOR_WHITE);
param_1->species = pokemon->speciesNum;
param_1->HP1 = pokemon->pokeHP;
param_1->HP2 = pokemon->pokeHP;
param_1->level = pokemon->level;
param_1->exp = pokemon->currExp;
for(index = 0; index < 2; index++)
{
param_1->offense.att[index] = pokemon->offense.att[index];
param_1->offense.def[index] = pokemon->offense.def[index];
param_1->types[index] = GetPokemonType(pokemon->speciesNum,index);
param_1->abilities[index] = GetPokemonAbility(pokemon->speciesNum,index);
}
param_1->isTeamLeader = pokemon->isTeamLeader;
param_1->atkBoost = 0;
param_1->spAtkBoost = 0;
param_1->defBoost = 0;
param_1->spDefBoost = 0;
if (pokemon->heldItem.id != 0) {
if (pokemon->heldItem.id == ITEM_POWER_BAND) {
param_1->atkBoost += gUnknown_810AC60;
}
if (pokemon->heldItem.id == ITEM_SPECIAL_BAND) {
param_1->spAtkBoost+= gUnknown_810AC62;
}
if (pokemon->heldItem.id == ITEM_MUNCH_BELT) {
param_1->atkBoost += gUnknown_810AC68;
}
if (pokemon->heldItem.id == ITEM_MUNCH_BELT) {
param_1->spAtkBoost+= gUnknown_810AC68;
}
if (pokemon->heldItem.id == ITEM_DEF_SCARF) {
param_1->defBoost += gUnknown_810AC64;
}
if (pokemon->heldItem.id == ITEM_ZINC_BAND) {
param_1->spDefBoost += gUnknown_810AC66;
}
}
param_1->tactic = pokemon->tacticIndex;
HeldItemToSlot(&param_1->item,&pokemon->heldItem);
param_1->IQ = pokemon->IQ;
param_1->dungeonLocation = pokemon->dungeonLocation;
param_1->unk44[0] = pokemon->unkC[0];
param_1->unk44[1] = pokemon->unkC[1];
param_1->IQSkills = pokemon->IQSkills;
if (param_3) {
param_1->unk4C = sub_808F700(pokemon);
}
else {
param_1->unk4C = 3;
}
for(index = 0; index < 0xC; index++)
{
param_1->unk58[index] = 0;
}
}

254
src/pokemon_evolution.c Normal file
View File

@ -0,0 +1,254 @@
#include "global.h"
#include "globaldata.h"
#include "pokemon_evolution.h"
#include "pokemon.h"
#include "pokemon_3.h"
#include "text_util.h"
#include "friend_area.h"
#include "code_8097670.h"
#include "constants/evolve_type.h"
#include "constants/evolution_status.h"
void sub_808F468(PokemonStruct1 *pokemon, EvolveStatus *evolveStatus,bool8 param_3)
{
struct FriendAreaCapacity friendAreaCapacity;
struct unkEvolve evolveConditions;
s32 index;
evolveStatus->evolutionConditionStatus = 0;
for (index = MONSTER_BULBASAUR; index < MONSTER_MAX; index++) {
s32 speciesId = (s16) index;
if (speciesId == MONSTER_ALAKAZAM) {
GetPokemonEvolveConditions(MONSTER_ALAKAZAM,&evolveConditions);
}
else {
GetPokemonEvolveConditions(speciesId,&evolveConditions);
}
if (evolveConditions.preEvolution.evolveType != 0 && pokemon->speciesNum == evolveConditions.preEvolution.evolveFrom)
break;
};
if (index == MONSTER_MAX) {
evolveStatus->evolutionConditionStatus = EVOLUTION_NO_MORE;
return;
}
for (index = MONSTER_BULBASAUR; index < MONSTER_MAX; index++) {
u8 evolvedMonFriendArea, monFriendArea;
bool8 cannotEvolve = FALSE;
s32 speciesId = (s16) (index);
GetPokemonEvolveConditions(speciesId, &evolveConditions);
if (evolveConditions.preEvolution.evolveType == 0 || pokemon->speciesNum != evolveConditions.preEvolution.evolveFrom)
continue;
evolvedMonFriendArea = GetFriendArea(speciesId);
monFriendArea = GetFriendArea(pokemon->speciesNum);
GetFriendAreaCapacity2(evolvedMonFriendArea,&friendAreaCapacity,0,0);
if (!friendAreaCapacity.hasFriendArea) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_FRIEND_AREA;
cannotEvolve = TRUE;
}
else {
s32 currMonsNo = friendAreaCapacity.currNoPokemon;
if (evolvedMonFriendArea == monFriendArea) {
currMonsNo--;
}
if (friendAreaCapacity.maxPokemon <= currMonsNo) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ROOM;
cannotEvolve = TRUE;
}
}
if (evolveConditions.preEvolution.evolveType == EVOLVE_TYPE_LEVEL) {
if (evolveStatus->evolutionConditionStatus & 1)
continue;
if (pokemon->level < evolveConditions.evolutionRequirements.mainRequirement) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_LEVEL;
cannotEvolve = TRUE;
}
}
else if (evolveConditions.preEvolution.evolveType == EVOLVE_TYPE_IQ) {
if (pokemon->IQ < evolveConditions.evolutionRequirements.mainRequirement) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_IQ;
cannotEvolve = TRUE;
}
}
else if (evolveConditions.preEvolution.evolveType == EVOLVE_TYPE_ITEM) {
if (param_3) {
if ((evolveStatus->evoItem1 != evolveConditions.evolutionRequirements.mainRequirement) &&
(evolveStatus->evoItem2 != evolveConditions.evolutionRequirements.mainRequirement))
{
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (FindItemInInventory(evolveConditions.evolutionRequirements.mainRequirement) < 0) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
if (evolveConditions.evolutionRequirements.additionalRequirement == 4) {
if (param_3) {
if ((evolveStatus->evoItem1 != ITEM_LINK_CABLE) && (evolveStatus->evoItem2 != ITEM_LINK_CABLE)) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (FindItemInInventory(ITEM_LINK_CABLE) < 0) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 5) {
if (pokemon->offense.att[0] <= pokemon->offense.def[0]) {
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 6) {
if (pokemon->offense.att[0] >= pokemon->offense.def[0]) {
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 7) {
if (pokemon->offense.att[0] != pokemon->offense.def[0]) {
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 8) {
if (param_3) {
if ((evolveStatus->evoItem1 != ITEM_SUN_RIBBON) && (evolveStatus->evoItem2 != ITEM_SUN_RIBBON)) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (FindItemInInventory(ITEM_SUN_RIBBON) < 0) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 9) {
if (param_3) {
if ((evolveStatus->evoItem1 != ITEM_LUNAR_RIBBON) && (evolveStatus->evoItem2 != ITEM_LUNAR_RIBBON)) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (FindItemInInventory(ITEM_LUNAR_RIBBON) < 0) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_LACK_ITEM;
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 0xb) {
if ((evolveStatus->wurmpleVal & 1)) {
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 0xc) {
if (!(evolveStatus->wurmpleVal & 1)) {
cannotEvolve = TRUE;
}
}
else if (evolveConditions.evolutionRequirements.additionalRequirement == 10) {
if (param_3 != 0) {
if ((evolveStatus->evoItem1 != ITEM_BEAUTY_SCARF) && (evolveStatus->evoItem2 != ITEM_BEAUTY_SCARF)) {
cannotEvolve = TRUE;
}
}
else {
if (FindItemInInventory(ITEM_BEAUTY_SCARF) < 0) {
cannotEvolve = TRUE;
}
}
}
if (!cannotEvolve) {
evolveStatus->evolutionConditionStatus |= EVOLUTION_GOOD;
evolveStatus->targetEvolveSpecies = speciesId;
}
}
}
s32 sub_808F700(PokemonStruct1 *pokemon)
{
EvolveStatus evolveStatus;
sub_808F468(pokemon, &evolveStatus, 0);
if ((evolveStatus.evolutionConditionStatus & EVOLUTION_GOOD)) {
return 1;
}
else if ((evolveStatus.evolutionConditionStatus & EVOLUTION_NO_MORE)) {
return 2;
}
else {
return 0;
}
}
PokemonStruct1 *sub_808F734(PokemonStruct1 *pokemon, s16 _species)
{
PokemonStruct1 *uVar1;
PokemonStruct1 *iVar3;
PokemonStruct1 pokeStruct;
s32 species = _species;
iVar3 = NULL;
pokeStruct = *pokemon;
uVar1 = sub_808F798(pokemon, species);
if (species == MONSTER_NINJASK) {
pokeStruct.isTeamLeader = FALSE;
pokeStruct.heldItem.id = ITEM_NOTHING;
BoundedCopyStringtoBuffer(pokeStruct.name, GetMonSpecies(MONSTER_SHEDINJA),POKEMON_NAME_LENGTH);
iVar3 = sub_808F798(&pokeStruct,MONSTER_SHEDINJA);
}
if (iVar3 != NULL) {
IncrementAdventureNumJoined();
}
return uVar1;
}
PokemonStruct1 *sub_808F798(PokemonStruct1 *pokemon, s16 _species)
{
s32 r6;
s32 i;
PokemonStruct1 pokeStruct;
LevelData levelData;
u8 buffer [64];
s32 species = _species;
bool8 copy;
pokeStruct = *pokemon;
r6 = pokeStruct.speciesNum;
GetPokemonLevelData(&levelData,species,pokeStruct.level);
pokeStruct.currExp = levelData.expRequired;
pokemon->unk0 = 0;
pokeStruct.speciesNum = species;
if (pokeStruct.unkC[0].level == 0) {
pokeStruct.unkC[0].level = pokeStruct.level;
}
else if (pokeStruct.unkC[1].level == 0) {
pokeStruct.unkC[1].level = pokeStruct.level;
}
CopyStringtoBuffer(buffer, GetMonSpecies(r6));
copy = TRUE;
for (i = 0; i < POKEMON_NAME_LENGTH; i++) {
if (buffer[i] != pokeStruct.name[i]) {
copy = FALSE;
break;
}
if (buffer[i] == '\0')
break;
}
if (copy)
BoundedCopyStringtoBuffer(pokeStruct.name, GetMonSpecies(species), POKEMON_NAME_LENGTH);
return sub_808D1DC(&pokeStruct);
}
UNUSED static void sub_808F83C(PokemonStruct1 *pokemon, s16 species, u8 *r2)
{
*r2 = 0;
}

View File

@ -0,0 +1,297 @@
#include "global.h"
#include "globaldata.h"
#include "pokemon_summary_window.h"
#include "string_format.h"
#include "strings.h"
#include "pokemon_3.h"
#include "pokemon_evolution.h"
#include "text_1.h"
#include "items.h"
#include "text_util.h"
#include "friend_area.h"
#include "dungeon.h"
#include "dungeon_data.h"
#include "constants/ability.h"
#include "constants/type.h"
#include "constants/colors.h"
void ShowPokemonSummaryWindow(s32 which, s32 currSubWindowId, struct MonSummaryInfo *monInfo, struct UnkInfoTabStruct *param_4, u32 windowId)
{
s32 i, y;
s32 j;
sub_80073B8(windowId);
strncpy(gFormatBuffer_Monsters[0],monInfo->nameBuffer,0x14);
y = 0x20;
switch (which) {
case SUB_WINDOW_NONE:
break;
case SUB_WINDOW_STATS: {
const u8 *str;
s32 iVar8;
LevelData levelData;
PrintFormattedStringOnWindow(currSubWindowId * 8 + 0x10,0,_("Stats"),windowId,'\0');
gFormatArgs[0] = monInfo->level;
gFormatArgs[1] = monInfo->exp;
PrintFormattedStringOnWindow(4,y,gText_LevelUnkMacro,windowId,'\0');
y += 0xA;
PrintFormattedStringOnWindow(4,y,gText_ExpPtsUnkMacro,windowId,'\0');
y += 0xA;
if (monInfo->level < 100) {
GetPokemonLevelData(&levelData,monInfo->species,monInfo->level + 1);
gFormatArgs[0] = levelData.expRequired - monInfo->exp;
PrintFormattedStringOnWindow(4,y,gText_ToNextLevel,windowId,'\0');
}
y += 0xC;
gFormatArgs[0] = monInfo->HP1;
gFormatArgs[1] = monInfo->HP2;
PrintFormattedStringOnWindow(4,y,gUnknown_810DDD0,windowId,'\0');
y += 0xA;
PrintFormattedStringOnWindow(4,y,gUnknown_810DDE4,windowId,'\0');
str = gUnknown_810DE0C;
gFormatArgs[0] = monInfo->offense.att[0];
if (monInfo->atkBoost != 0) {
gFormatArgs[0] = gFormatArgs[0] + monInfo->atkBoost;
str = gUnknown_810DE20;
}
PrintFormattedStringOnWindow(4,y,str,windowId,'\0');
if (monInfo->defBoost != 0) {
gFormatArgs[0] = monInfo->offense.def[0] + monInfo->defBoost;
PrintFormattedStringOnWindow(4,y,gUnknown_810DE4C,windowId,'\0');
}
else {
gFormatArgs[0] = monInfo->offense.def[0];
PrintFormattedStringOnWindow(4,y,gUnknown_810DE38,windowId,'\0');
}
y += 0xA;
PrintFormattedStringOnWindow(4,y,gUnknown_810DDFC,windowId,'\0');
str = gUnknown_810DE24;
gFormatArgs[0] = monInfo->offense.att[1];
if (monInfo->spAtkBoost != 0) {
gFormatArgs[0] = gFormatArgs[0] + monInfo->spAtkBoost;
str = gUnknown_810DE28;
}
PrintFormattedStringOnWindow(4,y,str,windowId,'\0');
if (monInfo->spDefBoost != 0) {
gFormatArgs[0] = monInfo->offense.def[1] + monInfo->spDefBoost;
PrintFormattedStringOnWindow(4,y,gUnknown_810DE54,windowId,'\0');
}
else {
gFormatArgs[0] = monInfo->offense.def[1];
PrintFormattedStringOnWindow(4,y,gUnknown_810DE50,windowId,'\0');
}
y += 0xA;
if (ItemExists(&monInfo->item)) {
sub_8090E14(gFormatBuffer_Items[0],&monInfo->item,0);
}
else {
strcpy(gFormatBuffer_Items[0],gUnknown_810DE58);
}
PrintFormattedStringOnWindow(4,y,gUnknown_810DE6C,windowId,'\0');
y += 0xC;
gFormatArgs[0] = monInfo->IQ;
iVar8 = monInfo->IQ / 10;
if (iVar8 < 0) {
iVar8 = 0;
}
if (0x62 < iVar8) {
iVar8 = 99;
}
InlineStrcpy(gFormatBuffer_Monsters[0],gUnknown_8115718[iVar8]);
PrintFormattedStringOnWindow(4,y,gUnknown_810DE80,windowId,'\0');
y += 0xA;
if (!monInfo->isTeamLeader)
{
CopyTacticsNameToBuffer(gFormatBuffer_Monsters[0],monInfo->tactic);
PrintFormattedStringOnWindow(4,y,gUnknown_810DE98,windowId,'\0');
}
y += 0xA;
break;
}
case SUB_WINDOW_FEATUERS: {
PrintFormattedStringOnWindow(currSubWindowId * 8 + 0x10,0,_("Features"),windowId,'\0');
PrintFormattedStringOnWindow(4,y,_("Type:"),windowId,'\0');
PrintFormattedStringOnWindow(0x38,y,GetFormattedTypeString(monInfo->types[0]),windowId,'\0');
if (monInfo->types[1] != TYPE_NONE) {
PrintFormattedStringOnWindow(0x60,y,GetFormattedTypeString(monInfo->types[1]),windowId,'\0');
}
y += 0xC;
PrintFormattedStringOnWindow(4,y,_("Special Abilities:"),windowId,'\0');
y += 0xC;
PrintFormattedStringOnWindow2(4,y,GetAbilityDescription(monInfo->abilities[0]),windowId,'\0',0xb);
y += 0x21;
if (monInfo->abilities[1] != ABILITY_UNKNOWN) {
PrintFormattedStringOnWindow2(4,y,GetAbilityDescription(monInfo->abilities[1]),windowId,'\0',0xb);
}
break;
}
case SUB_WINDOW_STATUS: {
s32 iVar11;
bool8 bVar10;
PrintFormattedStringOnWindow(currSubWindowId * 8 + 0x10,0,gUnknown_810DD58,windowId,'\0');
iVar11 = monInfo->unk56 - 1;
y -= 0xC;
bVar10 = FALSE;
for (i = 0; i < 9; i++) {
param_4->unkC[i] = 0;
}
for (j = 0; j < 10; j++, iVar11++, y += 0xC) {
if (-1 < iVar11) {
if (0xb < iVar11)
break;
if (monInfo->unk58[iVar11] != 0) {
bVar10 = TRUE;
InlineStrncpy(gFormatBuffer_Items[1],gStatusNames[monInfo->unk58[iVar11]],0x50);
PrintFormattedStringOnWindow(0xc,y,_("{MOVE_ITEM_1}"),windowId,'\0');
if (0 < j) {
param_4->unkC[j - 1] = monInfo->unk58[iVar11];
}
}
}
}
if (!bVar10) {
PrintFormattedStringOnWindow(0xc,0x20,gUnknown_810DF78,windowId,'\0');
}
break;
}
case SUB_WINDOW_IQ: {
s32 iVar13;
bool8 bVar11;
u8 iqSkillBuffer[24];
PrintFormattedStringOnWindow(currSubWindowId * 8 + 0x10,0,gText_IqSkills,windowId,'\0');
GetNumAvailableIQSkills(iqSkillBuffer,monInfo->IQ);
iVar13 = monInfo->unk40 - 1;
for (i = 0; i < 9; i++) {
param_4->unk0[i] = 0;
}
y -= 0xC;
bVar11 = FALSE;
for(j = 0; j < 10; j++, iVar13++, y += 0xC) {
if (-1 < iVar13) {
if (0x17 < iVar13)
break;
if (iqSkillBuffer[iVar13] != 0) {
const u8 *iqSkillName;
bVar11 = TRUE;
iqSkillName = GetIQSkillName(iqSkillBuffer[iVar13]);
strncpy(gFormatBuffer_Items[1],iqSkillName,0x50);
if (IsIQSkillSet(&monInfo->IQSkills,1 << iqSkillBuffer[iVar13])) {
InlineStrcpy(gFormatBuffer_Items[0],_("{STAR_BULLET}"));
}
else {
InlineStrcpy(gFormatBuffer_Items[0],_("{ICON_BLANK}"));
}
if (j >= 1) {
param_4->unk0[j - 1] = iqSkillBuffer[iVar13];
}
PrintFormattedStringOnWindow(0xc,y,_("{MOVE_ITEM_0}{MOVE_ITEM_1}"),windowId,'\0');
}
}
}
if (!bVar11) {
PrintFormattedStringOnWindow(0xc,0x20,gUnknown_810DF84,windowId,'\0');
}
break;
}
case SUB_WINDOW_INFO: {
PrintFormattedStringOnWindow(currSubWindowId * 8 + 0x10,0,_("Info"),windowId,'\0');
CopyMonsterNameToBuffer(gFormatBuffer_Monsters[0],monInfo->species);
gFormatArgs[0] = monInfo->species;
PrintFormattedStringOnWindow(4,y,gUnknown_810DEB4,windowId,'\0');
y += 0xA;
InlineStrncpy(gFormatBuffer_Items[0],GetFriendAreaName(GetFriendArea(monInfo->species)),0x50);
PrintFormattedStringOnWindow(4,y,gUnknown_810DEC8,windowId,'\0');
y += 0xA;
PrintFormattedStringOnWindow(4,y,gUnknown_810DEDC,windowId,'\0');
y += 0xD;
PrintFormattedStringOnWindow(4,y,gUnknown_810DFB4,windowId,'\0');
y += 0xA;
PrintYellowDungeonNametoBuffer(gFormatBuffer_Items[0],&monInfo->dungeonLocation);
PrintFormattedStringOnWindow(4,y,gUnknown_810DFC8,windowId,'\0');
y += 0xD;
strncpy(gFormatBuffer_Monsters[0],GetCategoryString(monInfo->species),0x14);
PrintFormattedStringOnWindow(4,y,gUnknown_810DEF4,windowId,'\0');
y += 0xD;
strcpy(gFormatBuffer_Monsters[0],gUnknown_810E02C[GetBodySize(monInfo->species)]);
PrintFormattedStringOnWindow(4,y,gUnknown_810DF98,windowId,'\0');
y += 0xD;
PrintFormattedStringOnWindow(4,y,gEvolutionStrings[monInfo->unk4C],windowId,'\0');
break;
}
}
sub_80073E0(windowId);
}
void SetMonSummaryInfo(struct MonSummaryInfo *dst, struct PokemonStruct1 *pokemon, bool8 param_3)
{
s32 index;
PrintColoredPokeNameToBuffer(dst->nameBuffer, pokemon, COLOR_WHITE);
dst->species = pokemon->speciesNum;
dst->HP1 = pokemon->pokeHP;
dst->HP2 = pokemon->pokeHP;
dst->level = pokemon->level;
dst->exp = pokemon->currExp;
for(index = 0; index < 2; index++)
{
dst->offense.att[index] = pokemon->offense.att[index];
dst->offense.def[index] = pokemon->offense.def[index];
dst->types[index] = GetPokemonType(pokemon->speciesNum,index);
dst->abilities[index] = GetPokemonAbility(pokemon->speciesNum,index);
}
dst->isTeamLeader = pokemon->isTeamLeader;
dst->atkBoost = 0;
dst->spAtkBoost = 0;
dst->defBoost = 0;
dst->spDefBoost = 0;
if (pokemon->heldItem.id != 0) {
if (pokemon->heldItem.id == ITEM_POWER_BAND) {
dst->atkBoost += gUnknown_810AC60;
}
if (pokemon->heldItem.id == ITEM_SPECIAL_BAND) {
dst->spAtkBoost+= gUnknown_810AC62;
}
if (pokemon->heldItem.id == ITEM_MUNCH_BELT) {
dst->atkBoost += gUnknown_810AC68;
}
if (pokemon->heldItem.id == ITEM_MUNCH_BELT) {
dst->spAtkBoost+= gUnknown_810AC68;
}
if (pokemon->heldItem.id == ITEM_DEF_SCARF) {
dst->defBoost += gUnknown_810AC64;
}
if (pokemon->heldItem.id == ITEM_ZINC_BAND) {
dst->spDefBoost += gUnknown_810AC66;
}
}
dst->tactic = pokemon->tacticIndex;
HeldItemToSlot(&dst->item,&pokemon->heldItem);
dst->IQ = pokemon->IQ;
dst->dungeonLocation = pokemon->dungeonLocation;
dst->unk44[0] = pokemon->unkC[0];
dst->unk44[1] = pokemon->unkC[1];
dst->IQSkills = pokemon->IQSkills;
if (param_3) {
dst->unk4C = sub_808F700(pokemon);
}
else {
dst->unk4C = 3;
}
for(index = 0; index < 0xC; index++)
{
dst->unk58[index] = 0;
}
}