mirror of
https://github.com/pret/pmd-red.git
synced 2026-07-18 16:53:54 -05:00
818 lines
23 KiB
C
818 lines
23 KiB
C
#include "global.h"
|
|
#include "globaldata.h"
|
|
#include "constants/tactic.h"
|
|
#include "dungeon_config.h"
|
|
#include "dungeon_leader.h"
|
|
#include "dungeon_message.h"
|
|
#include "code_8041AD0.h"
|
|
#include "code_8077274_1.h"
|
|
#include "constants/dungeon.h"
|
|
#include "dungeon_map_access.h"
|
|
#include "dungeon_misc.h"
|
|
#include "dungeon_random.h"
|
|
#include "dungeon_vram.h"
|
|
#include "dungeon_util.h"
|
|
#include "dungeon_spawns.h"
|
|
#include "dungeon_info.h"
|
|
#include "pokemon_3.h"
|
|
#include "code_805D8C8.h"
|
|
#include "structs/str_806B7F8.h"
|
|
#include "dungeon_logic.h"
|
|
#include "dungeon_strings.h"
|
|
#include "dungeon_menu_moves.h"
|
|
#include "code_806CD90.h"
|
|
#include "moves.h"
|
|
#include "structs/dungeon_entity.h"
|
|
#include "structs/map.h"
|
|
#include "structs/str_pokemon.h"
|
|
#include "structs/str_806B7F8.h"
|
|
#include "dungeon_pos_data.h"
|
|
|
|
EWRAM_DATA s32 gUnknown_202F31C[2] = {0, 0};
|
|
EWRAM_DATA s32 gUnknown_202F324[2] = {0, 0};
|
|
|
|
extern void ResetMonEntityData(EntityInfo *, u32);
|
|
void sub_8042A44(Entity *r0);
|
|
void sub_8083D78(void);
|
|
void sub_8083D58(void);
|
|
void sub_8072778(Entity *, Entity *, u8, u8);
|
|
bool8 sub_80725A4(Entity *, Entity *);
|
|
void GetUnlockedTacticFlags(u8 *tacticsBuffer, s32 pokeLevel);
|
|
void sub_807218C(Entity *);
|
|
|
|
extern void sub_8072B78(Entity *pokemon, Entity *target, s16 id);
|
|
extern s32 GetMovesLearnedAtLevel(u16* dst, s16 species, s32 level, s32 IQPoints);
|
|
|
|
void sub_8072B24(Entity *entity, Move *moves);
|
|
|
|
static const u8 gUnknown_8107010[8] = {0, 1, 1, 2, 1, 1, 0, 0};
|
|
static const u8 * const gUnknown_8107018[3] = {
|
|
_(""),
|
|
_("{WAIT_PRESS}\n"),
|
|
_("\n"),
|
|
};
|
|
|
|
static bool8 LevelUp(Entity *, Entity *, u8, u8);
|
|
|
|
void sub_8071D4C(Entity *pokemon, Entity *target, s32 exp)
|
|
{
|
|
s32 newExp;
|
|
s32 expDiff;
|
|
EntityInfo *info;
|
|
|
|
info = GetEntInfo(target);
|
|
if (info->level != 100) {
|
|
if (!IsExperienceLocked(info->joinedAt.id)) {
|
|
newExp = info->exp + exp;
|
|
if (9999998 < newExp) {
|
|
newExp = 9999999;
|
|
}
|
|
expDiff = newExp - info->exp;
|
|
if (expDiff != 0) {
|
|
info->expGainedInTurn += expDiff;
|
|
gDungeon->unkD = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnemyEvolution(Entity *entity)
|
|
{
|
|
int counter;
|
|
s16 *id;
|
|
Entity EStack_f4;
|
|
u8 tacticsBuffer1[NUM_TACTICS];
|
|
u8 tacticsBuffer2[NUM_TACTICS];
|
|
s16 idStack [20];
|
|
Entity *entityPtr; // 0xB4
|
|
s32 index;
|
|
|
|
entityPtr = entity;
|
|
if ((gDungeon->unkD != 0) && (gDungeon->unkD = 0, gDungeon->unk10 == 0)) {
|
|
if (!EntityIsValid(entityPtr)) {
|
|
sub_80457DC(&EStack_f4);
|
|
entityPtr = &EStack_f4;
|
|
}
|
|
for(index = 0; index < DUNGEON_MAX_POKEMON; index++)
|
|
{
|
|
EntityInfo *info;
|
|
bool8 flag = FALSE;
|
|
Entity *target = gDungeon->activePokemon[index];
|
|
s32 maxHP = 0;
|
|
u32 atk[2] = {0, 0};
|
|
u32 def[2] = {0, 0};
|
|
|
|
if (target == NULL)
|
|
continue;
|
|
if (!EntityIsValid(target))
|
|
continue;
|
|
|
|
info = GetEntInfo(target);
|
|
if (info->HP != 0) {
|
|
if (info->unkF9 != 0) {
|
|
info->unkF9 = 0;
|
|
}
|
|
else
|
|
{
|
|
s32 expGained = info->expGainedInTurn;
|
|
if (expGained != 0) {
|
|
if (info->isTeamLeader) {
|
|
GetUnlockedTacticFlags(tacticsBuffer1, info->level);
|
|
}
|
|
maxHP = info->maxHPStat;
|
|
atk[0] = info->atk[0];
|
|
atk[1] = info->atk[1];
|
|
def[0] = info->def[0];
|
|
def[1] = info->def[1];
|
|
if (info->level != 100) {
|
|
info->exp += expGained;
|
|
gFormatArgs[0] = expGained;
|
|
SetMessageArgument_2(gFormatBuffer_Monsters[0],info,0);
|
|
TryDisplayDungeonLoggableMessage3(entityPtr,target,gUnknown_80F9E64); // $m0 gained $d0 Exp Points
|
|
flag = LevelUp(entityPtr,target,1,1);
|
|
}
|
|
}
|
|
if (info->unk149 != 0) {
|
|
s32 numMons = sub_808E400(info->id, idStack, FALSE, FALSE);
|
|
if (numMons != 0) {
|
|
s32 randIndex = DungeonRandInt(numMons);
|
|
for(counter = 0; counter < numMons; counter++)
|
|
{
|
|
id = &idStack[randIndex];
|
|
if ((CanMonsterBeSpawnedHere(*id) != 0) && (GetSpriteData(*id) != NULL)) {
|
|
sub_8072B78(entityPtr,target,*id);
|
|
break;
|
|
}
|
|
randIndex++;
|
|
if (randIndex >= numMons) {
|
|
randIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
flag = FALSE;
|
|
}
|
|
if (flag && (!info->isNotTeamMember)) {
|
|
gFormatArgs[0] = info->maxHPStat - maxHP;
|
|
gFormatArgs[1] = info->atk[0] - atk[0];
|
|
gFormatArgs[2] = info->def[0] - def[0];
|
|
gFormatArgs[3] = info->atk[1] - atk[1];
|
|
gFormatArgs[4] = info->def[1] - def[1];
|
|
sub_807218C(target);
|
|
}
|
|
if ((expGained != 0) && (info->isTeamLeader)) {
|
|
s32 tacticIndex;
|
|
|
|
GetUnlockedTacticFlags(tacticsBuffer2,info->level);
|
|
for(tacticIndex = 0; tacticIndex < NUM_TACTICS; tacticIndex++)
|
|
{
|
|
if ((tacticsBuffer1[tacticIndex] == 0) && (tacticsBuffer2[tacticIndex] == 1)) {
|
|
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],target,0);
|
|
CopyTacticsNameToBuffer(gFormatBuffer_Items[0],tacticIndex);
|
|
TryDisplayDungeonLoggableMessage3(entityPtr,target,gUnknown_80FF730); // $i0 was added to $m0's list of usable tactics
|
|
}
|
|
}
|
|
}
|
|
}
|
|
info->expGainedInTurn = 0;
|
|
info->unk149 = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_8072008(Entity *pokemon, Entity *target, s32 level, u8 param_4, u8 param_5)
|
|
{
|
|
bool8 flag;
|
|
s32 newLevel;
|
|
EntityInfo *info;
|
|
s32 tacticIndex;
|
|
LevelData leveldata;
|
|
u8 tacticsBuffer1 [NUM_TACTICS];
|
|
u8 tacticsBuffer2 [NUM_TACTICS];
|
|
s32 maxHP;
|
|
u32 atk[2];
|
|
u32 def[2];
|
|
|
|
if (EntityIsValid(target)) {
|
|
flag = 0;
|
|
info = GetEntInfo(target);
|
|
if (info->isTeamLeader) {
|
|
GetUnlockedTacticFlags(tacticsBuffer1,info->level);
|
|
}
|
|
maxHP = info->maxHPStat;
|
|
atk[0] = info->atk[0];
|
|
atk[1] = info->atk[1];
|
|
def[0] = info->def[0];
|
|
def[1] = info->def[1];
|
|
if (!IsExperienceLocked(info->joinedAt.id)) {
|
|
newLevel = info->level + level;
|
|
if (99 < newLevel) {
|
|
newLevel = 100;
|
|
}
|
|
if (newLevel != info->level) {
|
|
GetLvlUpEntry(&leveldata,info->id,newLevel);
|
|
info->exp = leveldata.expRequired;
|
|
flag |= (LevelUp(pokemon,target,param_4,param_5));
|
|
if ((flag != 0) && (!info->isNotTeamMember)) {
|
|
gFormatArgs[0] = info->maxHPStat - maxHP;
|
|
gFormatArgs[1] = info->atk[0] - atk[0];
|
|
gFormatArgs[2] = info->def[0] - def[0];
|
|
gFormatArgs[3] = info->atk[1] - atk[1];
|
|
gFormatArgs[4] = info->def[1] - def[1];
|
|
if (param_4 != 0) {
|
|
sub_807218C(target);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (info->isTeamLeader) {
|
|
GetUnlockedTacticFlags(tacticsBuffer2,info->level);
|
|
for(tacticIndex = 0; tacticIndex < NUM_TACTICS; tacticIndex++)
|
|
{
|
|
if ((tacticsBuffer1[tacticIndex] == 0) && (tacticsBuffer2[tacticIndex] == 1)) {
|
|
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],target,0);
|
|
CopyTacticsNameToBuffer(gFormatBuffer_Items[0],tacticIndex);
|
|
TryDisplayDungeonLoggableMessage3(pokemon,target,gUnknown_80FF730);
|
|
}
|
|
}
|
|
}
|
|
info->expGainedInTurn = 0;
|
|
info->unk149 = 0;
|
|
if ((flag == 0) && (param_4 != 0)) {
|
|
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],target,0);
|
|
TryDisplayDungeonLoggableMessage3(pokemon,target,gUnknown_80F9B74);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_807218C(Entity *pokemon)
|
|
{
|
|
EntityInfo *info;
|
|
u8 buffer [400];
|
|
s32 r1;
|
|
s32 r6;
|
|
s32 r3;
|
|
|
|
r6 = 0;
|
|
info = GetEntInfo(pokemon);
|
|
|
|
TryPointCameraToMonster(pokemon, 0);
|
|
SetMessageArgument_2(gFormatBuffer_Monsters[0], info, 0);
|
|
if(sub_8070BC0(pokemon))
|
|
{
|
|
r3 = 0;
|
|
r1 = info->id;
|
|
if(info->joinedAt.id == DUNGEON_JOIN_LOCATION_CLIENT_POKEMON)
|
|
{
|
|
r1 = 0x1A4;
|
|
}
|
|
else if(info->joinedAt.id == DUNGEON_RESCUE_TEAM_BASE)
|
|
{
|
|
r1 = 0x1A5;
|
|
}
|
|
else if(info->joinedAt.id == DUNGEON_JOIN_LOCATION_PARTNER)
|
|
{
|
|
if(gDungeon->unk644.unk18 == 0)
|
|
r3 = 1;
|
|
}
|
|
sub_806A3D4(buffer, r1, 3, r3);
|
|
}
|
|
else
|
|
{
|
|
strcpy(buffer, gUnknown_80FCF18);
|
|
}
|
|
DisplayDungeonMessage(0, buffer, 1);
|
|
buffer[0] = 0;
|
|
|
|
|
|
if(gFormatArgs[0]> 0)
|
|
{
|
|
strcat(buffer, gUnknown_80F9ACC);
|
|
r6++;
|
|
}
|
|
|
|
if(gFormatArgs[1]> 0)
|
|
{
|
|
if(gUnknown_8107010[r6] != 0)
|
|
strcat(buffer, gUnknown_8107018[gUnknown_8107010[r6]]);
|
|
strcat(buffer, gUnknown_80F9AEC);
|
|
r6++;
|
|
}
|
|
if(gFormatArgs[2]> 0)
|
|
{
|
|
if(gUnknown_8107010[r6] != 0)
|
|
strcat(buffer, gUnknown_8107018[gUnknown_8107010[r6]]);
|
|
strcat(buffer, gUnknown_80F9B10);
|
|
r6++;
|
|
}
|
|
if(gFormatArgs[3]> 0)
|
|
{
|
|
if(gUnknown_8107010[r6] != 0)
|
|
strcat(buffer, gUnknown_8107018[gUnknown_8107010[r6]]);
|
|
strcat(buffer, gUnknown_80F9B34);
|
|
r6++;
|
|
}
|
|
if(gFormatArgs[4]> 0)
|
|
{
|
|
if(gUnknown_8107010[r6] != 0)
|
|
strcat(buffer, gUnknown_8107018[gUnknown_8107010[r6]]);
|
|
strcat(buffer, gUnknown_80F9B58);
|
|
}
|
|
|
|
if(buffer[0])
|
|
DisplayDungeonMessage(0, buffer, 1);
|
|
|
|
TryPointCameraToMonster(GetLeader(), 0);
|
|
}
|
|
|
|
void LevelDownTarget(Entity *pokemon, Entity *target, u32 level)
|
|
{
|
|
EntityInfo *info;
|
|
u8 flag;
|
|
s32 newLevel;
|
|
LevelData leveldata;
|
|
|
|
if(EntityIsValid(target))
|
|
{
|
|
flag = FALSE;
|
|
info = GetEntInfo(target);
|
|
if(!IsExperienceLocked(info->joinedAt.id))
|
|
{
|
|
newLevel = info->level - level;
|
|
if(newLevel <= 0)
|
|
newLevel = 1;
|
|
|
|
if(newLevel != info->level)
|
|
{
|
|
GetLvlUpEntry(&leveldata, info->id, newLevel);
|
|
info->exp = leveldata.expRequired;
|
|
flag |= sub_80725A4(pokemon, target);
|
|
}
|
|
}
|
|
info->expGainedInTurn = 0;
|
|
info->unk149 = 0;
|
|
|
|
if(!flag)
|
|
{
|
|
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], target, 0);
|
|
TryDisplayDungeonLoggableMessage3(pokemon, target, gUnknown_80F9B94);
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool8 LevelUp(Entity *pokemon, Entity *target, u8 param_3, u8 param_4)
|
|
{
|
|
EntityInfo *info;
|
|
LevelData leveldata;
|
|
bool8 flag = FALSE;
|
|
s32 id;
|
|
s32 level;
|
|
s32 exp;
|
|
|
|
if(!EntityIsValid(target)) return FALSE;
|
|
info = GetEntInfo(target);
|
|
id = info->id;
|
|
exp = info->exp;
|
|
|
|
|
|
if(IsExperienceLocked(info->joinedAt.id))
|
|
return FALSE;
|
|
|
|
for(level = info->level + 1; level <= 100; level++)
|
|
{
|
|
GetLvlUpEntry(&leveldata, id, level);
|
|
if(leveldata.expRequired > exp) break;
|
|
|
|
info->level = level;
|
|
info->exp = exp;
|
|
|
|
if(param_3)
|
|
{
|
|
if(!info->isNotTeamMember)
|
|
{
|
|
TryPointCameraToMonster(target, 0);
|
|
if(!flag)
|
|
sub_8083D58();
|
|
gFormatArgs[0] = level;
|
|
|
|
SetMessageArgument_2(gFormatBuffer_Monsters[0], info, 0);
|
|
DisplayDungeonLoggableMessage(target, gUnknown_80F9E80);
|
|
}
|
|
else
|
|
{
|
|
if(!flag)
|
|
sub_8083D58();
|
|
gFormatArgs[0] = level;
|
|
SetMessageArgument_2(gFormatBuffer_Monsters[0], info, 0);
|
|
DisplayDungeonLoggableMessageTrue(target, gUnknown_80F9E80);
|
|
}
|
|
}
|
|
flag = TRUE;
|
|
|
|
info->maxHPStat += leveldata.gainHP;
|
|
info->HP += leveldata.gainHP;
|
|
|
|
if(info->maxHPStat > 998)
|
|
info->maxHPStat = 999;
|
|
|
|
if(info->HP >= info->maxHPStat)
|
|
{
|
|
info->HP = info->maxHPStat;
|
|
}
|
|
|
|
gUnknown_202F31C[0] = info->atk[0];
|
|
gUnknown_202F31C[1] = info->atk[1];
|
|
gUnknown_202F324[0] = info->def[0];
|
|
gUnknown_202F324[1] = info->def[1];
|
|
|
|
gUnknown_202F31C[0] += leveldata.gainAtt[0];
|
|
gUnknown_202F31C[1] += leveldata.gainAtt[1];
|
|
gUnknown_202F324[0] += leveldata.gainDef[0];
|
|
gUnknown_202F324[1] += leveldata.gainDef[1];
|
|
|
|
if(gUnknown_202F31C[0] > 254)
|
|
gUnknown_202F31C[0] = 255;
|
|
if(gUnknown_202F31C[1] > 254)
|
|
gUnknown_202F31C[1] = 255;
|
|
if(gUnknown_202F324[0] > 254)
|
|
gUnknown_202F324[0] = 255;
|
|
if(gUnknown_202F324[1] > 254)
|
|
gUnknown_202F324[1] = 255;
|
|
|
|
|
|
LoadIQSkills(target);
|
|
sub_8079764(target);
|
|
|
|
info->atk[0] = gUnknown_202F31C[0];
|
|
info->atk[1] = gUnknown_202F31C[1];
|
|
info->def[0] = gUnknown_202F324[0];
|
|
info->def[1] = gUnknown_202F324[1];
|
|
|
|
sub_8072778(pokemon, target, param_3, param_4);
|
|
}
|
|
|
|
return flag;
|
|
}
|
|
|
|
bool8 sub_80725A4(Entity *pokemon, Entity *target)
|
|
{
|
|
EntityInfo *info;
|
|
LevelData leveldata;
|
|
s32 level;
|
|
s32 levelMax;
|
|
s32 id;
|
|
s32 exp;
|
|
s32 oldLevel;
|
|
|
|
|
|
if(!EntityIsValid(target)) return FALSE;
|
|
info = GetEntInfo(target);
|
|
id = info->id;
|
|
exp = info->exp;
|
|
oldLevel = info->level;
|
|
|
|
|
|
if(IsExperienceLocked(info->joinedAt.id)) return FALSE;
|
|
|
|
for(level = 1; level < info->level; level++)
|
|
{
|
|
GetLvlUpEntry(&leveldata, id, level);
|
|
if(leveldata.expRequired >= exp) break;
|
|
}
|
|
|
|
levelMax = level - 1;
|
|
|
|
for(level = info->level; level > levelMax; level--)
|
|
{
|
|
if(level < 100)
|
|
{
|
|
GetLvlUpEntry(&leveldata, id, level + 1);
|
|
info->exp = leveldata.expRequired - 1;
|
|
}
|
|
else
|
|
{
|
|
info->exp = exp;
|
|
}
|
|
|
|
if(oldLevel > level)
|
|
{
|
|
GetLvlUpEntry(&leveldata, id, level + 1);
|
|
|
|
info->level = level;
|
|
|
|
info->maxHPStat -= leveldata.gainHP;
|
|
info->HP -= leveldata.gainHP;
|
|
|
|
if(info->HP <= 1)
|
|
info->HP = 1;
|
|
|
|
if(info->maxHPStat <= 1)
|
|
info->maxHPStat = 1;
|
|
|
|
if(info->HP >= info->maxHPStat)
|
|
{
|
|
info->HP = info->maxHPStat;
|
|
}
|
|
|
|
gUnknown_202F31C[0] = info->atk[0];
|
|
gUnknown_202F31C[1] = info->atk[1];
|
|
gUnknown_202F324[0] = info->def[0];
|
|
gUnknown_202F324[1] = info->def[1];
|
|
|
|
gUnknown_202F31C[0] -= leveldata.gainAtt[0];
|
|
gUnknown_202F31C[1] -= leveldata.gainAtt[1];
|
|
gUnknown_202F324[0] -= leveldata.gainDef[0];
|
|
gUnknown_202F324[1] -= leveldata.gainDef[1];
|
|
|
|
if(gUnknown_202F31C[0] <= 1)
|
|
gUnknown_202F31C[0] = 1;
|
|
if(gUnknown_202F31C[1] <= 1)
|
|
gUnknown_202F31C[1] = 1;
|
|
if(gUnknown_202F324[0] <= 1)
|
|
gUnknown_202F324[0] = 1;
|
|
if(gUnknown_202F324[1] <= 1)
|
|
gUnknown_202F324[1] = 1;
|
|
|
|
|
|
LoadIQSkills(target);
|
|
sub_8079764(target);
|
|
|
|
info->atk[0] = gUnknown_202F31C[0];
|
|
info->atk[1] = gUnknown_202F31C[1];
|
|
info->def[0] = gUnknown_202F324[0];
|
|
info->def[1] = gUnknown_202F324[1];
|
|
}
|
|
}
|
|
|
|
|
|
SetMessageArgument_2(gFormatBuffer_Monsters[0], info, 0);
|
|
|
|
if(info->level != oldLevel)
|
|
{
|
|
gFormatArgs[0] = info->level;
|
|
sub_80421C0(target, 0xD3 << 1);
|
|
TryDisplayDungeonLoggableMessage3(pokemon, target, gUnknown_80F9EC8); // $m0 dropped to Level $d0!
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
TryDisplayDungeonLoggableMessage3(pokemon, target, gUnknown_80F9EEC); // $m0's level didn't drop!
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
void sub_8072778(Entity *pokemon, Entity *target, u8 param_2, u8 param_3)
|
|
{
|
|
s32 i, j;
|
|
u16 learnedMoves[16];
|
|
Move localMoves[8];
|
|
u8 text[0x64];
|
|
s32 count;
|
|
EntityInfo *info = GetEntInfo(target);
|
|
bool8 sp_0xCC = FALSE;
|
|
|
|
if (info->isNotTeamMember) {
|
|
param_3 = 0;
|
|
param_2 = 0;
|
|
}
|
|
|
|
count = GetMovesLearnedAtLevel(learnedMoves, info->id, info->level, info->IQ);
|
|
unk_CopyMoves4To8AndClearFlag2Unk4(localMoves, info->moves.moves);
|
|
|
|
if (count != 0) {
|
|
s32 randIndex = DungeonRandInt(count);
|
|
for (j = 0; j < 8; j++) {
|
|
if(!MoveFlagExists(&localMoves[j])) {
|
|
InitPokemonMove(&localMoves[j], learnedMoves[randIndex]);
|
|
localMoves[j].moveFlags2 |= 4;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 0x1E; i++) {
|
|
count = 0;
|
|
for (j = 0; j < 8; j++) {
|
|
if (MoveFlagExists(&localMoves[j])) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if (count <= MAX_MON_MOVES) {
|
|
s32 i;
|
|
bool8 r3 = FALSE;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
info->moves.moves[i] = localMoves[i];
|
|
if((info->moves.moves[i].moveFlags2 & 4))
|
|
{
|
|
info->moves.moves[i].moveFlags2 &= 0xFB;
|
|
BufferMoveName(text, &info->moves.moves[i], 0);
|
|
r3 = TRUE;
|
|
}
|
|
}
|
|
for (; i < MAX_MON_MOVES; i++) {
|
|
ResetMoveFlags(&info->moves.moves[i]);
|
|
}
|
|
|
|
if (r3 && param_2) {
|
|
SetMessageArgument_2(gFormatBuffer_Monsters[0], info, 0);
|
|
strcpy(gFormatBuffer_Items[0], text);
|
|
sub_80421C0(target, 312);
|
|
DisplayDungeonLoggableMessage(target, gUnknown_80F9F04);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (!info->isNotTeamMember && param_3) {
|
|
if (!sp_0xCC && param_2) {
|
|
sub_803E708(0xA, 0x6);
|
|
DisplayDungeonMessage(0, gUnknown_80F9FA4, 1);
|
|
}
|
|
sp_0xCC = 1;
|
|
sub_8063E70(target, localMoves, 1, 0);
|
|
}
|
|
else {
|
|
sub_8072B24(target, localMoves);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool8 sub_8072938(Entity *target, u16 moveId)
|
|
{
|
|
s32 i, j;
|
|
Move localMoves[8];
|
|
u8 text[0x64];
|
|
s32 count;
|
|
EntityInfo *info = GetEntInfo(target);
|
|
bool8 r10 = FALSE;
|
|
|
|
unk_CopyMoves4To8AndClearFlag2Unk4(localMoves, info->moves.moves);
|
|
for (j = 0; j < 8; j++) {
|
|
if(!(MoveFlagExists(&localMoves[j]))) {
|
|
InitPokemonMove(&localMoves[j], moveId);
|
|
localMoves[j].moveFlags2 |= 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 0x1E; i++) {
|
|
count = 0;
|
|
for (j = 0; j < 8; j++) {
|
|
if (MoveFlagExists(&localMoves[j])) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if (count <= MAX_MON_MOVES) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
info->moves.moves[i] = localMoves[i];
|
|
if((info->moves.moves[i].moveFlags2 & 4))
|
|
{
|
|
info->moves.moves[i].moveFlags2 &= 0xFB;
|
|
BufferMoveName(text, &info->moves.moves[i], 0);
|
|
r10 = TRUE;
|
|
}
|
|
}
|
|
for (; i < MAX_MON_MOVES; i++) {
|
|
ResetMoveFlags(&info->moves.moves[i]);
|
|
}
|
|
|
|
if (r10) {
|
|
if (!info->isNotTeamMember) {
|
|
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], target, 0);
|
|
strcpy(gFormatBuffer_Items[0], text);
|
|
sub_80421C0(target, 312);
|
|
DisplayDungeonLoggableMessage(target, gUnknown_80F9F04);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
r10 = FALSE;
|
|
|
|
if (!info->isNotTeamMember) {
|
|
DisplayDungeonMessage(0, gUnknown_80FDF40, 1);
|
|
if (!sub_8063E70(target, localMoves, TRUE, TRUE)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!r10 && !info->isNotTeamMember) {
|
|
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], target, 0);
|
|
DisplayDungeonLoggableMessage(target, gUnknown_80F9F2C);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void sub_8072AC8(s16 *param_1, s16 species, s32 param_3)
|
|
{
|
|
const u8 *levelUpMoves;
|
|
s32 arrIndex;
|
|
s32 counter;
|
|
u16 moveIDs [2];
|
|
s32 species_s32;
|
|
s32 index;
|
|
|
|
species_s32 = species;
|
|
|
|
for(index = 0; index < MAX_MON_MOVES; index++) {
|
|
param_1[index] = MOVE_NOTHING;
|
|
}
|
|
|
|
counter = 0;
|
|
levelUpMoves = GetLevelUpMoves(species_s32);
|
|
|
|
while( 1 ) {
|
|
if (*levelUpMoves == 0) {
|
|
return;
|
|
}
|
|
levelUpMoves = DecompressMoveID(levelUpMoves,moveIDs);
|
|
if (*levelUpMoves++ > param_3) break;
|
|
if (counter == MAX_MON_MOVES) {
|
|
arrIndex = DungeonRandInt(MAX_MON_MOVES);
|
|
counter = MAX_MON_MOVES;
|
|
}
|
|
else {
|
|
arrIndex = counter;
|
|
counter++;
|
|
}
|
|
param_1[arrIndex] = moveIDs[0];
|
|
}
|
|
}
|
|
|
|
void sub_8072B24(Entity *entity, Move *moves)
|
|
{
|
|
int index;
|
|
int count;
|
|
|
|
count = 0;
|
|
for(index = 0; index < 8; index++)
|
|
{
|
|
if (moves[index].moveFlags & MOVE_FLAG_EXISTS) {
|
|
moves[index].moveFlags &= 0xfd;
|
|
count++;
|
|
}
|
|
}
|
|
index = DungeonRandInt(count);
|
|
for (; index < 7; index++) {
|
|
moves[index] = moves[index + 1];
|
|
}
|
|
moves[7].moveFlags = 0;
|
|
}
|
|
|
|
static inline void fu(EntityInfo *entityInfo, s16 id)
|
|
{
|
|
++id; --id;
|
|
entityInfo->apparentID = id;
|
|
entityInfo->id = id;
|
|
}
|
|
|
|
void sub_8072B78(Entity *pokemon, Entity *target, s16 id)
|
|
{
|
|
OpenedFile *file;
|
|
const Tile *tile;
|
|
int index;
|
|
s32 id_s32;
|
|
EntityInfo *entityInfo;
|
|
LevelData levelData;
|
|
struct unkStruct_806B7F8 local_2c;
|
|
|
|
id_s32 = id;
|
|
entityInfo = GetEntInfo(target);
|
|
SetMessageArgument_2(gFormatBuffer_Monsters[0],entityInfo,0);
|
|
CopyCyanMonsterNametoBuffer(gFormatBuffer_Monsters[1],id_s32);
|
|
file = GetSpriteData(id_s32);
|
|
fu(entityInfo, id_s32);
|
|
GetLvlUpEntry(&levelData,id_s32,entityInfo->level);
|
|
entityInfo->exp = levelData.expRequired;
|
|
target->axObj.spriteFile = file;
|
|
ResetMonEntityData(entityInfo,0);
|
|
sub_8069E0C(target);
|
|
sub_806CCB4(target,7);
|
|
TryDisplayDungeonLoggableMessage3(pokemon,target,gUnknown_80FE2EC);
|
|
sub_8042A44(target);
|
|
sub_8083D78();
|
|
if (id_s32 == MONSTER_NINJASK) {
|
|
for (index = 0; index < 8; index++) {
|
|
tile = GetTile(gAdjacentTileOffsets[index].x + target->pos.x,gAdjacentTileOffsets[index].y + target->pos.y);
|
|
if (sub_807034C(MONSTER_SHEDINJA,tile) == 0) break;
|
|
}
|
|
if (CanMonsterBeSpawnedHere(MONSTER_SHEDINJA)) {
|
|
local_2c.species = MONSTER_SHEDINJA;
|
|
local_2c.level = entityInfo->level;
|
|
local_2c.unk2 = 0;
|
|
local_2c.pos.x = gAdjacentTileOffsets[index].x + target->pos.x;
|
|
local_2c.pos.y = gAdjacentTileOffsets[index].y + target->pos.y;
|
|
local_2c.unk4 = 0;
|
|
local_2c.unk10 = 0;
|
|
sub_806B7F8(&local_2c, TRUE);
|
|
}
|
|
}
|
|
}
|