mirror of
https://github.com/pret/pmd-red.git
synced 2026-05-19 05:18:48 -05:00
1756 lines
55 KiB
C
1756 lines
55 KiB
C
#include "global.h"
|
|
#include "globaldata.h"
|
|
#include "dungeon_misc.h"
|
|
#include "dungeon_music.h"
|
|
#include "structs/str_dungeon.h"
|
|
#include "dungeon_util.h"
|
|
#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"
|
|
#include "run_dungeon.h"
|
|
#include "move_orb_effects_1.h"
|
|
#include "dungeon_map_access.h"
|
|
#include "dungeon_map.h"
|
|
#include "dungeon_range.h"
|
|
#include "dungeon_message.h"
|
|
#include "dungeon_message_log.h"
|
|
#include "dungeon_logic.h"
|
|
#include "constants/ability.h"
|
|
#include "constants/dungeon.h"
|
|
#include "constants/dungeon_exit.h"
|
|
#include "constants/fixed_rooms.h"
|
|
#include "constants/friend_area.h"
|
|
#include "constants/iq_skill.h"
|
|
#include "constants/status.h"
|
|
#include "constants/type.h"
|
|
#include "constants/weather.h"
|
|
#include "dungeon_mon_sprite_render.h"
|
|
#include "dungeon_util.h"
|
|
#include "exclusive_pokemon.h"
|
|
#include "dungeon_config.h"
|
|
#include "game_options.h"
|
|
#include "weather.h"
|
|
#include "pokemon_types.h"
|
|
#include "dungeon_random.h"
|
|
#include "position_util.h"
|
|
#include "dungeon_ai_movement.h"
|
|
#include "dungeon_vram.h"
|
|
#include "def_filearchives.h"
|
|
#include "code_803D110.h"
|
|
#include "dungeon_strings.h"
|
|
#include "dungeon_exit.h"
|
|
#include "dungeon_pos_data.h"
|
|
#include "dungeon_data.h"
|
|
#include "dungeon_tilemap.h"
|
|
#include "dungeon_engine.h"
|
|
#include "dungeon_cutscene.h"
|
|
#include "dungeon_mon_spawn.h"
|
|
#include "dungeon_info.h"
|
|
#include "dungeon_monster_house.h"
|
|
#include "move_orb_effects_2.h"
|
|
#include "move_orb_effects_5.h"
|
|
#include "dungeon_recruit_release_menu.h"
|
|
#include "dungeon_8041AD0.h"
|
|
#include "dungeon_pokemon_sprites.h"
|
|
|
|
static void EnsureCastformLoaded(void);
|
|
static void EnsureDeoxysLoaded(void);
|
|
static bool8 sub_806A5A4(s16 r0);
|
|
|
|
void OpenDungeonPaletteFile(void)
|
|
{
|
|
gDungeon->paletFile = OpenFileAndGetFileDataPtr("palet", &gMonsterFileArchive);
|
|
}
|
|
|
|
void CloseDungeonPaletteFile(void)
|
|
{
|
|
CloseFile(gDungeon->paletFile);
|
|
}
|
|
|
|
void LoadDungeonPokemonSprites(void)
|
|
{
|
|
s32 index;
|
|
|
|
for(index = 0; index < MONSTER_MAX; index++)
|
|
{
|
|
gDungeon->sprites[index] = NULL;
|
|
}
|
|
LoadPokemonSprite(MONSTER_DECOY, TRUE);
|
|
for(index = 0; index < gDungeon->currFloorMonsterSpawnsCount; index++)
|
|
{
|
|
LoadPokemonSprite(ExtractSpeciesIndex(&gDungeon->monsterSpawns[index]), TRUE);
|
|
}
|
|
if(gDungeon->unk644.unk44)
|
|
{
|
|
LoadPokemonSprite(gDungeon->unk644.unk44, TRUE);
|
|
}
|
|
for(index = 0; index < 4; index++)
|
|
{
|
|
DungeonMon *ptr = &gRecruitedPokemonRef->dungeonTeam[index];
|
|
if(DungeonMonExists(ptr))
|
|
if(DungeonMonIsOnTeam(ptr))
|
|
LoadPokemonSprite(ptr->speciesNum, FALSE);
|
|
}
|
|
if(gDungeon->fixedRoomNumber == FIXED_ROOM_RESCUE_TEAM_MAZE_BOSS)
|
|
{
|
|
for(index = 0; index < MAX_TEAM_MEMBERS; index++)
|
|
{
|
|
Pokemon *ptr = &gRecruitedPokemonRef->team[index];
|
|
if(PokemonExists(ptr))
|
|
LoadPokemonSprite(ptr->speciesNum, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void LoadDungeonActivePokemonSprites(void)
|
|
{
|
|
Entity *entity;
|
|
s32 i;
|
|
|
|
for (i = 0; i < DUNGEON_MAX_POKEMON; i++) {
|
|
entity = gDungeon->activePokemon[i];
|
|
|
|
if (entity != NULL && EntityIsValid(entity))
|
|
LoadPokemonSprite(GetEntInfo(entity)->apparentID, FALSE);
|
|
}
|
|
}
|
|
|
|
void sub_80687AC(void)
|
|
{
|
|
gDungeon->unk37F0 = 0x400;
|
|
gDungeon->unk37F4 = 10;
|
|
}
|
|
|
|
OpenedFile *GetSpriteData(s32 _species)
|
|
{
|
|
s32 species = (s16)(_species);
|
|
return gDungeon->sprites[species];
|
|
}
|
|
|
|
static void EnsureSpriteLoaded(s32 _id)
|
|
{
|
|
u8 name[12];
|
|
s32 id = (s16) _id;
|
|
|
|
if (gDungeon->sprites[id] == NULL) {
|
|
sprintf(name, "ax%03d", id);
|
|
gDungeon->sprites[id] = OpenFileAndGetFileDataPtr(name, &gMonsterFileArchive);
|
|
}
|
|
}
|
|
|
|
void LoadPokemonSprite(s32 _id, bool32 _ignoreDeoxys)
|
|
{
|
|
s32 id = (s16) _id;
|
|
bool8 ignoreDeoxys = _ignoreDeoxys;
|
|
|
|
if (!ignoreDeoxys && (id == MONSTER_DEOXYS_NORMAL || id == MONSTER_DEOXYS_ATTACK || id == MONSTER_DEOXYS_DEFENSE || id == MONSTER_DEOXYS_SPEED)) {
|
|
EnsureDeoxysLoaded();
|
|
}
|
|
else {
|
|
s16 idS16;
|
|
|
|
EnsureSpriteLoaded(id);
|
|
idS16 = id;
|
|
if (idS16 == MONSTER_CASTFORM || IS_CASTFORM_FORM_MONSTER(idS16))
|
|
EnsureCastformLoaded();
|
|
}
|
|
}
|
|
|
|
static void EnsureCastformLoaded(void)
|
|
{
|
|
EnsureSpriteLoaded(MONSTER_CASTFORM);
|
|
EnsureSpriteLoaded(MONSTER_CASTFORM_SNOWY);
|
|
EnsureSpriteLoaded(MONSTER_CASTFORM_SUNNY);
|
|
EnsureSpriteLoaded(MONSTER_CASTFORM_RAINY);
|
|
}
|
|
|
|
static void EnsureDeoxysLoaded(void)
|
|
{
|
|
EnsureSpriteLoaded(gDungeon->deoxysForm);
|
|
}
|
|
|
|
void CloseAllSpriteFiles(void)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < MONSTER_MAX; i++) {
|
|
TRY_CLOSE_FILE_AND_SET_NULL(gDungeon->sprites[i]);
|
|
}
|
|
}
|
|
|
|
void SetDungeonMonsFromTeam(void)
|
|
{
|
|
s32 index;
|
|
s32 recruitedId;
|
|
|
|
index = 0;
|
|
for (recruitedId = 0; recruitedId < NUM_MONSTERS; recruitedId++) {
|
|
Pokemon lvl1Mon;
|
|
Pokemon *pokeStruct = &gRecruitedPokemonRef->pokemon[recruitedId];
|
|
if (PokemonExists(pokeStruct) && PokemonIsOnTeam(pokeStruct)) {
|
|
RecruitedPokemonToDungeonMon(&gRecruitedPokemonRef->dungeonTeam[index],recruitedId);
|
|
if (IsLevelResetDungeon(gDungeon->unk644.dungeonLocation.id)) {
|
|
DungeonLocation dungeonLoc = { .id = DUNGEON_TINY_WOODS, .floor = 1 };
|
|
CreateLevel1Pokemon(&lvl1Mon,pokeStruct->speciesNum,0,0,&dungeonLoc,0);
|
|
gRecruitedPokemonRef->dungeonTeam[index].level = lvl1Mon.level;
|
|
gRecruitedPokemonRef->dungeonTeam[index].IQ = lvl1Mon.IQ;
|
|
gRecruitedPokemonRef->dungeonTeam[index].unk10 = lvl1Mon.pokeHP;
|
|
gRecruitedPokemonRef->dungeonTeam[index].unk12 = lvl1Mon.pokeHP;
|
|
gRecruitedPokemonRef->dungeonTeam[index].offense.att[0] = lvl1Mon.offense.att[0];
|
|
gRecruitedPokemonRef->dungeonTeam[index].offense.att[1] = lvl1Mon.offense.att[1];
|
|
gRecruitedPokemonRef->dungeonTeam[index].offense.def[0] = lvl1Mon.offense.def[0];
|
|
gRecruitedPokemonRef->dungeonTeam[index].offense.def[1] = lvl1Mon.offense.def[1];
|
|
gRecruitedPokemonRef->dungeonTeam[index].currExp = lvl1Mon.currExp;
|
|
gRecruitedPokemonRef->dungeonTeam[index].IQSkills = lvl1Mon.IQSkills;
|
|
gRecruitedPokemonRef->dungeonTeam[index].tacticIndex = lvl1Mon.tacticIndex;
|
|
CopyAndResetMoves(&gRecruitedPokemonRef->dungeonTeam[index].moves, lvl1Mon.moves);
|
|
}
|
|
gRecruitedPokemonRef->dungeonTeam[index].unkC = index;
|
|
if (++index == MAX_TEAM_MEMBERS)
|
|
break;
|
|
}
|
|
}
|
|
for (; index < MAX_TEAM_MEMBERS; index++) {
|
|
gRecruitedPokemonRef->dungeonTeam[index].flags = 0;
|
|
}
|
|
}
|
|
|
|
void sub_8068A84(Pokemon *pokemon)
|
|
{
|
|
s32 i, totalBodySize;
|
|
|
|
totalBodySize = 0;
|
|
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
|
|
DungeonMon *ptr = &gRecruitedPokemonRef->dungeonTeam[i];
|
|
if (DungeonMonExists(ptr)) {
|
|
totalBodySize += GetBodySize(ptr->speciesNum);
|
|
}
|
|
}
|
|
|
|
totalBodySize += GetBodySize(pokemon->speciesNum);
|
|
if (totalBodySize >= 7) {
|
|
PrintColoredPokeNameToBuffer(gFormatBuffer_Monsters[0],pokemon,0);
|
|
if (pokemon->dungeonLocation.id == DUNGEON_JOIN_LOCATION_CLIENT_POKEMON) {
|
|
DisplayDungeonMessage_Async(0,gUnknown_80FE0F4,1);
|
|
}
|
|
else if (pokemon->dungeonLocation.id == DUNGEON_RESCUE_TEAM_BASE) {
|
|
DisplayDungeonMessage_Async(0,gUnknown_80FE0F8,1);
|
|
}
|
|
else {
|
|
DisplayDungeonMessage_Async(0,gUnknown_80FE0AC,1);
|
|
}
|
|
}
|
|
else {
|
|
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
|
|
DungeonMon *monPtr = &gRecruitedPokemonRef->dungeonTeam[i];
|
|
if (!DungeonMonExists(monPtr)) {
|
|
PokemonToDungeonMon(monPtr,pokemon,0x55aa);
|
|
monPtr->flags |= POKEMON_FLAG_EXISTS;
|
|
if (monPtr->IQ < 0x1a) {
|
|
monPtr->IQ = 0x1a;
|
|
}
|
|
monPtr->flags |= 2;
|
|
monPtr->unkC = i;
|
|
ZeroOutItem(&monPtr->itemSlot);
|
|
PrintColoredPokeNameToBuffer(gFormatBuffer_Monsters[0],pokemon,6);
|
|
if (pokemon->dungeonLocation.id == DUNGEON_JOIN_LOCATION_CLIENT_POKEMON) {
|
|
DisplayDungeonMessage_Async(0,gUnknown_80FE168,1);
|
|
}
|
|
else if (pokemon->dungeonLocation.id == DUNGEON_RESCUE_TEAM_BASE) {
|
|
;
|
|
}
|
|
else {
|
|
DisplayDungeonMessage_Async(0,gUnknown_80FE134,1);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
PrintColoredPokeNameToBuffer(gFormatBuffer_Monsters[0],pokemon,6);
|
|
if (pokemon->dungeonLocation.id == DUNGEON_JOIN_LOCATION_CLIENT_POKEMON) {
|
|
DisplayDungeonMessage_Async(0,gUnknown_80FE0F4,1);
|
|
}
|
|
else if (pokemon->dungeonLocation.id == DUNGEON_RESCUE_TEAM_BASE) {
|
|
DisplayDungeonMessage_Async(0,gUnknown_80FE0F8,1);
|
|
}
|
|
else {
|
|
DisplayDungeonMessage_Async(0,gUnknown_80FE0AC,1);
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline bool8 IsUnkDungeon(u8 joinedDungeon)
|
|
{
|
|
if (joinedDungeon == DUNGEON_POKEMON_SQUARE || joinedDungeon == DUNGEON_HOWLING_FOREST_2)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
void sub_8068BDC(bool8 a0)
|
|
{
|
|
bool8 spArr[FRIEND_AREA_COUNT];
|
|
Pokemon *monPointers[21];
|
|
Pokemon mon1Structs[MAX_TEAM_MEMBERS];
|
|
u16 arr2[18];
|
|
FriendAreaCapacity areaCapacity;
|
|
s32 i, j, id;
|
|
|
|
for (i = 0; i < FRIEND_AREA_COUNT; i++) {
|
|
spArr[i] = FALSE;
|
|
}
|
|
|
|
for (id = 0; id < MAX_TEAM_MEMBERS; id++) {
|
|
DungeonMon *monPtr = &gRecruitedPokemonRef->dungeonTeam[id];
|
|
if (DungeonMonExists(monPtr) && !sub_806A564(monPtr->recruitedPokemonId)) {
|
|
Item *monItem = &monPtr->itemSlot;
|
|
if (ItemExists(monItem) && monItem->id == ITEM_POKE) {
|
|
AddToTeamMoney(GetMoneyValue(monItem));
|
|
ZeroOutItem(monItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (id = 0; id < MAX_TEAM_MEMBERS; id++) {
|
|
DungeonMon *monPtr = &gRecruitedPokemonRef->dungeonTeam[id];
|
|
if (DungeonMonExists(monPtr) && !sub_806A564(monPtr->recruitedPokemonId)) {
|
|
if (IS_CASTFORM_FORM_MONSTER(monPtr->speciesNum)) {
|
|
monPtr->speciesNum = MONSTER_CASTFORM;
|
|
}
|
|
|
|
if (sub_806A58C(monPtr->recruitedPokemonId)) {
|
|
if (IsLevelResetDungeon(gDungeon->unk644.dungeonLocation.id)) {
|
|
sub_808DFDC(monPtr->recruitedPokemonId, monPtr);
|
|
}
|
|
else {
|
|
DungeonMonToRecruitedPokemon(monPtr->recruitedPokemonId, monPtr);
|
|
}
|
|
}
|
|
else {
|
|
if (a0) {
|
|
spArr[GetFriendArea(monPtr->speciesNum)] = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < FRIEND_AREA_COUNT; i++) {
|
|
u8 friendAreaId = i;
|
|
if (!spArr[friendAreaId])
|
|
continue;
|
|
|
|
sub_8092404(friendAreaId, arr2, TRUE, TRUE);
|
|
GetFriendAreaCapacity2(friendAreaId, &areaCapacity, FALSE, FALSE);
|
|
for (j = 0; j < 21 && arr2[j] != 0xFFFF; j++) {
|
|
monPointers[j] = &gRecruitedPokemonRef->pokemon[arr2[j]];
|
|
}
|
|
|
|
for (id = 0; id < MAX_TEAM_MEMBERS; id++) {
|
|
DungeonMon *monPtr = &gRecruitedPokemonRef->dungeonTeam[id];
|
|
if (DungeonMonExists(monPtr) && sub_806A5A4(monPtr->recruitedPokemonId) && GetFriendArea(monPtr->speciesNum) == friendAreaId && a0) {
|
|
monPointers[j] = &mon1Structs[id];
|
|
DungeonMonToPokemon(monPointers[j], monPtr);
|
|
monPointers[j]->flags |= POKEMON_FLAG_x4000;
|
|
monPointers[j]->unkC[0].level = 0;
|
|
monPointers[j]->unkC[1].level = 0;
|
|
j++;
|
|
}
|
|
}
|
|
|
|
if (j <= areaCapacity.maxPokemon) {
|
|
s32 k;
|
|
for (k = 0; k < j; k++) {
|
|
if (monPointers[k]->flags & POKEMON_FLAG_x4000) {
|
|
TryAddPokemonToRecruited(monPointers[k]);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
WriteFriendAreaName(gFormatBuffer_Items[0], friendAreaId, FALSE);
|
|
DisplayDungeonMessage_Async(NULL, gUnknown_80FE1A4, TRUE); // The Friend Area is full, a friend must be released.
|
|
while (TRUE) {
|
|
ShowRecruitReleaseMenu(friendAreaId, j - areaCapacity.maxPokemon, j, monPointers);
|
|
for (id = 0; id < j; id++) {
|
|
Pokemon *monPtr = monPointers[id];
|
|
if (PokemonExists(monPtr) && (monPtr->flags & POKEMON_FLAG_x8000)) {
|
|
if (IsUnkDungeon(monPtr->dungeonLocation.id)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (id == j)
|
|
break;
|
|
if (DisplayDungeonYesNoMessage_Async(NULL, gUnknown_80FE20C, TRUE) == TRUE) // If you dismiss this mon, it may never join you again. Bid farewell to it?
|
|
break;
|
|
}
|
|
|
|
for (id = 0; id < j; id++) {
|
|
if (PokemonExists(monPointers[id]) && (monPointers[id]->flags & POKEMON_FLAG_x8000)) {
|
|
monPointers[id]->flags = 0;
|
|
}
|
|
}
|
|
for (id = 0; id < j; id++) {
|
|
if (PokemonExists(monPointers[id]) && (monPointers[id]->flags & POKEMON_FLAG_x4000)) {
|
|
TryAddPokemonToRecruited(monPointers[id]);
|
|
monPointers[id]->flags = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_8068F28(void)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
|
|
DungeonMon *monStruct2Ptr = &gRecruitedPokemonRef->dungeonTeam[i];
|
|
if (DungeonMonExists(monStruct2Ptr)) {
|
|
if (sub_806A564(monStruct2Ptr->recruitedPokemonId)) {
|
|
monStruct2Ptr->flags = 0;
|
|
}
|
|
else if (sub_806A538(monStruct2Ptr->recruitedPokemonId)) {
|
|
monStruct2Ptr->flags = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_8068F80(void)
|
|
{
|
|
Entity *leader = GetLeader();
|
|
Dungeon *dungeon = gDungeon;
|
|
|
|
dungeon->unk644.unk28 = 0;
|
|
dungeon->unk644.unk29 = 0;
|
|
dungeon->unk644.unk2F = 0;
|
|
dungeon->unkC0.type = ENTITY_NOTHING;
|
|
if (leader != NULL) {
|
|
bool8 isShop = (GetTileAtEntitySafe(leader)->terrainFlags & TERRAIN_TYPE_SHOP) != 0;
|
|
dungeon->unk644.unk54 = isShop;
|
|
dungeon->unk644.unk55 = isShop;
|
|
DiscoverMinimap(&leader->pos);
|
|
}
|
|
}
|
|
|
|
static inline void ClearOnTeamFlag(Pokemon *mon)
|
|
{
|
|
mon->flags &= ~(POKEMON_FLAG_ON_TEAM);
|
|
}
|
|
|
|
static inline void ClearMonItemId(Pokemon *mon)
|
|
{
|
|
mon->heldItem.id = ITEM_NOTHING;
|
|
}
|
|
|
|
void HandleFaint_Async(Entity *entity, s32 dungeonExitReason_, Entity *param_3)
|
|
{
|
|
u16 joinId;
|
|
Entity EStack_a4;
|
|
s32 i;
|
|
s32 dungeonExitReason = (s16) dungeonExitReason_;
|
|
EntityInfo *entInfo = GetEntInfo(entity);
|
|
Tile *tile = GetTileAtEntitySafe(entity);
|
|
if (param_3 == NULL) {
|
|
sub_80457DC(&EStack_a4);
|
|
param_3 = &EStack_a4;
|
|
}
|
|
if (tile->monster == entity) {
|
|
tile->monster = NULL;
|
|
}
|
|
|
|
DrawMinimapTile(entity->pos.x,entity->pos.y);
|
|
|
|
for (i = 0; i < DUNGEON_MAX_POKEMON; i++) {
|
|
Entity *mon = gDungeon->activePokemon[i];
|
|
if (mon != NULL && EntityIsValid(mon)) {
|
|
EntityInfo *info = GetEntInfo(mon);
|
|
if (info->aiTarget.aiTarget == entity) {
|
|
info->aiTarget.aiTarget = NULL;
|
|
}
|
|
}
|
|
}
|
|
if (entInfo->curseClassStatus.status == STATUS_DECOY) {
|
|
gDungeon->decoyIsActive = FALSE;
|
|
}
|
|
if (entInfo->frozenClassStatus.status == STATUS_WRAP || entInfo->frozenClassStatus.status == STATUS_WRAPPED) {
|
|
sub_8076CB4(entInfo->unk9C);
|
|
}
|
|
|
|
sub_8078084(entity);
|
|
entity->unk22 = 0;
|
|
entity->isVisible = FALSE;
|
|
gLeaderPointer = NULL;
|
|
joinId = entInfo->joinedAt.id;
|
|
if (joinId == DUNGEON_JOIN_LOCATION_PARTNER && !gDungeon->unk644.canChangeLeader) {
|
|
gDungeon->unk10 = 1;
|
|
entInfo->HP = 0;
|
|
SubstitutePlaceholderStringTags(gDungeon->faintStringBuffer,entity,0);
|
|
return;
|
|
}
|
|
|
|
#ifndef NONMATCHING
|
|
// Yeah, this is just agbcc at its finest...
|
|
joinId = entity->isVisible; joinId = entity->unk22;joinId = entity->isVisible; joinId = entity->unk22;joinId = entity->isVisible; joinId = entity->unk22;
|
|
#endif
|
|
if (entInfo->isTeamLeader) {
|
|
DungeonWaitFrames_Async(0x3c,0x49);
|
|
DisplayMessageLog();
|
|
if (gDungeon->unk6 == 0) {
|
|
if (gDungeon->unk644.stoleFromKecleon == 0
|
|
&& dungeonExitReason != DUNGEON_EXIT_DELETED_FOR_EVENT
|
|
&& dungeonExitReason != DUNGEON_EXIT_FAILED_TO_PROTECT_CLIENT
|
|
&& dungeonExitReason != DUNGEON_EXIT_BLOWN_OUT_UNSEEN_FORCE
|
|
&& gDungeon->cutscene == CUTSCENE_NONE
|
|
&& gDungeon->unk644.unk37 >= 0
|
|
&& gDungeon->unk644.missionKind != DUNGEON_MISSION_OUTONRESCUE)
|
|
{
|
|
if (gDungeon->unk644.unk37 > 0) {
|
|
if (DisplayDungeonYesNoMessage_Async(NULL,gUnknown_80FE268,1) == 1) {
|
|
DisplayDungeonMessage_Async(NULL,gUnknown_80FE28C,1);
|
|
gDungeon->unk4 = 1;
|
|
gDungeon->unk6 = 1;
|
|
gDungeon->unk644.unk10 = 1;
|
|
gDungeon->unk644.unk37 -= 1;
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
DisplayDungeonMessage_Async(NULL,gUnknown_80FE2D0,1);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
gDungeon->unk4 = 1;
|
|
gDungeon->unk6 = 1;
|
|
gDungeon->unk644.unk10 = 1;
|
|
return;
|
|
}
|
|
|
|
SetUpDungeonExitData(dungeonExitReason,param_3,entity);
|
|
if (dungeonExitReason == DUNGEON_EXIT_RETURNED_WITH_FALLEN_PARTNER) {
|
|
EntityInfo *partnerInfo = NULL;
|
|
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
|
|
Entity *teamMon = gDungeon->teamPokemon[i];
|
|
if (EntityIsValid(teamMon)) {
|
|
partnerInfo = GetEntInfo(teamMon);
|
|
if (partnerInfo->joinedAt.id == DUNGEON_JOIN_LOCATION_PARTNER)
|
|
break;
|
|
}
|
|
}
|
|
if (partnerInfo != NULL) {
|
|
DungeonMon *partnerStruct = &gRecruitedPokemonRef->dungeonTeam[partnerInfo->teamIndex];
|
|
sub_806C264(partnerInfo->teamIndex,partnerInfo);
|
|
if (sub_806A58C(partnerStruct->recruitedPokemonId) != 0) {
|
|
if (IsLevelResetDungeon(gDungeon->unk644.dungeonLocation.id) == 0) {
|
|
DungeonMonToRecruitedPokemon(partnerStruct->recruitedPokemonId, partnerStruct);
|
|
}
|
|
if (!IsMakuhitaTrainingMaze()) {
|
|
ClearMonItemId(&gRecruitedPokemonRef->pokemon[partnerStruct->recruitedPokemonId]);
|
|
}
|
|
}
|
|
partnerStruct->flags = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (entInfo->isNotTeamMember) {
|
|
for (i = 0; i < entInfo->unk168; i++) {
|
|
gUnknown_202EE76[entInfo->unk167 + i] = 0;
|
|
}
|
|
}
|
|
else {
|
|
for (i = 0; i < entInfo->unk168; i++) {
|
|
gUnknown_202EE70[entInfo->unk167 + i] = 0;
|
|
}
|
|
}
|
|
|
|
if (entInfo->joinedAt.id == DUNGEON_JOIN_LOCATION_CLIENT_POKEMON) {
|
|
gDungeon->unk10 = 2;
|
|
SubstitutePlaceholderStringTags(gDungeon->faintStringBuffer,entity,0);
|
|
}
|
|
else if (entInfo->joinedAt.id == DUNGEON_RESCUE_TEAM_BASE) {
|
|
gDungeon->unk10 = 3;
|
|
SubstitutePlaceholderStringTags(gDungeon->faintStringBuffer,entity,0);
|
|
}
|
|
|
|
if (GetLeader() != NULL && dungeonExitReason != DUNGEON_EXIT_DELETED_FOR_EVENT && !entInfo->isTeamLeader && !gDungeon->unk10) {
|
|
HandleBossFaint_Async(entity, entInfo->monsterBehavior, dungeonExitReason == DUNGEON_EXIT_TRANSFORMED_INTO_FRIEND);
|
|
if (IS_DEOXYS_FORM_MONSTER(entInfo->apparentID) && !IsFloorwideFixedRoom() && entInfo->isNotTeamMember) {
|
|
gDungeon->deoxysDefeat = 1;
|
|
DisplayDungeonLoggableMessageTrue_Async(entity,gUnknown_80FA580);
|
|
sub_803E178();
|
|
UpdateTrapsVisibility();
|
|
}
|
|
}
|
|
|
|
if (!entInfo->isNotTeamMember) {
|
|
DungeonMon *mon2Ptr = &gRecruitedPokemonRef->dungeonTeam[entInfo->teamIndex];
|
|
sub_806C264(entInfo->teamIndex,entInfo);
|
|
if (sub_806A58C(mon2Ptr->recruitedPokemonId) != 0) {
|
|
bool8 uVar10;
|
|
|
|
if (IsLevelResetDungeon(gDungeon->unk644.dungeonLocation.id) == 0) {
|
|
DungeonMonToRecruitedPokemon(mon2Ptr->recruitedPokemonId, mon2Ptr);
|
|
}
|
|
if (!IsMakuhitaTrainingMaze()) {
|
|
ClearMonItemId(&gRecruitedPokemonRef->pokemon[mon2Ptr->recruitedPokemonId]);
|
|
}
|
|
|
|
uVar10 = FALSE;
|
|
if (entInfo->isTeamLeader) {
|
|
uVar10 = TRUE;
|
|
}
|
|
if (!gDungeon->unk644.canChangeLeader && entInfo->joinedAt.id == DUNGEON_JOIN_LOCATION_PARTNER) {
|
|
uVar10 = TRUE;
|
|
}
|
|
|
|
if (!uVar10) {
|
|
ClearOnTeamFlag(&gRecruitedPokemonRef->pokemon[mon2Ptr->recruitedPokemonId]);
|
|
}
|
|
}
|
|
mon2Ptr->flags = 0;
|
|
}
|
|
|
|
DeletePokemonDungeonSprite(entInfo->dungeonSpriteId);
|
|
gLeaderPointer = 0;
|
|
gDungeon->unkC = 1;
|
|
entity->type = ENTITY_NOTHING;
|
|
sub_8045ACC();
|
|
}
|
|
|
|
void sub_80694C0(Entity *target,s32 x,s32 y,u8 param_4)
|
|
{
|
|
Tile *tile;
|
|
Tile *tile2;
|
|
EntityInfo *info;
|
|
|
|
tile = GetTileMut(x,y);
|
|
info = GetEntInfo(target);
|
|
|
|
if (info->frozenClassStatus.status == STATUS_WRAP || info->frozenClassStatus.status == STATUS_WRAPPED) {
|
|
sub_8076CB4(info->unk9C);
|
|
}
|
|
if (info->frozenClassStatus.status == STATUS_CONSTRICTION || info->frozenClassStatus.status == STATUS_INGRAIN || info->frozenClassStatus.status == STATUS_SHADOW_HOLD) {
|
|
EndFrozenClassStatus(target,target);
|
|
}
|
|
if ((x != (target->pos).x) || (y != (target->pos).y)) {
|
|
if ((0 <= (target->pos).x) && (0 <= (target->pos).y)) {
|
|
tile2 = GetTileMut((target->pos).x,(target->pos).y);
|
|
if (tile2->monster == target) {
|
|
tile2->monster = NULL;
|
|
}
|
|
DrawMinimapTile((target->pos).x,(target->pos).y);
|
|
}
|
|
(target->prevPos).x = (target->pos).x;
|
|
(target->prevPos).y = (target->pos).y;
|
|
(target->pos).x = x;
|
|
(target->pos).y = y;
|
|
if (info->isTeamLeader) {
|
|
gPlayerDotMapPosition.x = x;
|
|
gPlayerDotMapPosition.y = y;
|
|
}
|
|
tile->monster = target;
|
|
if (info->isTeamLeader) {
|
|
gLeaderPosition.x = x;
|
|
gLeaderPosition.y = y;
|
|
gDungeon->unk1 = 0;
|
|
}
|
|
DrawMinimapTile(x,y);
|
|
|
|
switch(param_4)
|
|
{
|
|
case 0:
|
|
info->prevPos[3] = info->prevPos[2];
|
|
info->prevPos[2] = info->prevPos[1];
|
|
info->prevPos[1] = info->prevPos[0];
|
|
if (info->invisibleClassStatus.status != 1) {
|
|
info->prevPos[0] = target->prevPos;
|
|
}
|
|
break;
|
|
case 1:
|
|
info->prevPos[0] = target->pos;
|
|
info->prevPos[1] = info->prevPos[0];
|
|
info->prevPos[2] = info->prevPos[0];
|
|
info->prevPos[3] = info->prevPos[0];
|
|
break;
|
|
}
|
|
target->room = tile->room;
|
|
DetermineMonsterShadow(target);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void sub_80695EC(Entity *param_1,s32 x,s32 y)
|
|
{
|
|
EntityInfo *info;
|
|
|
|
info = GetEntInfo(param_1);
|
|
if (info->frozenClassStatus.status == STATUS_WRAP || info->frozenClassStatus.status == STATUS_WRAPPED) {
|
|
sub_8076CB4(info->unk9C);
|
|
}
|
|
if ((x != (param_1->pos).x) || (y != (param_1->pos).y)) {
|
|
param_1->prevPos.x = param_1->pos.x;
|
|
param_1->prevPos.y = param_1->pos.y;
|
|
param_1->pos.x = x;
|
|
param_1->pos.y = y;
|
|
info->prevPos[3] = info->prevPos[2];
|
|
info->prevPos[2] = info->prevPos[1];
|
|
info->prevPos[1] = info->prevPos[0];
|
|
if (info->invisibleClassStatus.status != 1) {
|
|
info->prevPos[0] = param_1->prevPos;
|
|
}
|
|
param_1->room = GetTile(x,y)->room;
|
|
}
|
|
}
|
|
|
|
Entity * sub_8069660(Entity *target)
|
|
{
|
|
const Tile *tile;
|
|
|
|
EntityInfo *info;
|
|
|
|
info = GetEntInfo(target);
|
|
|
|
if(sub_8070F80(target, info->action.direction))
|
|
{
|
|
tile = GetTile((target->pos).x + (gAdjacentTileOffsets)[info->action.direction].x,(target->pos).y + (gAdjacentTileOffsets)[info->action.direction].y);
|
|
return tile->monster;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
Entity * sub_80696A8(Entity *target)
|
|
{
|
|
const Tile *tile;
|
|
Entity *entity;
|
|
|
|
EntityInfo *info;
|
|
|
|
info = GetEntInfo(target);
|
|
|
|
if(CanAttackInDirection(target, info->action.direction))
|
|
{
|
|
tile = GetTile((target->pos).x + (gAdjacentTileOffsets)[info->action.direction].x,(target->pos).y + (gAdjacentTileOffsets)[info->action.direction].y);
|
|
if (((entity = tile->monster, entity != NULL)) && (entity->type == ENTITY_MONSTER)) {
|
|
return entity;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
Entity * sub_80696FC(Entity *target)
|
|
{
|
|
const Tile *tile;
|
|
Entity *entity;
|
|
|
|
DungeonPos pos;
|
|
EntityInfo *info;
|
|
|
|
info = GetEntInfo(target);
|
|
|
|
pos.x = (target->pos).x + (gAdjacentTileOffsets)[info->action.direction].x;
|
|
pos.y = (target->pos).y + (gAdjacentTileOffsets)[info->action.direction].y;
|
|
tile = GetTile(pos.x,pos.y);
|
|
if (((!sub_80705F0(target,&pos)) && (entity = tile->monster, entity != NULL)) && (entity->type == ENTITY_MONSTER)) {
|
|
return entity;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
Entity * sub_806977C(Entity *target)
|
|
{
|
|
const Tile *tile;
|
|
Entity *entity;
|
|
|
|
DungeonPos pos;
|
|
EntityInfo *info;
|
|
|
|
info = GetEntInfo(target);
|
|
|
|
pos.x = (target->pos).x + (gAdjacentTileOffsets)[info->action.direction].x;
|
|
pos.y = (target->pos).y + ((gAdjacentTileOffsets)[info->action.direction].y);
|
|
GetTile(pos.x,(int)pos.y);
|
|
if (!sub_80705F0(target,&pos)) {
|
|
pos.x = (gAdjacentTileOffsets)[info->action.direction].x * 2 + (target->pos).x;
|
|
pos.y = (gAdjacentTileOffsets)[info->action.direction].y * 2 + (target->pos).y;
|
|
tile = GetTile(pos.x,pos.y);
|
|
if (((!sub_80705F0(target,&pos)) && (entity = tile->monster, entity != NULL)) && (entity->type == ENTITY_MONSTER)) {
|
|
return entity;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void SetMonSummaryInfoFromEntity(MonSummaryInfo *param_1, Entity *target)
|
|
{
|
|
s32 index;
|
|
u8 *atkPtr;
|
|
u8 *spAtkPtr;
|
|
u8 *defPtr;
|
|
s32 uVar15;
|
|
u8 *spDefBoost;
|
|
|
|
EntityInfo *info = GetEntInfo(target);
|
|
|
|
SetMessageArgument_2(param_1->nameBuffer, info, 0);
|
|
param_1->species = info->id;
|
|
param_1->HP1 = info->HP;
|
|
param_1->HP2 = info->maxHPStat;
|
|
param_1->level = info->level;
|
|
param_1->exp = info->exp;
|
|
for(index = 0; index < 2; index++)
|
|
{
|
|
(param_1->offense).att[index] = info->atk[index];
|
|
(param_1->offense).def[index] = info->def[index];
|
|
param_1->types[index] = info->types[index];
|
|
param_1->abilities[index] = info->abilities[index];
|
|
}
|
|
param_1->isTeamLeader = info->isTeamLeader;
|
|
atkPtr = ¶m_1->atkBoost;
|
|
*atkPtr = 0;
|
|
spAtkPtr = ¶m_1->spAtkBoost;
|
|
*spAtkPtr = 0;
|
|
defPtr = ¶m_1->defBoost;
|
|
*defPtr = 0;
|
|
spDefBoost = ¶m_1->spDefBoost;
|
|
*spDefBoost = 0;
|
|
if ((info->heldItem.flags & ITEM_FLAG_EXISTS) && ((info->heldItem.flags & ITEM_FLAG_STICKY) == 0)) {
|
|
if (info->heldItem.id == ITEM_POWER_BAND) {
|
|
*atkPtr += gPowerBandBoost;
|
|
}
|
|
if (info->heldItem.id == ITEM_MUNCH_BELT) {
|
|
*atkPtr += gMunchBeltBoost;
|
|
}
|
|
if (info->heldItem.id == ITEM_SPECIAL_BAND) {
|
|
*spAtkPtr += gSpecialBandBoost;
|
|
}
|
|
if (info->heldItem.id == ITEM_MUNCH_BELT) {
|
|
*spAtkPtr += gMunchBeltBoost;
|
|
}
|
|
if (info->heldItem.id == ITEM_DEF_SCARF) {
|
|
*defPtr += gDefScarfBoost;
|
|
}
|
|
if (info->heldItem.id == ITEM_ZINC_BAND) {
|
|
*spDefBoost += gZincBandBoost;
|
|
}
|
|
}
|
|
param_1->tactic = info->tactic;
|
|
param_1->item = info->heldItem;
|
|
param_1->IQ = info->IQ;
|
|
(param_1->dungeonLocation) = info->joinedAt;
|
|
param_1->unk44[0].level = 0;
|
|
param_1->unk44[1].level = 0;
|
|
param_1->IQSkills = info->IQSkillMenuFlags;
|
|
if (gDungeon->unk644.unlockedEvolutions) {
|
|
param_1->evoStringId = sub_806A4DC(info);
|
|
}
|
|
else {
|
|
param_1->evoStringId = EVO_STRING_EMPTY;
|
|
}
|
|
|
|
uVar15 = 0;
|
|
if (info->HP <= info->maxHPStat / 4) {
|
|
param_1->unk58[0] = 6;
|
|
uVar15 = 1;
|
|
}
|
|
|
|
if (gDungeon->unk644.itemHoldersIdentified) {
|
|
param_1->unk58[uVar15] = 11;
|
|
uVar15++;
|
|
}
|
|
if (FixedPointToInt(info->belly) == 0) {
|
|
if (info->isTeamLeader) {
|
|
param_1->unk58[uVar15] = 19;
|
|
}
|
|
else {
|
|
param_1->unk58[uVar15] = 59;
|
|
}
|
|
|
|
uVar15++;
|
|
}
|
|
if (GetEntInfo(target)->speedStage > 1) {
|
|
param_1->unk58[uVar15] = 27;
|
|
uVar15++;
|
|
}
|
|
if (GetEntInfo(target)->speedStage < 1) {
|
|
param_1->unk58[uVar15] = 40;
|
|
uVar15++;
|
|
}
|
|
if ((((((info->offensiveMultipliers[0] < 0x100) || (info->offensiveMultipliers[1] < 0x100)
|
|
) || (info->defensiveMultipliers[0] < 0x100)) ||
|
|
((info->defensiveMultipliers[1] < 0x100 || (info->offensiveStages[0] < 10)))) ||
|
|
((info->offensiveStages[1] < 10 ||
|
|
((info->defensiveStages[0] < 10 || (info->defensiveStages[1] < 10)))))) ||
|
|
((info->hitChanceStages[0] < 10 || (info->hitChanceStages[1] < 10)))) {
|
|
param_1->unk58[uVar15] = 55;
|
|
uVar15++;
|
|
}
|
|
if (((info->sleepClassStatus).status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = (info->sleepClassStatus).status;
|
|
uVar15++;
|
|
}
|
|
if (((info->burnClassStatus).status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = (info->burnClassStatus).status + 6;
|
|
uVar15++;
|
|
}
|
|
if (((info->frozenClassStatus).status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = (info->frozenClassStatus).status + 11;
|
|
uVar15++;
|
|
}
|
|
if (((info->cringeClassStatus).status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = (info->cringeClassStatus).status + 19;
|
|
uVar15++;
|
|
}
|
|
if (((info->bideClassStatus).status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = (info->bideClassStatus).status + 27;
|
|
uVar15++;
|
|
}
|
|
if (((info->reflectClassStatus).status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = (info->reflectClassStatus).status + 40;
|
|
uVar15++;
|
|
}
|
|
if (((info->curseClassStatus).status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = (info->curseClassStatus).status + 55;
|
|
uVar15++;
|
|
}
|
|
if (((info->leechSeedClassStatus).status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = (info->leechSeedClassStatus).status + 59;
|
|
uVar15++;
|
|
}
|
|
if (((info->sureShotClassStatus).status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = info->sureShotClassStatus.status + 62;
|
|
uVar15++;
|
|
}
|
|
if (((info->longTossClassStatus).status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = info->longTossClassStatus.status + 67;
|
|
uVar15++;
|
|
}
|
|
if ((info->invisibleClassStatus.status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = info->invisibleClassStatus.status + 70;
|
|
uVar15++;
|
|
}
|
|
if ((info->blinkerClassStatus.status != STATUS_NONE) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = info->blinkerClassStatus.status + 74;
|
|
uVar15++;
|
|
}
|
|
if ((info->muzzled.muzzled) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = info->muzzled.muzzled + 78;
|
|
uVar15++;
|
|
}
|
|
if ((info->stockpileStage != 0) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = 80;
|
|
uVar15++;
|
|
}
|
|
if ((info->powerEars) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = 81;
|
|
uVar15++;
|
|
}
|
|
if ((info->scanning) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = 82;
|
|
uVar15++;
|
|
}
|
|
if ((info->grudge) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = 83;
|
|
uVar15++;
|
|
}
|
|
if ((info->exposed) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = 84;
|
|
uVar15++;
|
|
}
|
|
if ((ShouldMonsterRunAway(target)) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = 85;
|
|
uVar15++;
|
|
}
|
|
if ((info->perishSongTurns != 0) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = 86;
|
|
uVar15++;
|
|
}
|
|
if ((1 < sub_8070828(target,FALSE)) && (uVar15 < 0xc)) {
|
|
param_1->unk58[uVar15] = 87;
|
|
uVar15++;
|
|
}
|
|
if (info->stairSpotter) {
|
|
if (0xb < uVar15) {
|
|
return;
|
|
}
|
|
param_1->unk58[uVar15] = 88;
|
|
uVar15++;
|
|
}
|
|
|
|
for(; uVar15 < 0xC; uVar15++)
|
|
{
|
|
param_1->unk58[uVar15] = 0;
|
|
}
|
|
return;
|
|
}
|
|
|
|
bool8 sub_8069D18(DungeonPos *pos,Entity *entity)
|
|
{
|
|
EntityInfo *info;
|
|
|
|
info = GetEntInfo(entity);
|
|
|
|
pos->x = entity->pos.x + gAdjacentTileOffsets[info->action.direction].x;
|
|
pos->y = entity->pos.y + gAdjacentTileOffsets[info->action.direction].y;
|
|
return info->action.direction & 1;
|
|
}
|
|
|
|
void sub_8069D4C(struct unkStruct_8069D4C *r0, Entity *target)
|
|
{
|
|
EntityInfo *info;
|
|
LevelData leveldata;
|
|
|
|
info = GetEntInfo(target);
|
|
|
|
r0->id = info->id;
|
|
r0->pos = target->pos;
|
|
|
|
if(info->bossFlag)
|
|
r0->HP = info->originalHP;
|
|
else
|
|
r0->HP = info->maxHPStat;
|
|
|
|
r0->level = info->level;
|
|
|
|
GetLvlUpEntry(&leveldata, info->id, info->level);
|
|
r0->exp = leveldata.expRequired;
|
|
r0->att[0] = info->atk[0];
|
|
r0->att[1] = info->atk[1];
|
|
r0->def[0] = info->def[0];
|
|
r0->def[1] = info->def[1];
|
|
r0->heldItem = info->heldItem;
|
|
memcpy(r0->moves.moves, info->moves.moves, sizeof(r0->moves));
|
|
r0->belly = info->belly;
|
|
r0->maxBelly = info->maxBelly;
|
|
r0->hiddenPower = info->hiddenPower;
|
|
}
|
|
|
|
void TargetTileInFront(Entity *pokemon)
|
|
{
|
|
EntityInfo *pokemonInfo = GetEntInfo(pokemon);
|
|
pokemonInfo->targetPos.x = pokemon->pos.x + gAdjacentTileOffsets[pokemonInfo->action.direction].x;
|
|
pokemonInfo->targetPos.y = pokemon->pos.y + gAdjacentTileOffsets[pokemonInfo->action.direction].y;
|
|
}
|
|
|
|
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 TryActivateArtificialWeatherAbilities(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_Async(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_Async(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 = GetBestResistingType(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_Async(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 && (!ShouldDisplayEntity(pokemon))) {
|
|
TryPointCameraToMonster(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 && (!ShouldDisplayEntity(pokemon))) {
|
|
TryPointCameraToMonster(pokemon,1);
|
|
return;
|
|
}
|
|
else if (GetEntityType(target) == ENTITY_MONSTER) {
|
|
entityInfo = GetEntInfo(target);
|
|
isNotTeamMember = (!entityInfo->isNotTeamMember);
|
|
}
|
|
if (isNotTeamMember && (!ShouldDisplayEntity(target))) {
|
|
TryPointCameraToMonster(target,1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TryPointCameraToMonster(Entity *pokemon, u8 param_2)
|
|
{
|
|
if ((EntityIsValid(pokemon)) && (GetEntityType(pokemon) == ENTITY_MONSTER) && (gDungeon->unk181e8.cameraTarget != pokemon)) {
|
|
if (param_2 != '\0') {
|
|
sub_804178C_Async(TRUE);
|
|
while (gDungeon->unk12 < 0x3c) {
|
|
DungeonRunFrameActions(0x34);
|
|
}
|
|
}
|
|
DungeonWaitFrames_Async(4,0x44);
|
|
PointCameraToMonster(pokemon);
|
|
DiscoverMinimap(&pokemon->pos);
|
|
gDungeon->unk12 = 0;
|
|
}
|
|
}
|
|
|
|
void nullsub_95(Entity *pokemon)
|
|
{}
|
|
|
|
void ReevaluateSnatchMonster(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)->dungeonSpriteId;
|
|
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[4];
|
|
};
|
|
|
|
void sub_806A3D4(u8 *dst, s32 _a1, s32 id, bool32 _a3)
|
|
{
|
|
u8 fileName[12];
|
|
OpenedFile *file;
|
|
s32 a1 = (s16) (_a1);
|
|
bool8 a3 = _a3;
|
|
s32 mod;
|
|
struct UnkTalkFileStruct *strPtr;
|
|
|
|
if (a3) {
|
|
sprintf(fileName, "talkp%d", (s16) (a1 / 10));
|
|
}
|
|
else {
|
|
sprintf(fileName, "talk%d", (s16) (a1 / 10));
|
|
}
|
|
|
|
file = OpenFileAndGetFileDataPtr(fileName, &gDungeonFileArchive);
|
|
|
|
mod = (s16)(a1 % 10);
|
|
strPtr = ((struct UnkTalkFileStruct *)(file->data));
|
|
strcpy(dst, strPtr[mod].strings[id]);
|
|
CloseFile(file);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
// Evolution string related
|
|
s32 sub_806A4DC(EntityInfo *info)
|
|
{
|
|
Pokemon pokemon;
|
|
DungeonLocation loc;
|
|
|
|
loc.id = 0;
|
|
loc.floor = 1;
|
|
|
|
CreateLevel1Pokemon(&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 GetMonSummaryScreenEvoStringId(&pokemon);
|
|
}
|
|
|
|
bool8 sub_806A538(s16 r0)
|
|
{
|
|
s32 r0_1 = Self_s16(r0);
|
|
if (r0 == UNK_RECRUITED_POKEMON_ID_55AA)
|
|
return TRUE;
|
|
if (r0 == UNK_RECRUITED_POKEMON_ID_5AA5)
|
|
return TRUE;
|
|
|
|
if (r0_1 >= 0)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
bool8 sub_806A564(s16 r0)
|
|
{
|
|
if (r0 == UNK_RECRUITED_POKEMON_ID_55AA)
|
|
return TRUE;
|
|
if (r0 == UNK_RECRUITED_POKEMON_ID_5AA5)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 sub_806A58C(s16 r0)
|
|
{
|
|
if (r0 >= 0 && r0 <= 0x19C)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 sub_806A5A4(s16 r0)
|
|
{
|
|
if (r0 < 0)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
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_Async(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) {
|
|
UpdateStatusIconFlags(entity);
|
|
}
|
|
}
|
|
else {
|
|
if (info->heldItem.id == ITEM_X_RAY_SPECS || info->unk64 == ITEM_X_RAY_SPECS) {
|
|
UpdateCamera(1);
|
|
UpdateMinimap();
|
|
}
|
|
}
|
|
TryWakeSleepingWildPokemon();
|
|
}
|
|
|
|
if (ItemExists(&info->heldItem)) {
|
|
info->unk64 = info->heldItem.id;
|
|
}
|
|
else {
|
|
info->unk64 = ITEM_NOTHING;
|
|
}
|
|
}
|
|
|
|
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_Async(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_Async(entity, gPtrLinkedMovesComeApartMessage);
|
|
}
|
|
else if (ret == 1) {
|
|
LogMessageByIdWithPopupCheckUser_Async(entity, gPtrLinkMoveOneUseWarningMessage);
|
|
}
|
|
else if (ret == 2) {
|
|
LogMessageByIdWithPopupCheckUser_Async(entity, gPtrLinkMoveTwoUsesWarningMessage);
|
|
}
|
|
}
|
|
}
|
|
|
|
// s16 again...
|
|
bool8 sub_806AA0C(s32 _species, bool32 _a1)
|
|
{
|
|
s32 species = (s16) _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;
|
|
DungeonMon *monStruct2Ptr = &gRecruitedPokemonRef->dungeonTeam[teamIndex];
|
|
|
|
if (gDungeon->unk11)
|
|
unkBool = TRUE;
|
|
else if (sub_806A564(monStruct2Ptr->recruitedPokemonId))
|
|
unkBool = TRUE;
|
|
else if (sub_806A58C(monStruct2Ptr->recruitedPokemonId))
|
|
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))
|
|
&& (IsMonsterSleeping(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;
|
|
}
|
|
}
|