pmd-red/src/code_8069E0C.c
2025-02-06 08:10:51 -08:00

2300 lines
67 KiB
C

#include "global.h"
#include "code_800F958.h"
#include "code_803E46C.h"
#include "code_803E668.h"
#include "code_8045A00.h"
#include "code_805D8C8.h"
#include "code_804267C.h"
#include "random.h"
#include "constants/ability.h"
#include "constants/move_id.h"
#include "constants/status.h"
#include "constants/type.h"
#include "constants/weather.h"
#include "dungeon_engine.h"
#include "dungeon_leader.h"
#include "dungeon_map_access.h"
#include "dungeon_movement.h"
#include "dungeon_pokemon_attributes.h"
#include "dungeon_random.h"
#include "dungeon_message.h"
#include "dungeon_util.h"
#include "game_options.h"
#include "move_effects_target.h"
#include "moves.h"
#include "pokemon.h"
#include "structs/dungeon_entity.h"
#include "structs/str_dungeon.h"
#include "text_util.h"
#include "weather.h"
#include "file_system.h"
#include "tile_types.h"
#include "position_util.h"
#include "exclusive_pokemon.h"
#include "number_util.h"
#include "pokemon_3.h"
#include "code_8077274_1.h"
#include "code_806CD90.h"
#include "dungeon_capabilities.h"
#include "status_checks_1.h"
#include "dungeon_ai_movement.h"
#include "constants/iq_skill.h"
#include "structs/str_806B7F8.h"
#include "structs/str_202ED28.h"
#include "dungeon_config.h"
extern u8 *gUnknown_80FCC7C[];
extern u8 *gUnknown_80FCCAC[];
extern u8 *gUnknown_80FDCC8[];
extern void sub_8042900(Entity *r0);
extern void sub_8042968(Entity *r0);
extern void EndAbilityImmuneStatus(Entity *, Entity *);
void sub_8041BBC(Entity *r0);
extern bool8 sub_8045888(Entity *);
extern void sub_806A2BC(Entity *, u8);
extern void sub_804178C(u32);
extern void sub_803F508(Entity *);
extern void sub_8042B20(Entity *entity);
extern void sub_8042B0C(Entity *entity);
extern s32 sub_803D808(UnkDungeonGlobal_unk1CD98 *strPtr, s32 id);
extern void sub_8072AC8(u16 *param_1, s32 species, s32 param_3);
extern s16 sub_803D970(u32);
extern bool8 sub_8083660(const DungeonPos *param_1);
extern Entity *gLeaderPointer;
extern DungeonPos gUnknown_202EE0C;
extern void sub_803F4A0(Entity *a0);
extern bool8 sub_80860A8(u8 id);
extern u8 gUnknown_202F32C;
extern u8 sub_803D73C(s32 a0);
extern void DeletePokemonDungeonSprite(s32 id);
extern void sub_80429E8(Entity *r0);
extern s32 sub_803DA20(s32 param_1);
extern void sub_80694C0(Entity *, s32, s32, u32);
extern s32 gUnknown_202EDCC;
extern void sub_800F958(s32 dungeonSpriteID, DungeonPos *pos, DungeonPos *statusOffsets, u32 a3);
extern void sub_8005700(DungeonPos *a0, struct axObject *a1);
u32 EntityGetStatusSprites(Entity *entity);
void UpdateDungeonPokemonSprite(int id, short species, int status, char visible);
extern void sub_8042EC8(Entity *a0, s32 a1);
void DoAxFrame_800558C(struct axObject *a0, s32 spriteX, s32 spriteY, u32 a3, u32 paletteNum, unkStruct_2039DB0 *spriteMasks);
extern Entity *sub_804550C(s16 a);
extern Entity *sub_80453AC(s16 id);
extern void sub_803F580(s32);
extern void sub_8040A84(void);
extern void sub_806B678(void);
extern void EntityUpdateStatusSprites(Entity *);
extern Entity *sub_80696A8(Entity *a0);
extern int sprintf(char *, const char *, ...);
extern const u8 gUnknown_8106EA8[]; // talkp%d
extern const u8 gUnknown_8106EB0[]; // talk%d
extern const struct FileArchive gDungeonFileArchive;
void sub_8069E0C(Entity *pokemon)
{
s32 index;
EntityInfo *entityInfo;
entityInfo = GetEntInfo(pokemon);
if (AbilityIsActive(pokemon, ABILITY_FORECAST)) {
entityInfo->types[0] = gCastformByWeather[GetApparentWeather(pokemon)].type;
entityInfo->types[1] = TYPE_NONE;
}
else {
for(index = 0; index < 2; index++)
entityInfo->types[index] = GetPokemonType(entityInfo->id, index);
}
for(index = 0; index < 2; index++)
entityInfo->abilities[index] = GetPokemonAbility(entityInfo->id, index);
gDungeon->unkC = 1;
}
void TriggerWeatherAbilities(void)
{
Entity *entity;
s32 index;
if (gDungeon->unkC != 0) {
gDungeon->unkC = 0;
gDungeon->weather.nullifyWeather = FALSE;
for(index = 0; index < DUNGEON_MAX_POKEMON; index++)
{
entity = gDungeon->activePokemon[index];
if (EntityIsValid(entity)) {
if (AbilityIsActive(entity, ABILITY_DRIZZLE)) {
gDungeon->weather.naturalWeather[WEATHER_RAIN] = 1;
}
else if (AbilityIsActive(entity, ABILITY_SAND_STREAM)) {
gDungeon->weather.naturalWeather[WEATHER_SANDSTORM] = 1;
}
else if (AbilityIsActive(entity, ABILITY_DROUGHT)) {
gDungeon->weather.naturalWeather[WEATHER_SUNNY] = 1;
}
if ((AbilityIsActive(entity, ABILITY_AIR_LOCK)) || (AbilityIsActive(entity, ABILITY_CLOUD_NINE))) {
gDungeon->weather.nullifyWeather = TRUE;
}
}
}
}
}
s32 GetMonsterApparentID(Entity *pokemon, s32 _id)
{
s16 id = (s16)(_id);
if (id == MONSTER_CASTFORM || IS_CASTFORM_FORM_MONSTER(id)) {
if (AbilityIsActive(pokemon, ABILITY_FORECAST))
return gCastformByWeather[GetApparentWeather(pokemon)].monsterId;
return MONSTER_CASTFORM;
}
return id;
}
void sub_8069F9C(Entity *pokemon, Entity *target, Move *move)
{
s32 abilityIndex;
EntityInfo *targetInfo;
EntityInfo *pokemonInfo;
u8 abilities[4];
if (!EntityIsValid(pokemon))
return;
if (!EntityIsValid(target))
return;
if (pokemon == target)
return;
pokemonInfo = GetEntInfo(pokemon);
targetInfo = GetEntInfo(target);
abilityIndex = -1;
if (targetInfo->abilities[0] == ABILITY_TRACE) {
abilityIndex = 0;
}
if (targetInfo->abilities[1] == ABILITY_TRACE) {
abilityIndex = 1;
}
if (abilityIndex > -1) {
s32 randomIndex;
s32 abilityCounter = 0;
if (pokemonInfo->abilities[0] != ABILITY_UNKNOWN) {
abilities[0] = pokemonInfo->abilities[0];
abilityCounter = 1;
}
if (pokemonInfo->abilities[1] != ABILITY_UNKNOWN) {
abilities[abilityCounter] = pokemonInfo->abilities[1];
abilityCounter++;
}
if (abilityCounter != 0) {
if (abilityCounter == 1) {
randomIndex = 0;
}
else {
randomIndex = DungeonRandInt(abilityCounter);
}
if (randomIndex >= 0) {
targetInfo->abilities[abilityIndex] = abilities[randomIndex];
gDungeon->unkC = 1;
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], target, 0);
TryDisplayDungeonLoggableMessage3(pokemon, target, *gUnknown_80FCC7C);
sub_8042900(target);
EndAbilityImmuneStatus(pokemon, target);
}
}
}
if (targetInfo->unk15A != 0) {
targetInfo->unk15A = 0;
if (AbilityIsActive(target, ABILITY_COLOR_CHANGE)) {
u8 type = GetMoveTypeForMonster(pokemon,move);
if (move->id == MOVE_WEATHER_BALL) {
u32 weather = GetApparentWeather(pokemon);
type = gWeatherBallTypes[weather];
}
if (type != TYPE_NONE && !MonsterIsType(target,type)) {
const u8 *str;
targetInfo->types[0] = type;
targetInfo->types[1] = TYPE_NONE;
targetInfo->isColorChanged = TRUE;
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], target, 0);
str = GetUnformattedTypeString(targetInfo->types[0]);
strcpy(gFormatBuffer_Items[0], str);
TryDisplayDungeonLoggableMessage3(pokemon,target,*gUnknown_80FCCAC);
sub_8042968(target);
}
}
}
}
void sub_806A120(Entity * pokemon, Entity * target, Move* move)
{
u32 uVar2_u32;
u8 moveType;
const char *typeString;
EntityInfo *entityInfo;
if ((((EntityIsValid(pokemon)) && (EntityIsValid(target))) && (pokemon != target))
&& (entityInfo = GetEntInfo(target), entityInfo->reflectClassStatus.status == STATUS_CONVERSION2)) {
moveType = GetMoveTypeForMonster(pokemon, move);
uVar2_u32 = sub_8092364(moveType);
if (uVar2_u32 != TYPE_NONE) {
entityInfo->types[0] = uVar2_u32;
entityInfo->types[1] = 0;
sub_8041BBC(target);
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],target,0);
typeString = GetUnformattedTypeString(uVar2_u32);
strcpy(gFormatBuffer_Items[0],typeString);
TryDisplayDungeonLoggableMessage3(pokemon,target,*gUnknown_80FDCC8);
}
}
}
void sub_806A1B0(Entity *pokemon)
{
if ((EntityIsValid(pokemon)) && (AbilityIsActive(pokemon, ABILITY_TRUANT))) {
PausedStatusTarget(pokemon,pokemon,0,1,0);
}
}
void sub_806A1E8(Entity *pokemon)
{
bool8 bVar3;
EntityInfo *entityInfo;
bVar3 = FALSE;
if (EntityIsValid(pokemon)) {
if (GetEntityType(pokemon) == ENTITY_MONSTER) {
entityInfo = GetEntInfo(pokemon);
bVar3 = (!entityInfo->isNotTeamMember);
}
if (gGameOptionsRef->FarOffPals == '\0') {
bVar3 = FALSE;
}
if (bVar3 && (!sub_8045888(pokemon))) {
sub_806A2BC(pokemon,1);
}
}
}
void sub_806A240(Entity *pokemon, Entity *target)
{
bool8 isNotTeamMember;
EntityInfo *entityInfo;
isNotTeamMember = FALSE;
if (EntityIsValid(pokemon)){
if (GetEntityType(pokemon) == ENTITY_MONSTER) {
entityInfo = GetEntInfo(pokemon);
isNotTeamMember = (!entityInfo->isNotTeamMember);
}
if (isNotTeamMember && (!sub_8045888(pokemon))) {
sub_806A2BC(pokemon,1);
return;
}
else if (GetEntityType(target) == ENTITY_MONSTER) {
entityInfo = GetEntInfo(target);
isNotTeamMember = (!entityInfo->isNotTeamMember);
}
if (isNotTeamMember && (!sub_8045888(target))) {
sub_806A2BC(target,1);
}
}
}
void sub_806A2BC(Entity *pokemon, u8 param_2)
{
if ((EntityIsValid(pokemon)) && (GetEntityType(pokemon) == ENTITY_MONSTER) && (gDungeon->unk181e8.cameraTarget != pokemon)) {
if (param_2 != '\0') {
sub_804178C(1);
while (gDungeon->unk12 < 0x3c) {
sub_803E46C(0x34);
}
}
sub_803E708(4,0x44);
sub_803F508(pokemon);
sub_804AC20(&pokemon->pos);
gDungeon->unk12 = 0;
}
}
void nullsub_95(void)
{}
void sub_806A338(void)
{
s32 i;
for (i = 0; i < DUNGEON_MAX_POKEMON; i++) {
Entity *entity = gDungeon->activePokemon[i];
if (EntityIsValid(entity) && (GetEntInfo(entity)->curseClassStatus.status == STATUS_SNATCH)) {
gDungeon->snatchPokemon = entity;
gDungeon->unk17B3C = GetEntInfo(entity)->unk98;
return;
}
}
}
void sub_806A390(Entity *pokemon)
{
s32 i;
EntityInfo *info = GetEntInfo(pokemon);
for (i = 0; i < MAX_MON_MOVES; i++) {
Move *move = &info->moves.moves[i];
if (MoveFlagExists(move)) {
move->moveFlags2 &= 0xF7;
move->moveFlags2 &= 0xEF;
move->moveFlags2 |= MOVE_FLAG2_UNK4;
move->PP = GetMoveBasePP(move);
}
}
}
struct UnkTalkFileStruct
{
const u8 *strings[10][4];
};
// https://decomp.me/scratch/beUzw s16 memes again
#ifdef NONMATCHING
void sub_806A3D4(u8 *dst, s16 a1, s32 id, bool8 a3)
{
u8 fileName[12];
OpenedFile *file;
s32 strId;
if (a3) {
sprintf(fileName, gUnknown_8106EA8, a1 / 10);
}
else {
sprintf(fileName, gUnknown_8106EB0, a1 / 10);
}
file = OpenFileAndGetFileDataPtr(fileName, &gDungeonFileArchive);
strId = a1 % 10;
strcpy(dst, ((struct UnkTalkFileStruct *)(file->data))->strings[strId][id]);
CloseFile(file);
}
#else
NAKED void sub_806A3D4(u8 *dst, s16 a1, s32 id, bool8 a3)
{
asm_unified("push {r4-r7,lr}\n"
" sub sp, 0xC\n"
" adds r7, r0, 0\n"
" adds r6, r2, 0\n"
" lsls r1, 16\n"
" asrs r5, r1, 16\n"
" lsls r3, 24\n"
" cmp r3, 0\n"
" beq _0806A404\n"
" ldr r4, _0806A400\n"
" adds r0, r5, 0\n"
" movs r1, 0xA\n"
" bl __divsi3\n"
" adds r2, r0, 0\n"
" lsls r2, 16\n"
" asrs r2, 16\n"
" mov r0, sp\n"
" adds r1, r4, 0\n"
" bl sprintf\n"
" b _0806A41C\n"
" .align 2, 0\n"
"_0806A400: .4byte gUnknown_8106EA8\n"
"_0806A404:\n"
" ldr r4, _0806A450\n"
" adds r0, r5, 0\n"
" movs r1, 0xA\n"
" bl __divsi3\n"
" adds r2, r0, 0\n"
" lsls r2, 16\n"
" asrs r2, 16\n"
" mov r0, sp\n"
" adds r1, r4, 0\n"
" bl sprintf\n"
"_0806A41C:\n"
" ldr r1, _0806A454\n"
" mov r0, sp\n"
" bl OpenFileAndGetFileDataPtr\n"
" adds r4, r0, 0\n"
" adds r0, r5, 0\n"
" movs r1, 0xA\n"
" bl __modsi3\n"
" lsls r0, 16\n"
" ldr r1, [r4, 0x4]\n"
" asrs r0, 12\n"
" adds r0, r1\n"
" lsls r1, r6, 2\n"
" adds r0, r1\n"
" ldr r1, [r0]\n"
" adds r0, r7, 0\n"
" bl strcpy\n"
" adds r0, r4, 0\n"
" bl CloseFile\n"
" add sp, 0xC\n"
" pop {r4-r7}\n"
" pop {r0}\n"
" bx r0\n"
" .align 2, 0\n"
"_0806A450: .4byte gUnknown_8106EB0\n"
"_0806A454: .4byte gDungeonFileArchive");
}
#endif // NONMATCHING
bool8 sub_806A458(Entity *pokemon)
{
s32 x, y;
s32 count = 0;
EntityInfo *info = GetEntInfo(pokemon);
bool8 isNotTeamMember = info->isNotTeamMember;
if (!sub_80696A8(pokemon))
return FALSE;
for (y = -1; y < 2; y++) {
for (x = -1; x < 2; x++) {
Tile *tile = GetTileMut(pokemon->pos.x + x, pokemon->pos.y + y);
if (tile->monster && GetEntityType(tile->monster) == ENTITY_MONSTER) {
if (GetEntInfo(tile->monster)->isNotTeamMember != isNotTeamMember)
count++;
}
}
}
return (count > 1);
}
s32 sub_806A4DC(EntityInfo *info)
{
PokemonStruct1 pokemon;
DungeonLocation loc;
loc.id = 0;
loc.floor = 1;
sub_808CFD0(&pokemon, info->id, NULL, 0, &loc, 0);
pokemon.speciesNum = info->id;
pokemon.level = info->level;
pokemon.IQ = info->IQ;
pokemon.offense.att[0] = info->atk[0];
pokemon.offense.def[0] = info->def[0];
return sub_808F700(&pokemon);
}
bool8 sub_806A538(s16 r0)
{
s32 r0_1 = Self_s16(r0);
if (r0 == 0x55AA)
return TRUE;
if (r0 == 0x5AA5)
return TRUE;
if (r0_1 >= 0)
return FALSE;
return TRUE;
}
bool8 sub_806A564(s16 r0)
{
if (r0 == 0x55AA)
return TRUE;
if (r0 == 0x5AA5)
return TRUE;
return FALSE;
}
bool8 sub_806A58C(s16 r0)
{
if (r0 >= 0 && r0 <= 0x19C)
return TRUE;
else
return FALSE;
}
bool8 sub_806A5A4(s16 r0)
{
if (r0 < 0)
return TRUE;
else
return FALSE;
}
extern const u8 *const gUnknown_80FD594;
extern const u8 *const gUnknown_80FD5B8;
extern const u8 *const gUnknown_80FEAC4;
extern const u8 *const gPtrLinkMoveTwoUsesWarningMessage;
extern const u8 *const gPtrLinkMoveOneUseWarningMessage;
extern const u8 *const gPtrLinkedMovesComeApartMessage;
void sub_806A5B8(Entity *entity)
{
s32 terrainType;
if (!EntityIsValid(entity))
return;
terrainType = GetTerrainType(GetTileAtEntitySafe(entity));
if (terrainType == TERRAIN_TYPE_SECONDARY) {
EntityInfo *info = GetEntInfo(entity);
// If lava - defrost and burn
if (gDungeonWaterType[gDungeon->tileset] == DUNGEON_WATER_TYPE_LAVA) {
if (info->frozenClassStatus.status == STATUS_FROZEN) {
EndFrozenClassStatus(entity, entity);
}
if (GetMovementType(info->id) != 4 &&
info->id != MONSTER_HO_OH
&& info->id != MONSTER_MOLTRES
&& info->burnClassStatus.status != STATUS_BURN)
{
BurnedStatusTarget(entity, entity, 1, FALSE);
}
}
// It's water - heal burn
else {
if (info->burnClassStatus.status == STATUS_BURN) {
EndBurnClassStatus(entity, entity);
}
}
}
// If wall - decrement belly by 5
else if (terrainType == TERRAIN_TYPE_WALL) {
const u8 *str;
EntityInfo *info = GetEntInfo(entity);
if (info->isTeamLeader) {
FixedPoint bellyBefore = info->belly;
info->belly = FixedPoint_Subtract(bellyBefore, IntToFixedPointMacro(5));
str = NULL;
if (FixedPointToInt(bellyBefore) > 19 && FixedPointToInt(info->belly) <= 19) {
str = gUnknown_80FD594; // Getting hungry...
}
if (FixedPointToInt(bellyBefore) > 9 && FixedPointToInt(info->belly) <= 9) {
str = gUnknown_80FD5B8; // Getting dizzy from hunger...
}
if (str != NULL) {
LogMessageByIdWithPopupCheckUser(entity, str);
}
}
}
}
void sub_806A6E8(Entity *entity)
{
EntityInfo *info = GetEntInfo(entity);
if (info->unk64 != info->heldItem.id) {
if (!info->isTeamLeader) {
if (info->heldItem.id == ITEM_HEAL_RIBBON || info->heldItem.id == ITEM_MUNCH_BELT) {
info->belly = FixedPoint_Subtract(info->belly, IntToFixedPoint(10));
}
else if (info->heldItem.id == ITEM_DIET_RIBBON) {
info->belly = IntToFixedPoint(0);
}
if (gDungeon->unk644.itemHoldersIdentified) {
EntityUpdateStatusSprites(entity);
}
}
else {
if (info->heldItem.id == ITEM_X_RAY_SPECS || info->unk64 == ITEM_X_RAY_SPECS) {
sub_803F580(1);
sub_8040A84();
}
}
sub_807AA30();
}
if (ItemExists(&info->heldItem)) {
info->unk64 = info->heldItem.id;
}
else {
info->unk64 = ITEM_NOTHING;
}
}
void DisplayMsgIfNewIqSkillLearned(EntityInfo *info, s32 pokeIq);
UNUSED static void DisplayMsgIfTeamMonsLearnedNewIqSkill(void)
{
s32 i;
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
Entity *entity = gDungeon->teamPokemon[i];
if (EntityIsValid(entity)) {
EntityInfo *info = GetEntInfo(entity);
if (info->IQ > 1) {
DisplayMsgIfNewIqSkillLearned(info, info->IQ - 1);
}
}
}
}
void DisplayMsgIfNewIqSkillLearned(EntityInfo *info, s32 iqBefore)
{
s32 i, j;
u8 iqSkillsArrayBefore[NUM_IQ_SKILLS];
u8 iqSkillsArrayNow[NUM_IQ_SKILLS];
s32 numIqSkillsBefore = GetNumAvailableIQSkills(iqSkillsArrayBefore, iqBefore);
s32 numIqSkillsNow = GetNumAvailableIQSkills(iqSkillsArrayNow, info->IQ);
SetMessageArgument_2(gFormatBuffer_Monsters[0], info, 0);
for (i = 1; i < NUM_IQ_SKILLS; i++) {
bool8 hadIqSkillBefore = FALSE;
bool8 hasIqSkillNow = FALSE;
for (j = 0; j < numIqSkillsBefore; j++) {
if (iqSkillsArrayBefore[j] == i) {
hadIqSkillBefore = TRUE;
break;
}
}
for (j = 0; j < numIqSkillsNow; j++) {
if (iqSkillsArrayNow[j] == i) {
hasIqSkillNow = TRUE;
break;
}
}
if (hadIqSkillBefore != hasIqSkillNow) {
strcpy(gFormatBuffer_Items[0], GetIQSkillName(i));
DisplayDungeonLoggableMessageTrue(NULL, gUnknown_80FEAC4); // IQ rose! \n It learned the IQ skill 'i0'
}
}
}
void sub_806A898(Entity *entity, bool8 r7, bool8 showRunAwayEffect)
{
EntityInfo *info = GetEntInfo(entity);
if (info->isTeamLeader) {
info->targetPos.x = entity->pos.x;
info->targetPos.y = entity->pos.y + 1;
}
else {
AIMovement(entity, showRunAwayEffect);
}
if (info->targetPos.x != 0 || info->targetPos.y != 0) {
if (!CheckVariousStatuses2(entity, TRUE) || !CheckVariousStatuses(entity)) {
s32 newDirection = GetDirectionTowardsPosition(&entity->pos, &info->targetPos);
info->action.direction = newDirection & DIRECTION_MASK;
if (r7) {
sub_806CE68(entity, newDirection);
}
}
}
}
void sub_806A914(bool8 a0, bool8 a1, bool8 showRunAwayEffect)
{
s32 i;
for (i = 0; i < DUNGEON_MAX_POKEMON; i++) {
Entity *entity = gDungeon->activePokemon[i];
if (EntityIsValid(entity)) {
EntityInfo *info = GetEntInfo(entity);
if (!a1 || info->monsterBehavior == 1) {
sub_806A898(entity, a0, showRunAwayEffect);
}
}
}
}
void sub_806A974(void)
{
s32 i;
for (i = 0; i < DUNGEON_MAX_POKEMON; i++) {
Entity *entity = gDungeon->activePokemon[i];
if (EntityIsValid(entity)) {
EntityInfo *info = GetEntInfo(entity);
sub_806CE68(entity, info->action.direction);
}
}
}
void sub_806A9B4(Entity *entity, s32 moveIndex)
{
if (EntityIsValid(entity)) {
EntityInfo *info = GetEntInfo(entity);
s32 ret = sub_80935B8(info->moves.moves, moveIndex);
if (ret == 0) {
LogMessageByIdWithPopupCheckUser(entity, gPtrLinkedMovesComeApartMessage);
}
else if (ret == 1) {
LogMessageByIdWithPopupCheckUser(entity, gPtrLinkMoveOneUseWarningMessage);
}
else if (ret == 2) {
LogMessageByIdWithPopupCheckUser(entity, gPtrLinkMoveTwoUsesWarningMessage);
}
}
}
// s16 again...
bool8 sub_806AA0C(s16 _species, bool32 _a1)
{
s32 species = _species;
bool8 a1 = _a1;
if (!IsExclusivePokemonUnlocked(_species))
return FALSE;
if (gDungeon->unk37FD && GetBaseSpecies(species) == MONSTER_DEOXYS_NORMAL)
return FALSE;
if (species == MONSTER_MEW) {
if (gDungeon->unk37FF || !a1)
return FALSE;
}
return TRUE;
}
void sub_806AA70(void)
{
s32 i;
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
Entity *entity = gDungeon->teamPokemon[i];
if (EntityIsValid(entity)) {
EntityInfo *info = GetEntInfo(entity);
s32 teamIndex = info->teamIndex;
if (info->isTeamLeader) {
if (gDungeon->unk11 == 1) {
sub_8042B20(entity);
}
else {
sub_8042B0C(entity);
}
entity->isVisible = FALSE;
}
else {
if (teamIndex >= 0) {
bool8 unkBool = FALSE;
PokemonStruct2 *monStruct2Ptr = &gRecruitedPokemonRef->pokemon2[teamIndex];
if (gDungeon->unk11)
unkBool = TRUE;
else if (sub_806A564(monStruct2Ptr->unkA))
unkBool = TRUE;
else if (sub_806A58C(monStruct2Ptr->unkA))
unkBool = TRUE;
if (unkBool) {
sub_8042B0C(entity);
entity->isVisible = FALSE;
}
}
}
}
}
}
void sub_806AB2C(void)
{
s32 i, j;
for (i = 0; i < DUNGEON_MAX_POKEMON; i++) {
Entity *entity1 = gDungeon->activePokemon[i];
if (EntityIsValid(entity1)) {
EntityInfo *info1 = GetEntInfo(entity1);
for (j = 0; j < DUNGEON_MAX_POKEMON; j++) {
Entity *entity2 = gDungeon->activePokemon[j];
if (EntityIsValid(entity2) && entity1 != entity2 && info1->aiTarget.aiTargetSpawnGenID == entity2->spawnGenID) {
info1->aiTarget.aiTarget = entity2;
}
}
}
}
}
void EndAbilityImmuneStatus(Entity *attacker, Entity *target)
{
EntityInfo *targetInfo = GetEntInfo(target);
if (AbilityIsActive(target, ABILITY_LIMBER) && targetInfo->burnClassStatus.status == STATUS_PARALYSIS) {
EndBurnClassStatus(attacker, target);
}
if (AbilityIsActive(target, ABILITY_OWN_TEMPO) && targetInfo->cringeClassStatus.status == STATUS_CONFUSED) {
EndCringeClassStatus(attacker, target);
}
if (AbilityIsActive(target, ABILITY_WATER_VEIL) && targetInfo->burnClassStatus.status == STATUS_BURN) {
EndBurnClassStatus(attacker, target);
}
if (AbilityIsActive(target, ABILITY_OBLIVIOUS) && targetInfo->cringeClassStatus.status == STATUS_INFATUATED) {
EndCringeClassStatus(attacker, target);
}
if ((AbilityIsActive(target, ABILITY_INSOMNIA) || AbilityIsActive(target, ABILITY_VITAL_SPIRIT))
&& (IsSleeping(target) || targetInfo->sleepClassStatus.status == STATUS_YAWNING))
{
EndSleepClassStatus(attacker, target, FALSE, TRUE);
}
if (AbilityIsActive(target, ABILITY_MAGMA_ARMOR) && targetInfo->frozenClassStatus.status == STATUS_FROZEN) {
EndFrozenClassStatus(attacker, target);
}
if (AbilityIsActive(target, ABILITY_IMMUNITY) && ENTITY_POISONED(targetInfo)) {
EndBurnClassStatus(attacker, target);
}
if (AbilityIsActive(target, ABILITY_FORECAST)) {
targetInfo->isColorChanged = FALSE;
if (targetInfo->reflectClassStatus.status == STATUS_CONVERSION2) {
EndReflectClassStatus(attacker, target);
}
}
}
void MarkLastUsedMonMove(Entity *entity, Move *move)
{
s32 i;
EntityInfo *entInfo = GetEntInfo(entity);
for (i = 0; i < MAX_MON_MOVES; i++) {
entInfo->moves.moves[i].moveFlags &= ~(MOVE_FLAG_LAST_USED);
}
entInfo->moves.struggleMoveFlags &= ~(MOVE_FLAG_LAST_USED);
if (move->id == MOVE_STRUGGLE) {
entInfo->moves.struggleMoveFlags |= MOVE_FLAG_LAST_USED;
}
else {
move->moveFlags |= MOVE_FLAG_LAST_USED;
}
}
s32 sub_806C444(s32 species, s32 level);
s32 sub_806C488(s32 species, s32 level, s32 categoryIndex);
s32 sub_806C4D4(s32 species, s32 level, s32 categoryIndex);
bool8 sub_806B8CC(s16 _species, s32 x, s32 y, PokemonStruct2 *monPtr, Entity **a4, bool32 _a5, u32 _a6);
void sub_806BC68(bool8 a0, Entity *entity, struct unkStruct_806B7F8 *structPtr, DungeonPos *pos);
void ResetMonEntityData(EntityInfo *, bool8 a1);
void sub_806C264(s32 teamIndex, EntityInfo *entInfo);
void sub_806AD3C(void)
{
s32 r10;
s32 i, j;
UnkDungeonGlobal_unk1CD98 sp[64];
unkDungeon2F3C *structPtr = gDungeon->unk2F3C;
s32 var_24 = sub_803D808(sp, 0);
for (i = 0; i < var_24; structPtr++, i++) {
structPtr->species = ExtractSpeciesIndex(&sp[i]);
structPtr->level = ExtractLevel(&sp[i]);
sub_8072AC8(structPtr->moves, structPtr->species, structPtr->level);
if (structPtr->moves[0] == MOVE_NOTHING) {
structPtr->moves[0] = MOVE_BLOWBACK;
}
structPtr->unkC = sub_806C444(structPtr->species, structPtr->level);
for (j = 0; j < 2; j++) {
structPtr->unkE[j] = sub_806C488(structPtr->species, structPtr->level, j);
structPtr->unk10[j] = sub_806C4D4(structPtr->species, structPtr->level, j);
}
}
for (; i < 64; structPtr++, i++) {
structPtr->species = 0;
}
for (i = 0; i < MONSTER_MAX; i++) {
gDungeon->expYieldRankings[i] = 0;
}
r10 = 1;
for (i = 0; i < var_24; i++) {
s32 j;
s32 expSpecies = -1;
s32 expGain = -1;
for (j = 0; j < var_24; j++) {
s32 species = ExtractSpeciesIndex(&sp[j]);
if (gDungeon->expYieldRankings[species] == 0) {
s32 level = ExtractLevel(&sp[j]);
s32 exp = CalculateEXPGain(species, level);
if (expGain < exp) {
expGain = exp;
expSpecies = species;
}
}
}
if (expSpecies < 0)
break;
gDungeon->expYieldRankings[expSpecies] = r10;
r10 += 2;
}
for (i = 0; i < MONSTER_MAX; i++) {
if (gDungeon->expYieldRankings[i] == 0) {
gDungeon->expYieldRankings[i] = 1;
}
}
}
void sub_806AED8(Moves *moves, s16 *maxHPStat, u8 *atk, u8 *def, s16 _species, s32 level)
{
s32 i;
s32 moveCategory;
s32 species = _species;
unkDungeon2F3C *structPtr = gDungeon->unk2F3C;
for (i = 0; i < 64; i++) {
s16 loopSpecies;
structPtr = &gDungeon->unk2F3C[i];
loopSpecies = SpeciesId(structPtr->species);
if (structPtr->species == 0)
break;
if (loopSpecies == species && structPtr->level == level) {
s32 moveIndex;
for (moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++) {
InitPokemonMoveOrNullObject(&moves->moves[moveIndex], structPtr->moves[moveIndex]);
}
*maxHPStat = structPtr->unkC;
for (moveCategory = 0; moveCategory < 2; moveCategory++) {
atk[moveCategory] = structPtr->unkE[moveCategory];
def[moveCategory] = structPtr->unk10[moveCategory];
}
moves->struggleMoveFlags = 0;
return;
}
}
if (i == 64) {
s32 moveIndex;
u16 spMoves[MAX_MON_MOVES];
sub_8072AC8(spMoves, species, level);
for (moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++) {
InitPokemonMoveOrNullObject(&moves->moves[moveIndex], spMoves[moveIndex]);
}
*maxHPStat = sub_806C444(species, level);
for (moveCategory = 0; moveCategory < 2; moveCategory++) {
atk[moveCategory] = sub_806C488(species, level, moveCategory);
def[moveCategory] = sub_806C4D4(species, level, moveCategory);
}
}
else {
s32 moveIndex;
structPtr->species = species;
structPtr->level = level;
sub_8072AC8(structPtr->moves, species, level);
structPtr->unkC = sub_806C444(structPtr->species, structPtr->level);
for (moveCategory = 0; moveCategory < 2; moveCategory++) {
structPtr->unkE[moveCategory] = sub_806C488(structPtr->species, structPtr->level, moveCategory);
structPtr->unk10[moveCategory] = sub_806C4D4(structPtr->species, structPtr->level, moveCategory);
}
for (moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++) {
InitPokemonMoveOrNullObject(&moves->moves[moveIndex], structPtr->moves[moveIndex]);
}
*maxHPStat = structPtr->unkC;
for (moveCategory = 0; moveCategory < 2; moveCategory++) {
atk[moveCategory] = structPtr->unkE[moveCategory];
def[moveCategory] = structPtr->unk10[moveCategory];
}
}
moves->struggleMoveFlags = 0;
}
UNUSED static s32 sub_806B09C(UnkDungeonGlobal_unk1CD98 *unkPtr, bool8 a1)
{
s32 i, j;
s32 count = 0;
s16 *unk2Field;
UnkDungeonGlobal_unk1CD98 *loopPtr;
for (i = 0, unk2Field = unkPtr->unk2, loopPtr = unkPtr; i < MAX_TEAM_MEMBERS; i++) {
PokemonStruct2 *monStructPtr = &gRecruitedPokemonRef->pokemon2[i];
if (PokemonFlag1Struct2(monStructPtr) && PokemonFlag2Struct2(monStructPtr))
{
for (j = 0; j < count; j++) {
if (ExtractSpeciesIndex(&unkPtr[j]) == monStructPtr->speciesNum)
break;
}
if (j == count) {
SetSpeciesLevelToExtract(loopPtr, 0, monStructPtr->speciesNum);
unk2Field[0] = 0;
unk2Field[1] = 0;
unk2Field += sizeof(*unkPtr) / sizeof(unkPtr->unk2[0]); // Hacky solution, because loopPtr->unk2[0/1] = 0; doesn't match
loopPtr++;
count++;
}
}
}
count = sub_803D808(unkPtr, count);
if (a1) {
SetSpeciesLevelToExtract(&unkPtr[count], 1, MONSTER_DECOY);
unkPtr[count].unk2[0] = 0;
unkPtr[count].unk2[1] = 0;
count++;
}
return count;
}
extern const DungeonPos gUnknown_80F4598[];
void sub_806B168(void)
{
s32 count;
PokemonStruct2 *monPtrs[MAX_TEAM_MEMBERS];
PokemonStruct2 *monPtrs2[MAX_TEAM_MEMBERS]; // Leader and partner?
u8 playerSpawnRoomId = GetTile(gDungeon->playerSpawn.x, gDungeon->playerSpawn.y)->room;
s32 i;
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
PokemonStruct2 *currMonPtr = &gRecruitedPokemonRef->pokemon2[i];
currMonPtr->unkC = i;
}
// Populate monPtrs
count = 0;
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
PokemonStruct2 *currMonPtr = &gRecruitedPokemonRef->pokemon2[i];
if (PokemonFlag1Struct2(currMonPtr) && PokemonFlag2Struct2(currMonPtr)) {
monPtrs[count++] = currMonPtr;
}
}
for (; count < MAX_TEAM_MEMBERS; count++) {
monPtrs[count] = NULL;
}
// Populate monPtrs2
count = 0;
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
PokemonStruct2 *currMonPtr = monPtrs[i];
if (currMonPtr != NULL && currMonPtr->isTeamLeader) {
monPtrs[i] = NULL;
monPtrs2[count++] = currMonPtr;
}
}
if (gDungeon->unk644.unk18 == 0) {
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
PokemonStruct2 *currMonPtr = monPtrs[i];
if (currMonPtr != NULL && currMonPtr->dungeonLocation.id == DUNGEON_JOIN_LOCATION_PARTNER) {
monPtrs[i] = NULL;
monPtrs2[count++] = currMonPtr;
}
}
}
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
PokemonStruct2 *currMonPtr = monPtrs[i];
if (monPtrs[i] != NULL) {
monPtrs[i] = NULL;
monPtrs2[count++] = currMonPtr;
}
}
for (; count < MAX_TEAM_MEMBERS; count++) {
monPtrs2[count] = NULL;
}
// Do something else
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
PokemonStruct2 *currMonPtr = monPtrs2[i];
if (currMonPtr != NULL) {
DungeonPos unkPosition;
s32 j;
const Tile *tile;
bool8 skipSecondLoop;
if (currMonPtr->speciesNum == MONSTER_CASTFORM_SNOWY || currMonPtr->speciesNum == MONSTER_CASTFORM_RAINY || currMonPtr->speciesNum == MONSTER_CASTFORM_SUNNY) {
currMonPtr->speciesNum = MONSTER_CASTFORM;
}
skipSecondLoop = FALSE;
j = 0;
while (1) {
unkPosition = gUnknown_80F4598[j];
if (unkPosition.x == 99)
break;
tile = GetTile(unkPosition.x + gDungeon->playerSpawn.x, unkPosition.y + gDungeon->playerSpawn.y);
if (tile->room == playerSpawnRoomId && !sub_807034C(currMonPtr->speciesNum, tile)) {
sub_806B8CC(currMonPtr->speciesNum, unkPosition.x + gDungeon->playerSpawn.x, unkPosition.y + gDungeon->playerSpawn.y, currMonPtr, NULL, TRUE, 0);
skipSecondLoop = TRUE;
break;
}
j++;
}
if (skipSecondLoop)
continue;
j = 0;
while (1) {
unkPosition = gUnknown_80F4598[j];
if (unkPosition.x == 99)
break;
tile = GetTile(unkPosition.x + gDungeon->playerSpawn.x, unkPosition.y + gDungeon->playerSpawn.y);
if (!sub_807034C(currMonPtr->speciesNum, tile)) {
sub_806B8CC(currMonPtr->speciesNum, unkPosition.x + gDungeon->playerSpawn.x, unkPosition.y + gDungeon->playerSpawn.y, currMonPtr, NULL, TRUE, 0);
break;
}
j++;
}
}
}
sub_806B678();
}
void sub_806B404(void)
{
Entity *leader;
s32 i;
PokemonStruct2 *monPtrs[MAX_TEAM_MEMBERS];
u8 roomId;
DungeonPos pos;
s32 count = 0;
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
PokemonStruct2 *currMonPtr = &gRecruitedPokemonRef->pokemon2[i];
if (PokemonFlag1Struct2(currMonPtr) && PokemonFlag2Struct2(currMonPtr) && currMonPtr->unkA == 0x55AA) {
monPtrs[count++] = currMonPtr;
break;
}
}
for (; count < MAX_TEAM_MEMBERS; count++) {
monPtrs[count] = NULL;
}
gLeaderPointer = NULL;
leader = GetLeader();
if (EntityIsValid(leader)) {
pos.x = leader->pos.x;
pos.y = leader->pos.y;
}
else {
pos.x = gDungeon->playerSpawn.x;
pos.y = gDungeon->playerSpawn.y;
}
roomId = GetTile(pos.x, pos.y)->room;
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
DungeonPos unkPosition;
bool8 skipNextLoop;
const Tile *tile;
s32 j;
PokemonStruct2 *currMonPtr = monPtrs[i];
if (currMonPtr != NULL && PokemonFlag1Struct2(currMonPtr) && PokemonFlag2Struct2(currMonPtr) && currMonPtr->unkA == 0x55AA) {
currMonPtr->unkA = 0x5AA5;
skipNextLoop = FALSE;
j = 0;
while (1) {
unkPosition = gUnknown_80F4598[j];
if (unkPosition.x == 99)
break;
tile = GetTile(unkPosition.x + pos.x, unkPosition.y + pos.y);
if (tile->room == roomId && !sub_807034C(currMonPtr->speciesNum, tile)) {
sub_806B8CC(currMonPtr->speciesNum, unkPosition.x + pos.x, unkPosition.y + pos.y, currMonPtr, NULL, TRUE, 0);
skipNextLoop = TRUE;
break;
}
j++;
}
if (skipNextLoop)
continue;
skipNextLoop = FALSE;
j = 0;
while (1) {
unkPosition = gUnknown_80F4598[j];
if (unkPosition.x == 99)
break;
tile = GetTile(unkPosition.x + pos.x, unkPosition.y + pos.y);
if (!sub_807034C(currMonPtr->speciesNum, tile)) {
sub_806B8CC(currMonPtr->speciesNum, unkPosition.x + pos.x, unkPosition.y + pos.y, currMonPtr, NULL, TRUE, 0);
skipNextLoop = TRUE;
break;
}
j++;
}
if (skipNextLoop)
continue;
for (j = 0; j <= 99; j++) {
if (sub_8083660(&unkPosition)) {
const Tile *tile = GetTile(unkPosition.x, unkPosition.y);
if (!sub_807034C(currMonPtr->speciesNum, tile)) {
sub_806B8CC(currMonPtr->speciesNum, unkPosition.x, unkPosition.y, currMonPtr, NULL, TRUE, 0);
break;
}
}
}
}
}
}
void sub_806B678(void)
{
s32 i;
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
Entity *mon = gDungeon->teamPokemon[i];
if (EntityIsValid(mon)) {
EntityInfo *monInfo = GetEntInfo(mon);
if (monInfo->isTeamLeader) {
sub_803F4A0(mon);
gUnknown_202EE0C = mon->pos;
break;
}
}
}
}
/* s16 species;
u8 unk2;
u32 unk4;
u16 level;
DungeonPos pos;
u8 unk10;*/
void sub_806B6C4(void)
{
struct unkStruct_806B7F8 spStruct;
s32 i, j;
s32 x, y;
bool8 r8 = (gDungeon->unk644.unk44 != 0);
if (sub_80860A8(ITEM_MUSIC_BOX) && !HasRecruitedMon(MONSTER_MEW)) {
gDungeon->unk37FF = FALSE;
}
else {
gDungeon->unk37FF = TRUE;
}
x = DungeonRandInt(DUNGEON_MAX_SIZE_X);
y = DungeonRandInt(DUNGEON_MAX_SIZE_Y);
for (j = 0; j < DUNGEON_MAX_SIZE_Y; j++) {
y++;
if (y == DUNGEON_MAX_SIZE_Y) {y = 0;}
for (i = 0; i < DUNGEON_MAX_SIZE_X; i++) {
x++;
if (x == DUNGEON_MAX_SIZE_X) {x = 0;}
if (GetTile(x, y)->spawnOrVisibilityFlags & 8) {
bool8 r6 = FALSE;
if (r8) {
spStruct.species = gDungeon->unk644.unk44;
spStruct.level = 1;
spStruct.unk2 = 1;
r6 = TRUE;
}
else {
spStruct.species = sub_803D970(0);
spStruct.level = 0;
spStruct.unk2 = 0;
}
spStruct.unk4 = 0;
spStruct.unk10 = 0;
spStruct.pos.x = x;
spStruct.pos.y = y;
if (r6 || sub_806AA0C(spStruct.species, TRUE)) {
if (sub_806B7F8(&spStruct, FALSE)) {
r8 = FALSE;
}
}
}
}
}
if (r8) {
gDungeon->unkA = 1;
}
}
Entity* sub_806B7F8(struct unkStruct_806B7F8 *structPtr, bool8 a1)
{
Entity *entity;
EntityInfo *entityInfo;
const Tile *tile = GetTile(structPtr->pos.x, structPtr->pos.y);
if (sub_807034C(structPtr->species, tile))
return FALSE;
entity = sub_804550C(structPtr->species);
if (entity == NULL)
return FALSE;
sub_806BC68(FALSE, entity, structPtr, &gUnknown_202EE0C);
entityInfo = GetEntInfo(entity);
entityInfo->isNotTeamMember = TRUE;
sub_806AED8(&entityInfo->moves, &entityInfo->maxHPStat, entityInfo->atk, entityInfo->def, entityInfo->id, entityInfo->level);
entityInfo->HP = entityInfo->maxHPStat;
entityInfo->moveRandomly = structPtr->unk4;
if (!structPtr->unk2 && !a1 && !structPtr->unk10) {
s32 rand = DungeonRandInt(100);
if (GetChanceAsleep(structPtr->species) > rand) {
sub_8075BF4(entity, 0x7F);
sub_806CE68(entity, NUM_DIRECTIONS);
}
}
return entity;
}
bool8 sub_806B8CC(s16 _species, s32 x, s32 y, PokemonStruct2 *monPtr, Entity **a4, bool32 _a5, u32 _a6)
{
s32 i;
DungeonPos unkPosition;
struct unkStruct_806B7F8 spStruct;
// s16 memes
s32 species = SpeciesId(_species);
bool8 a5 = _a5;
u8 a6 = _a6;
Entity *entity;
EntityInfo *entityInfo;
bool8 isTeamLeader = (monPtr->isTeamLeader != FALSE);
if (a4 != NULL) {
*a4 = NULL;
}
if (GetBaseSpecies(species) == MONSTER_DEOXYS_NORMAL) {
if (a5) {
species = gDungeon->deoxysForm;
}
else {
species = MONSTER_DEOXYS_NORMAL;
}
}
if (sub_807034C(species, GetTile(x, y)))
return FALSE;
entity = sub_80453AC(species);
if (entity == NULL)
return FALSE;
spStruct.pos.x = x;
spStruct.pos.y = y;
spStruct.species = species;
spStruct.level = monPtr->level;
spStruct.unk2 = 0;
spStruct.unk4 = 0;
spStruct.unk10 = 0;
unkPosition.x = gAdjacentTileOffsets[gUnknown_202F32C].x + x;
unkPosition.y = gAdjacentTileOffsets[gUnknown_202F32C].y + y;
sub_806BC68(TRUE, entity, &spStruct, (isTeamLeader ? &unkPosition : &gUnknown_202EE0C));
entityInfo = GetEntInfo(entity);
entityInfo->isNotTeamMember = FALSE;
entityInfo->shopkeeper = 0;
entityInfo->isTeamLeader = isTeamLeader;
entityInfo->unkF9 = a6;
gLeaderPointer = NULL;
if (isTeamLeader) {
gUnknown_202EE0C.x = x;
gUnknown_202EE0C.y = y;
}
entityInfo->HP = monPtr->unk10;
entityInfo->maxHPStat = monPtr->unk12;
entityInfo->exp = monPtr->currExp;
for (i = 0; i < 2; i++) {
entityInfo->atk[i] = monPtr->offense.att[i];
entityInfo->def[i] = monPtr->offense.def[i];
}
entityInfo->moves = monPtr->moves;
for (i = 0; i < MAX_MON_MOVES; i++) {
Move *move = &entityInfo->moves.moves[i];
if (MoveFlagExists(move)) {
move->moveFlags &= ~(MOVE_FLAG_LAST_USED);
move->moveFlags &= ~(MOVE_FLAG_REPLACE);
}
}
entityInfo->moves.struggleMoveFlags &= ~(MOVE_FLAG_LAST_USED);
entityInfo->moves.struggleMoveFlags &= ~(MOVE_FLAG_REPLACE);
entityInfo->level = monPtr->level;
entityInfo->IQ = monPtr->IQ;
entityInfo->tactic = monPtr->tacticIndex;
entityInfo->IQSkillMenuFlags = monPtr->IQSkills;
entityInfo->hiddenPower = monPtr->hiddenPower;
entityInfo->joinedAt = monPtr->dungeonLocation;
entityInfo->belly = monPtr->belly;
entityInfo->maxBelly = monPtr->maxBelly;
entityInfo->teamIndex = monPtr->unkC;
entityInfo->heldItem = monPtr->itemSlot;
entityInfo->unkF3 = 0;
entityInfo->unk64 = 0;
// Pickup Check
if (gDungeon->unk644.dungeonLocation.id != DUNGEON_TINY_WOODS
&& !IsBossFight()
&& (entityInfo->abilities[0] == ABILITY_PICKUP || entityInfo->abilities[1] == ABILITY_PICKUP)
&& !ItemExists(&entityInfo->heldItem))
{
u32 pickUpItem = sub_803D73C(0);
if (pickUpItem != ITEM_POKE) {
xxx_init_itemslot_8090A8C(&entityInfo->heldItem, pickUpItem, 0);
entityInfo->unkF3 = TRUE;
}
}
sub_806A6E8(entity);
LoadIQSkills(entity);
if (a4) {
*a4 = entity;
}
return TRUE;
}
// s16 species memes ughh https://decomp.me/scratch/jcfzb
#ifdef NONMATCHING
void sub_806BB6C(Entity *entity, s16 _species)
{
s32 species = _species;
s16 speciesMatch;
struct unkStruct_806B7F8 spStruct;
EntityInfo *entInfo = GetEntInfo(entity);
DeletePokemonDungeonSprite(entInfo->unk98);
speciesMatch = species;
spStruct.species = speciesMatch;
spStruct.level = 0;
spStruct.unk2 = 0;
spStruct.pos = entity->pos;
spStruct.unk4 = 0;
{
s16 apparentSpeciesMatch;
s32 apparentSpecies = (GetMonsterApparentID(NULL, _species));
entity->unk22 = 0;
apparentSpeciesMatch = apparentSpecies;
GetEntInfo(entity)->apparentID = (apparentSpecies);
GetEntInfo(entity)->id = speciesMatch;
entity->axObj.spriteFile = GetSpriteData(apparentSpeciesMatch);
}
entity->axObj.unk42_animId1 = 7;
entity->axObj.unk44_direction1 = 0;
entity->axObj.unk43_animId2 = 0xFF;
entity->axObj.unk45_orientation = 1;
entity->axObj.unk47 = 1;
entity->unk1C = 0;
if (entInfo->frozenClassStatus.status == STATUS_WRAP || entInfo->frozenClassStatus.status == STATUS_WRAPPED) {
sub_8076CB4(entInfo->unk9C);
}
sub_806BC68((entInfo->isNotTeamMember == FALSE), entity, &spStruct, NULL);
sub_806AED8(&entInfo->moves, &entInfo->maxHPStat, entInfo->atk, entInfo->def, entInfo->id, entInfo->level);
entInfo->HP = entInfo->maxHPStat;
entInfo->shopkeeper = 0;
sub_80429E8(entity);
EntityUpdateStatusSprites(entity);
}
#else
NAKED void sub_806BB6C(Entity *entity, s16 _species)
{
asm_unified("\n"
" push {r4-r7,lr}\n"
" mov r7, r10\n"
" mov r6, r9\n"
" mov r5, r8\n"
" push {r5-r7}\n"
" sub sp, 0x1C\n"
" adds r7, r0, 0\n"
" lsls r4, r1, 16\n"
" asrs r4, 16\n"
" ldr r0, [r7, 0x70]\n"
" mov r9, r0\n"
" mov r8, r9\n"
" adds r0, 0x98\n"
" ldr r0, [r0]\n"
" bl DeletePokemonDungeonSprite\n"
" add r0, sp, 0x8\n"
" movs r1, 0\n"
" mov r10, r1\n"
" movs r6, 0\n"
" lsls r5, r4, 16\n"
" lsrs r5, 16\n"
" strh r5, [r0]\n"
" strh r6, [r0, 0x8]\n"
" mov r2, r10\n"
" strb r2, [r0, 0x2]\n"
" ldr r0, [r7, 0x4]\n"
" str r0, [sp, 0x14]\n"
" str r6, [sp, 0xC]\n"
" movs r0, 0\n"
" adds r1, r4, 0\n"
" bl GetMonsterApparentID\n"
" lsls r0, 16\n"
" adds r1, r7, 0\n"
" adds r1, 0x22\n"
" mov r2, r10\n"
" strb r2, [r1]\n"
" ldr r1, [r7, 0x70]\n"
" asrs r2, r0, 16\n"
" lsrs r0, 16\n"
" strh r0, [r1, 0x4]\n"
" ldr r0, [r7, 0x70]\n"
" strh r5, [r0, 0x2]\n"
" adds r0, r2, 0\n"
" bl GetSpriteData\n"
" str r0, [r7, 0x64]\n"
" adds r1, r7, 0\n"
" adds r1, 0x6A\n"
" movs r0, 0x7\n"
" strb r0, [r1]\n"
" adds r0, r7, 0\n"
" adds r0, 0x6C\n"
" mov r5, r10\n"
" strb r5, [r0]\n"
" adds r1, 0x1\n"
" movs r0, 0xFF\n"
" strb r0, [r1]\n"
" adds r1, 0x2\n"
" movs r0, 0x1\n"
" strb r0, [r1]\n"
" adds r1, 0x2\n"
" strb r0, [r1]\n"
" str r6, [r7, 0x1C]\n"
" mov r0, r9\n"
" adds r0, 0xB0\n"
" ldrb r0, [r0]\n"
" subs r0, 0x3\n"
" lsls r0, 24\n"
" lsrs r0, 24\n"
" cmp r0, 0x1\n"
" bhi _0806BC08\n"
" mov r0, r9\n"
" adds r0, 0x9C\n"
" ldr r0, [r0]\n"
" bl sub_8076CB4\n"
"_0806BC08:\n"
" movs r1, 0\n"
" mov r6, r9\n"
" ldrb r0, [r6, 0x6]\n"
" cmp r0, 0\n"
" bne _0806BC14\n"
" movs r1, 0x1\n"
"_0806BC14:\n"
" adds r0, r1, 0\n"
" adds r1, r7, 0\n"
" add r2, sp, 0x8\n"
" movs r3, 0\n"
" bl sub_806BC68\n"
" movs r0, 0x8C\n"
" lsls r0, 1\n"
" add r0, r8\n"
" mov r1, r8\n"
" adds r1, 0x10\n"
" mov r2, r8\n"
" adds r2, 0x14\n"
" mov r3, r8\n"
" adds r3, 0x16\n"
" mov r5, r8\n"
" movs r6, 0x2\n"
" ldrsh r4, [r5, r6]\n"
" str r4, [sp]\n"
" ldrb r4, [r5, 0x9]\n"
" str r4, [sp, 0x4]\n"
" bl sub_806AED8\n"
" ldrh r0, [r5, 0x10]\n"
" strh r0, [r5, 0xE]\n"
" mov r0, r10\n"
" strb r0, [r5, 0x8]\n"
" adds r0, r7, 0\n"
" bl sub_80429E8\n"
" adds r0, r7, 0\n"
" bl EntityUpdateStatusSprites\n"
" add sp, 0x1C\n"
" pop {r3-r5}\n"
" mov r8, r3\n"
" mov r9, r4\n"
" mov r10, r5\n"
" pop {r4-r7}\n"
" pop {r0}\n"
" bx r0");
}
#endif // NONMATCHING
void sub_806BC68(bool8 a0, Entity *entity, struct unkStruct_806B7F8 *structPtr, DungeonPos *pos)
{
DungeonPos entityPos;
EntityInfo *entInfo;
gDungeon->unkC = 1;
entInfo = GetEntInfo(entity);
ResetMonEntityData(entInfo, TRUE);
entInfo->monsterBehavior = structPtr->unk2;
entity->isVisible = TRUE;
entity->unk22 = 0;
entity->prevPos.x = -1;
entity->prevPos.y = -1;
entity->pos.x = -2;
entity->pos.y = -2;
sub_80694C0(entity, structPtr->pos.x, structPtr->pos.y, 1);
sub_804535C(entity, NULL);
if (!a0) {
if (structPtr->species == MONSTER_KECLEON
&& !gDungeon->unk644.unk2A
&& gDungeon->unk3A0A
&& !structPtr->unk2)
{
entInfo->shopkeeper = 1;
}
else {
entInfo->shopkeeper = 0;
}
if (GetBaseSpecies(entInfo->id) == MONSTER_DEOXYS_NORMAL) {
gDungeon->unk37FD = TRUE;
}
if (GetBaseSpecies(entInfo->id) == MONSTER_MEW) {
gDungeon->unk37FF = TRUE;
}
}
entInfo->unk98 = gDungeon->unk37F0;
gDungeon->unk37F0++;
entInfo->unk9C = 0;
if (structPtr->level == 0) {
entInfo->level = sub_803DA20(structPtr->species);
}
else {
entInfo->level = structPtr->level;
}
entInfo->moveRandomly = structPtr->unk4;
entInfo->IQ = 1;
SetDefaultIQSkills(&entInfo->IQSkillMenuFlags, FALSE);
GenerateHiddenPower(&entInfo->hiddenPower);
entInfo->maxHPStat = 1;
entInfo->HP = 1;
entInfo->belly = IntToFixedPoint(100);
entInfo->maxBelly = IntToFixedPoint(100);
if (pos != NULL) {
entInfo->targetPos = *pos;
}
else {
entInfo->targetPos.x = 0;
entInfo->targetPos.y = 0;
}
entInfo->flags = 0;
entInfo->aiAllySkip = FALSE;
entInfo->recalculateFollow = FALSE;
entInfo->numMoveTiles = 0;
entInfo->notMoving = 0;
entInfo->aiTarget.aiObjective = 0;
entInfo->aiTarget.aiTargetPos = entity->pos;
entInfo->aiTarget.aiTarget = NULL;
entInfo->aiTarget.unkC = 0;
entInfo->aiTarget.aiTargetSpawnGenID = 0;
entInfo->unkFF = 0;
entInfo->unk174.raw = 0;
entInfo->decoyAITracker = 0;
ResetMonEntityData(entInfo, TRUE);
ZeroOutItem(&entInfo->heldItem);
entInfo->unk64 = 0;
entInfo->statusIcons = 0;
entInfo->unk164 = 0xFF;
entInfo->unk165 = 0xFF;
entInfo->expGainedInTurn = 0;
entInfo->waiting = 0;
entInfo->unk146 = 0;
entInfo->unk166 = 0;
entInfo->unk1F8 = 0;
entInfo->mobileTurnTimer = 0;
entInfo->attacking = FALSE;
entInfo->unk149 = FALSE;
entInfo->abilityEffectFlags = FALSE;
entInfo->terrifiedTurns = 0;
entInfo->useHeldItem = 0;
entInfo->unk14B = 0;
entInfo->unk14C = 1;
entInfo->visualFlags = 0;
entInfo->previousVisualFlags = 0;
entInfo->unk152 = 0;
entInfo->unk153 = 0;
entInfo->unk154 = 0;
entInfo->unk155 = 0;
entInfo->turnsSinceWarpScarfActivation = 0;
entInfo->perishSongTurns = 0;
entInfo->unkFE = 99;
entInfo->unk158 = 0;
entInfo->unk159 = 0;
entInfo->unk15A = 0;
CalcSpeedStage(entity);
entInfo->unk156 = 1;
entInfo->unk15C = 0;
entInfo->unk15E = 0;
entInfo->unk15D = 0;
entInfo->unk15F = 0;
entInfo->unk160 = 0;
if (entInfo->apparentID == MONSTER_DIGLETT || entInfo->apparentID == MONSTER_DUGTRIO) {
entInfo->unk156 = 0;
}
entityPos.x = entity->pos.x;
entityPos.y = entity->pos.y;
AddPokemonDungeonSprite(entInfo->unk98, entInfo->apparentID, &entityPos, gDungeon->unk181e8.priority);
LoadIQSkills(entity);
sub_806A898(entity, FALSE, FALSE);
}
void ResetMonEntityData(EntityInfo *entInfo, bool8 setStatsToOne)
{
s32 i;
bool8 hasForecast;
entInfo->sleepClassStatus.status = 0;
entInfo->sleepClassStatus.turns = 0;
entInfo->burnClassStatus.status = 0;
entInfo->burnClassStatus.turns = 0;
entInfo->burnClassStatus.damageCountdown = 0;
entInfo->burnClassStatus.unk4 = 0;
entInfo->frozenClassStatus.status = 0;
entInfo->frozenClassStatus.turns = 0;
entInfo->frozenClassStatus.damageCountdown = 0;
entInfo->frozenClassStatus.unk4 = 34;
entInfo->cringeClassStatus.status = 0;
entInfo->cringeClassStatus.turns = 0;
entInfo->bideClassStatus.status = 0;
entInfo->reflectClassStatus.status = 0;
entInfo->reflectClassStatus.turns = 0;
entInfo->curseClassStatus.status = 0;
entInfo->curseClassStatus.turns = 0;
entInfo->curseClassStatus.damageCountdown = 0;
entInfo->leechSeedClassStatus.status = 0;
entInfo->leechSeedClassStatus.turns = 0;
entInfo->leechSeedClassStatus.damageCountdown = 0;
entInfo->sureShotClassStatus.status = 0;
entInfo->sureShotClassStatus.turns = 0;
entInfo->longTossClassStatus.status = 0;
entInfo->invisibleClassStatus.status = 0;
entInfo->invisibleClassStatus.turns = 0;
entInfo->blinkerClassStatus.status = 0;
entInfo->blinkerClassStatus.turns = 0;
entInfo->muzzled.muzzled = FALSE;
entInfo->muzzled.turns = 0;
entInfo->powerEars = FALSE;
entInfo->scanning = FALSE;
entInfo->stairSpotter = FALSE;
entInfo->stairSpotter = FALSE;
entInfo->unk164 = 0xFF;
entInfo->unk165 = 0xFF;
for (i = 0; i < NUM_SPEED_COUNTERS; i++) {
entInfo->speedUpCounters[i] = 0;
entInfo->speedDownCounters[i] = 0;
}
hasForecast = FALSE;
for (i = 0; i < 2; i++) {
entInfo->abilities[i] = GetPokemonAbility(entInfo->id, i);
if (entInfo->abilities[i] == ABILITY_FORECAST) {
hasForecast = TRUE;
}
if (setStatsToOne) {
entInfo->atk[i] = 1;
entInfo->def[i] = 1;
}
entInfo->offensiveStages[i] = 10;
entInfo->defensiveStages[i] = 10;
entInfo->hitChanceStages[i] = 10;
entInfo->offensiveMultipliers[i].raw = IntToF248_2(1).raw;
entInfo->defensiveMultipliers[i].raw = IntToF248_2(1).raw;
}
if (hasForecast) {
entInfo->types[0] = gCastformByWeather[GetApparentWeather(NULL)].type;
entInfo->types[1] = TYPE_NONE;
}
else {
for (i = 0; i < 2; i++) {
entInfo->types[i] = GetPokemonType(entInfo->id, i);
}
}
gDungeon->unkC = 1;
entInfo->flashFireBoost = 0;
entInfo->stockpileStage = 0;
entInfo->perishSongTurns = 0;
entInfo->speedBoostFrames = 0;
entInfo->grudge = 0;
entInfo->expMultiplier = EXP_HALVED;
entInfo->exposed = FALSE;
entInfo->isColorChanged = 0;
entInfo->bossFlag = 0;
entInfo->unkFF = 0;
}
void sub_806C1D8(void)
{
s32 i, j;
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
Entity *entity = gDungeon->teamPokemon[i];
if (EntityIsValid(entity)) {
EntityInfo *entInfo = GetEntInfo(entity);
s32 teamIndex = entInfo->teamIndex;
if (teamIndex >= 0) {
for (j = 0; j < MAX_MON_MOVES; j++) {
if (MoveFlagExists(&entInfo->moves.moves[j])) {
entInfo->moves.moves[j].moveFlags2 &= ~(1);
}
}
sub_806C264(teamIndex, entInfo);
}
}
}
}
void sub_806C264(s32 teamIndex, EntityInfo *entInfo)
{
s32 i;
PokemonStruct2 *monPtr = &gRecruitedPokemonRef->pokemon2[teamIndex];
monPtr->unk10 = entInfo->HP;
monPtr->unk12 = entInfo->maxHPStat;
monPtr->currExp = entInfo->exp;
for (i = 0; i < 2; i++) {
monPtr->offense.att[i] = entInfo->atk[i];
monPtr->offense.def[i] = entInfo->def[i];
}
if (IS_CASTFORM_FORM_MONSTER(entInfo->apparentID)) {
monPtr->speciesNum = MONSTER_CASTFORM;
}
monPtr->moves = entInfo->moves;
monPtr->level = entInfo->level;
monPtr->IQ = entInfo->IQ;
monPtr->IQSkills = entInfo->IQSkillMenuFlags;
monPtr->tacticIndex = entInfo->tactic;
monPtr->hiddenPower = entInfo->hiddenPower;
monPtr->belly = entInfo->belly;
monPtr->maxBelly = entInfo->maxBelly;
monPtr->itemSlot = entInfo->heldItem;
if (monPtr->unkA == 0x55AA) {
monPtr->unkA = 0x5AA5;
}
}
// s16 species memes again
void sub_806C330(s32 _x, s32 _y, s16 _species, u32 _a3)
{
s32 i;
s32 x = _x;
s32 y = _y;
s32 species = (_species);
u8 a3 = _a3;
unkDungeon57C *strPtr = &gDungeon->unk57C;
for (i = 0; i < strPtr->unk40; i++) {
if (strPtr->unkArray[i].unk3 && strPtr->unkArray[i].unk4 == x && strPtr->unkArray[i].unk5 == y) {
s16 speciesMatchMe = SpeciesId(_species);
strPtr->unkArray[i].unk0 = speciesMatchMe;
strPtr->unkArray[i].unk2 = a3;
return;
}
}
if (strPtr->unk40 < UNK_DUNGEON57C_ARRAY_COUNT) {
strPtr->unkArray[strPtr->unk40].unk3 = TRUE;
strPtr->unkArray[strPtr->unk40].unk4 = x;
strPtr->unkArray[strPtr->unk40].unk5 = y;
strPtr->unkArray[strPtr->unk40].unk0 = species;
strPtr->unkArray[strPtr->unk40].unk2 = a3;
strPtr->unk40++;
}
}
void sub_806C3C0(void)
{
s32 i;
struct unkStruct_806B7F8 spStruct;
unkDungeon57C *strPtr = &gDungeon->unk57C;
for (i = 0; i < strPtr->unk40; i++) {
if (strPtr->unkArray[i].unk3) {
spStruct.species = strPtr->unkArray[i].unk0;
spStruct.level = 0;
spStruct.pos.x = strPtr->unkArray[i].unk4;
spStruct.pos.y = strPtr->unkArray[i].unk5;
spStruct.unk2 = strPtr->unkArray[i].unk2;
spStruct.unk4 = 0;
spStruct.unk10 = 0;
sub_806B7F8(&spStruct, TRUE);
}
}
}
void sub_806C42C(void)
{
unkDungeon57C *strPtr = &gDungeon->unk57C;
strPtr->unk40 = 0;
}
s32 sub_806C444(s32 _species, s32 level)
{
LevelData levelData;
s32 i;
s32 species = SpeciesId(_species);
s32 hpCount = GetBaseHP(species);
for (i = 2; i <= level; i++) {
GetPokemonLevelData(&levelData, species, i);
hpCount += levelData.gainHP;
}
return hpCount;
}
s32 sub_806C488(s32 _species, s32 level, s32 categoryIndex)
{
LevelData levelData;
s32 i;
s32 species = SpeciesId(_species);
s32 offensiveCount = GetBaseOffensiveStat(species, categoryIndex);
for (i = 2; i <= level; i++) {
GetPokemonLevelData(&levelData, species, i);
offensiveCount += levelData.gainAtt[categoryIndex];
}
return offensiveCount;
}
s32 sub_806C4D4(s32 _species, s32 level, s32 categoryIndex)
{
LevelData levelData;
s32 i;
s32 species = SpeciesId(_species);
s32 defensiveCount = GetBaseDefensiveStat(species, categoryIndex);
for (i = 2; i <= level; i++) {
GetPokemonLevelData(&levelData, species, i);
defensiveCount += levelData.gainDef[categoryIndex];
}
return defensiveCount;
}
extern const u8 gUnknown_8106EC8[][13];
static inline u16 GetUnkFlag(Entity *entity)
{
if ((entity->axObj.axdata.flags & 0x2000))
return 0;
else
return entity->axObj.axdata.flags >> 15;
}
void sub_806C51C(Entity *entity)
{
s32 x, y, y2;
bool8 var_3C;
bool8 decoySprite;
s32 var_34;
DungeonPos pos1;
DungeonPos posArray[4];
u32 statusSprites;
bool8 r4;
u8 r7;
unkStruct_2039DB0 spriteMasks;
s32 xSprite, ySprite;
EntityInfo *entInfo = GetEntInfo(entity);
if (gDungeon->unk181e8.cameraTarget == entity) {
decoySprite = FALSE;
}
else {
decoySprite = gDungeon->unk181e8.hallucinating;
}
if (entInfo->curseClassStatus.status == STATUS_DECOY) {
decoySprite = TRUE;
}
if (entity->axObj.unk43_animId2 == entity->axObj.unk42_animId1 && entity->axObj.unk45_orientation == entity->axObj.unk44_direction1 && entity->axObj.unk47 == 0) {
bool8 r2 = FALSE;
if (!GetUnkFlag(entity))
r2 = TRUE;
if (r2) {
s32 r0;
s32 r3 = sub_806CEBC(entity);
entity->unk21 = 1;
if (entInfo->unkFE == 99) {
if (entity->axObj.unk43_animId2 <= 12) {
s32 r2;
if (entInfo->bideClassStatus.status == STATUS_BIDE) {
r2 = 2;
}
else if (entity->unk23 < 3) {
r2 = 0;
}
else {
r2 = 1;
}
r0 = gUnknown_8106EC8[r2][entity->axObj.unk43_animId2];
if (r0 == 7) {
r0 = r3;
}
}
else {
r0 = 99;
}
}
else {
r0 = entInfo->unkFE;
}
if (r0 != 99) {
entity->axObj.unk42_animId1 = r0;
entity->axObj.unk44_direction1 = entity->axObj.unk45_orientation & DIRECTION_MASK;
entity->axObj.unk47 = 1;
if (entity->axObj.unk42_animId1 == 6 && ++entity->axObj.unk46 == 16) {
entity->axObj.unk42_animId1 = r3;
}
}
}
}
if (entity->axObj.unk43_animId2 != entity->axObj.unk42_animId1 || entity->axObj.unk45_orientation != entity->axObj.unk44_direction1 || entity->axObj.unk47 != 0) {
s32 r7;
entity->axObj.unk43_animId2 = entity->axObj.unk42_animId1;
entity->axObj.unk45_orientation = entity->axObj.unk44_direction1;
entity->axObj.unk47 = 0;
r7 = entity->axObj.unk40_maybeAnimTimer;
if (sub_808DA44(entInfo->apparentID, entity->axObj.unk42_animId1)) {
r7 = 0;
}
if (!decoySprite) {
s32 rnd = Rand32Bit() & 3;
AxResInitFile(&entity->axObj.axdata, entity->axObj.spriteFile, entity->axObj.unk42_animId1, entity->axObj.unk44_direction1, r7, rnd, FALSE);
}
else {
OpenedFile *spriteData = GetSpriteData(MONSTER_DECOY);
s32 rnd = Rand32Bit() & 3;
AxResInitFile(&entity->axObj.axdata, spriteData, entity->axObj.unk42_animId1, entity->axObj.unk44_direction1, r7, rnd, FALSE);
}
if (entity->axObj.unk42_animId1 != 6) {
entity->axObj.unk46 = 0;
}
}
if (gDungeon->unk1356C) {
if (entity->axObj.unk43_animId2 != 7 || GetMovementType(entInfo->apparentID) == 2) {
if (entInfo->unk15C != 0) {
if (entInfo->unk160 == 0) {
if (entInfo->unk15F != 0) {
RunAxAnimationFrame(&entity->axObj);
RunAxAnimationFrame(&entity->axObj);
RunAxAnimationFrame(&entity->axObj);
}
else {
RunAxAnimationFrame(&entity->axObj);
}
}
}
else {
RunAxAnimationFrame(&entity->axObj);
}
}
}
else {
if (entInfo->frozenClassStatus.status != STATUS_FROZEN && entInfo->frozenClassStatus.status != STATUS_PETRIFIED) {
if (gDungeon->unk644.unk28 != 0 && gDungeon->unk1BDD4.unk1C05F == 0) {
RunAxAnimationFrame(&entity->axObj);
RunAxAnimationFrame(&entity->axObj);
}
else if ((entity->axObj.unk43_animId2 == 0 || entity->axObj.unk43_animId2 == 7) && GetEntInfo(entity)->speedStage > 1) {
RunAxAnimationFrame(&entity->axObj);
}
RunAxAnimationFrame(&entity->axObj);
}
}
if (entity->pixelPos.x == entity->prevPixelPos.x && entity->pixelPos.y == entity->prevPixelPos.y) {
if (entity->unk23 < 10) {
entity->unk23++;
}
}
else {
entity->unk23 = 0;
}
entity->prevPixelPos.x = entity->pixelPos.x;
entity->prevPixelPos.y = entity->pixelPos.y;
x = (entity->pixelPos.x / 256) - gDungeon->unk181e8.cameraPixelPos.x;
y = (((entity->pixelPos.y - entity->unk1C.raw) - entInfo->unk174.raw) / 256) - gDungeon->unk181e8.cameraPixelPos.y;
y2 = (entity->pixelPos.y / 256) - gDungeon->unk181e8.cameraPixelPos.y;
y2 /= 2;
if (entInfo->unk156 == 0) {
y2--;
}
if (entInfo->unk15C == 0) {
var_3C = sub_8042768(entity);
}
else {
if (entInfo->unk15D != 0) {
if (gUnknown_202EDCC & 4) {
x++;
}
else {
x--;
}
}
var_3C = (entInfo->unk15E == 0);
}
pos1.x = entity->pixelPos.x / 256;
pos1.y = ((entity->pixelPos.y - entity->unk1C.raw) - entInfo->unk174.raw) / 256;
sub_8005700(posArray, &entity->axObj);
sub_800F958(entInfo->unk98, &pos1, posArray, gDungeon->unk181e8.priority);
statusSprites = EntityGetStatusSprites(entity);
UpdateDungeonPokemonSprite(entInfo->unk98, entInfo->apparentID, statusSprites, (var_3C && entInfo->unk14C));
sub_8042EC8(entity, y2);
if (entInfo->unk15C == 0) {
if (entInfo->unkFF == 1) {
if (entInfo->unk174.raw <= IntToF248_2(199.999).raw) {
entInfo->unk174.raw += IntToF248_2(8).raw;
if (entInfo->unk174.raw > IntToF248_2(200).raw) {
entInfo->unk174.raw = IntToF248_2(200).raw;
}
}
}
else {
entInfo->unk174.raw -= IntToF248_2(12).raw;
if (entInfo->unk174.raw < IntToF248_2(0).raw) {
entInfo->unk174.raw = IntToF248_2(0).raw;
}
}
}
if (!var_3C)
return;
r4 = FALSE;
r7 = sub_806CF54(entity);
spriteMasks.unk0 = 0xF3FF;
spriteMasks.unk2 = 0xFFFF;
spriteMasks.unk4 = 0xF3FF;
spriteMasks.unk6 = 0;
spriteMasks.unk8 = 0;
spriteMasks.unkA = gDungeon->unk181e8.priority << 10;
if (entInfo->isNotTeamMember && (entInfo->apparentID == MONSTER_DEOXYS_ATTACK || entInfo->apparentID == MONSTER_DEOXYS_DEFENSE || entInfo->apparentID == MONSTER_DEOXYS_SPEED)) {
r4 = TRUE;
}
if (entInfo->invisibleClassStatus.status == STATUS_INVISIBLE && !gDungeon->unk181e8.unk1820F) {
r4 = TRUE;
}
if (r4) {
spriteMasks.unk6 |= 0x400;
}
var_34 = 0;
if (!entInfo->isNotTeamMember || entInfo->curseClassStatus.status == STATUS_DECOY) {
var_34 = 1;
}
if (IsExperienceLocked(entInfo->joinedAt.id) || entInfo->monsterBehavior == 1) {
var_34 = 1;
}
if (entInfo->unkFF != 2) {
s32 overworldPal;
if (entInfo->frozenClassStatus.status == STATUS_PETRIFIED || entInfo->burnClassStatus.status == STATUS_PARALYSIS || entInfo->frozenClassStatus.status == STATUS_SHADOW_HOLD) {
x += gUnknown_202EDCC & 2;
}
if (decoySprite) {
overworldPal = GetPokemonOverworldPalette(MONSTER_DECOY, 0);
}
else {
overworldPal = GetPokemonOverworldPalette(entInfo->apparentID, 0);
}
if (entity->unk22 == 0) {
DoAxFrame_800558C(&entity->axObj, x, y, y2, overworldPal, &spriteMasks);
}
else if (entity->unk22 == 1 && (gUnknown_202EDCC & 1)) {
DoAxFrame_800558C(&entity->axObj, x, y, y2, overworldPal, &spriteMasks);
}
}
entInfo->pixelPos.x = (entity->pixelPos.x / 256) + entity->axObj.axdata.sub1.shadow.x;
entInfo->pixelPos.y = (entity->pixelPos.y / 256) + entity->axObj.axdata.sub1.shadow.y;
xSprite = entInfo->pixelPos.x - gDungeon->unk181e8.cameraPixelPos.x;
ySprite = entInfo->pixelPos.y - gDungeon->unk181e8.cameraPixelPos.y;
if (xSprite >= -32 && ySprite >= -32 && xSprite <= 271 && ySprite <= 191 && r7 != 6 && entity->unk22 == 0) {
struct unkStruct_202ED28 *spriteStructPtr = &gUnknown_202ED28[var_34][r7];
if (entInfo->unk156 != 0) {
SpriteSetX(&spriteStructPtr->sprite, xSprite + spriteStructPtr->x);
SpriteSetY(&spriteStructPtr->sprite, ySprite + spriteStructPtr->y);
AddSprite(&spriteStructPtr->sprite, 0, NULL, NULL);
}
}
}