decompile pokemon1

This commit is contained in:
DizzyEggg 2018-02-09 15:55:12 +01:00
parent 387dbf48d0
commit 9e7696f25a
14 changed files with 652 additions and 2054 deletions

View File

@ -1591,7 +1591,7 @@ _0818F7E8:
lsrs r1, 16
ldr r0, [sp, 0x18]
movs r2, 0x1
bl nature_stat_mod
bl ModifyStatByNature
lsls r0, 24
lsrs r0, 24
mov r1, r8
@ -1618,7 +1618,7 @@ _0818F820:
lsrs r1, 16
ldr r0, [sp, 0x18]
movs r2, 0x2
bl nature_stat_mod
bl ModifyStatByNature
lsls r0, 24
lsrs r0, 24
mov r1, r8
@ -1645,7 +1645,7 @@ _0818F858:
lsrs r1, 16
ldr r0, [sp, 0x18]
movs r2, 0x3
bl nature_stat_mod
bl ModifyStatByNature
lsls r0, 24
lsrs r0, 24
mov r1, r8
@ -1672,7 +1672,7 @@ _0818F890:
lsrs r1, 16
ldr r0, [sp, 0x18]
movs r2, 0x4
bl nature_stat_mod
bl ModifyStatByNature
lsls r0, 24
lsrs r0, 24
mov r1, r8
@ -1699,7 +1699,7 @@ _0818F8C8:
lsrs r1, 16
ldr r0, [sp, 0x18]
movs r2, 0x5
bl nature_stat_mod
bl ModifyStatByNature
lsls r0, 24
lsrs r0, 24
mov r1, r8
@ -1941,7 +1941,7 @@ sub_818FA74: @ 818FA74
str r4, [sp, 0x4]
ldr r7, [sp, 0x14]
str r7, [sp, 0x8]
bl sub_8068634
bl CreateMonWithEVSpreadPersonalityOTID
add r0, sp, 0xC
movs r1, 0x1
negs r1, r1

View File

@ -1960,7 +1960,7 @@ _0819B572:
mov r2, r9
str r2, [sp, 0x8]
ldr r2, [sp, 0x14]
bl sub_8068634
bl CreateMonWithEVSpreadPersonalityOTID
movs r1, 0
add r0, sp, 0xC
strb r1, [r0]
@ -2103,7 +2103,7 @@ _0819B678:
mov r2, r10
str r2, [sp, 0x8]
movs r2, 0x1E
bl sub_8068634
bl CreateMonWithEVSpreadPersonalityOTID
add r0, sp, 0xC
movs r3, 0
strb r3, [r0]
@ -23864,7 +23864,7 @@ _081A6E0C:
ldr r4, [sp, 0x28]
str r4, [sp, 0x8]
lsrs r2, 24
bl sub_8068634
bl CreateMonWithEVSpreadPersonalityOTID
add r0, sp, 0x1C
movs r7, 0
strb r7, [r0]

View File

@ -2351,7 +2351,7 @@ _08163368:
ldr r2, [sp, 0x30]
str r2, [sp, 0x8]
ldr r2, [sp, 0x20]
bl sub_8068634
bl CreateMonWithEVSpreadPersonalityOTID
movs r0, 0xFF
mov r6, sp
strb r0, [r6, 0x14]
@ -2775,7 +2775,7 @@ _081636CE:
str r2, [sp, 0x8]
ldr r2, [sp, 0x14]
mov r3, r10
bl sub_8068634
bl CreateMonWithEVSpreadPersonalityOTID
movs r1, 0
add r0, sp, 0xC
strb r1, [r0]
@ -2894,7 +2894,7 @@ _081637D0:
mov r2, r9
str r2, [sp, 0x8]
movs r2, 0x1E
bl sub_8068634
bl CreateMonWithEVSpreadPersonalityOTID
movs r1, 0
add r0, sp, 0xC
strb r1, [r0]
@ -6289,7 +6289,7 @@ _081655A6:
str r3, [sp, 0x8]
lsrs r2, 24
mov r3, r12
bl sub_8068634
bl CreateMonWithEVSpreadPersonalityOTID
movs r0, 0xFF
str r0, [sp, 0x48]
movs r0, 0
@ -7550,7 +7550,7 @@ _08165FDA:
ldr r2, [sp, 0x2C]
str r2, [sp, 0x8]
ldr r2, [sp, 0x20]
bl sub_8068634
bl CreateMonWithEVSpreadPersonalityOTID
add r1, sp, 0x14
movs r0, 0xFF
strb r0, [r1]

File diff suppressed because it is too large Load Diff

View File

@ -86,7 +86,7 @@ BirthIsland_Exterior_EventScript_267FC1:: @ 8267FC1
setvar VAR_0x8004, 410
setvar VAR_0x8005, 30
setvar VAR_0x8006, 0
special DoScriptedWildBattle
special CreateObedientEnemyMon
setflag FLAG_SYS_CTRL_OBJ_DELETE
special BattleSetup_StartLegendaryBattle
waitstate

View File

@ -143,7 +143,7 @@ FarawayIsland_Interior_EventScript_267DF2:: @ 8267DF2
setvar VAR_0x8004, 151
setvar VAR_0x8005, 30
setvar VAR_0x8006, 0
special DoScriptedWildBattle
special CreateObedientEnemyMon
setflag FLAG_SYS_CTRL_OBJ_DELETE
special BattleSetup_StartLegendaryBattle
waitstate

View File

@ -59,7 +59,7 @@ NavelRock_Bottom_EventScript_2692A2:: @ 82692A2
setvar VAR_0x8004, 249
setvar VAR_0x8005, 70
setvar VAR_0x8006, 0
special DoScriptedWildBattle
special CreateObedientEnemyMon
setflag FLAG_SYS_CTRL_OBJ_DELETE
special BattleSetup_StartLegendaryBattle
waitstate

View File

@ -63,7 +63,7 @@ NavelRock_Top_EventScript_26916F:: @ 826916F
setvar VAR_0x8004, 250
setvar VAR_0x8005, 70
setvar VAR_0x8006, 0
special DoScriptedWildBattle
special CreateObedientEnemyMon
setflag FLAG_SYS_CTRL_OBJ_DELETE
special BattleSetup_StartLegendaryBattle
waitstate

View File

@ -121,14 +121,14 @@ SouthernIsland_Interior_EventScript_242BA4:: @ 8242BA4
setvar VAR_0x8004, 408
setvar VAR_0x8005, 50
setvar VAR_0x8006, 191
special DoScriptedWildBattle
special CreateObedientEnemyMon
return
SouthernIsland_Interior_EventScript_242BB7:: @ 8242BB7
setvar VAR_0x8004, 407
setvar VAR_0x8005, 50
setvar VAR_0x8006, 191
special DoScriptedWildBattle
special CreateObedientEnemyMon
return
SouthernIsland_Interior_Movement_242BCA: @ 8242BCA

View File

@ -490,7 +490,7 @@ gSpecials:: @ 81DBA64
def_special sub_813AF48
def_special sub_813AFC8
def_special sub_813B1D0
def_special DoScriptedWildBattle
def_special CreateObedientEnemyMon
def_special sub_81BEB54
def_special sub_81BEB68
def_special sub_81BEB7C

View File

@ -334,6 +334,32 @@ struct UnknownPokemonStruct
u8 friendship;
};
struct UnknownPokemonSubStruct2
{
u16 species;
u16 moves[4];
u16 item;
};
struct UnknownPokemonStruct2
{
u8 field_0_0 : 5;
u8 field_0_1 : 2;
u8 field_1;
u8 field_2;
u8 field_3;
struct UnknownPokemonSubStruct2 mons[3];
u8 field_28[23];
u8 language;
};
struct UnknownPokemonStruct3
{
u8 field_0[48];
u16 field_30;
u8 field_32[38];
};
#define BATTLE_STATS_NO 8
struct BattlePokemon
@ -590,7 +616,7 @@ void CopyPlayerPartyMonToBattleData(u8 battleIndex, u8 partyIndex);
u8 GetNature(struct Pokemon *mon);
u8 GetNatureFromPersonality(u32 personality);
u16 nature_stat_mod(u8 nature, u16 n, u8 statIndex);
u16 ModifyStatByNature(u8 nature, u16 n, u8 statIndex);
void MonRestorePP(struct Pokemon *);
void BoxMonRestorePP(struct BoxPokemon *);
@ -628,7 +654,7 @@ void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality);
s32 GetBattlerMultiplayerId(u16 a1);
bool16 sub_806D82C(u8 id);
u16 MonTryLearningNewMove(struct Pokemon* mon, bool8);
void sub_8068AA4(void); // sets stats for deoxys
void SetDeoxysStats(void); // sets stats for deoxys
bool8 HasTwoFramesAnimation(u16 species);
u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem);
void RandomlyGivePartyPokerus(struct Pokemon *party);
@ -645,7 +671,7 @@ void sub_806A1C0(u16 arg0, u8 bankIdentity);
void sub_806A12C(u16 trainerSpriteId, u8 bankIdentity);
u8 GetSecretBaseTrainerPicIndex(void);
bool8 TryIncrementMonLevel(struct Pokemon *mon);
void BoxMonToMon(struct BoxPokemon *srcMon, struct Pokemon *dstMon);
void BoxMonToMon(const struct BoxPokemon *srcMon, struct Pokemon *dstMon);
u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves);
u8 GetMonsStateToDoubles_2(void);

View File

@ -46,7 +46,7 @@
#include "battle_string_ids.h"
#include "data2.h"
struct UnknownPokemonStruct2
struct UnknownPokemonStruct4
{
/*0x00*/ u16 species;
/*0x02*/ u16 heldItem;
@ -81,8 +81,8 @@ extern struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT];
extern void (*gPreBattleCallback1)(void);
extern void (*gBattleMainFunc)(void);
extern void (*gCB2_AfterEvolution)(void);
extern struct UnknownPokemonStruct2 gUnknown_02022FF8[3]; // what is it used for?
extern struct UnknownPokemonStruct2* gUnknown_02023058; // what is it used for?
extern struct UnknownPokemonStruct4 gUnknown_02022FF8[3]; // what is it used for?
extern struct UnknownPokemonStruct4* gUnknown_02023058; // what is it used for?
extern struct MusicPlayerInfo gMPlayInfo_SE1;
extern struct MusicPlayerInfo gMPlayInfo_SE2;
extern u8 gDecompressionBuffer[];
@ -751,7 +751,7 @@ static void CB2_HandleStartBattle(void)
gTasks[taskId].data[4] = gBlockRecvBuffer[enemyMultiplayerId][1];
sub_8185F90(gBlockRecvBuffer[playerMultiplayerId][1]);
sub_8185F90(gBlockRecvBuffer[enemyMultiplayerId][1]);
sub_8068AA4();
SetDeoxysStats();
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@ -1163,9 +1163,9 @@ static void CB2_PreInitMultiBattle(void)
case 0:
if (gReceivedRemoteLinkPlayers != 0 && sub_800A520())
{
gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct2) * 3);
gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct4) * 3);
sub_80379F8(0);
SendBlock(bitmask_all_link_players_but_self(), gUnknown_02023058, sizeof(struct UnknownPokemonStruct2) * 3);
SendBlock(bitmask_all_link_players_but_self(), gUnknown_02023058, sizeof(struct UnknownPokemonStruct4) * 3);
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@ -1183,12 +1183,12 @@ static void CB2_PreInitMultiBattle(void)
if ((!(gLinkPlayers[i].lp_field_18 & 1) && !(gLinkPlayers[playerMultiplierId].lp_field_18 & 1))
|| (gLinkPlayers[i].lp_field_18 & 1 && gLinkPlayers[playerMultiplierId].lp_field_18 & 1))
{
memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct2) * 3);
memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct4) * 3);
}
}
else
{
memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct2) * 3);
memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct4) * 3);
}
}
gBattleCommunication[MULTIUSE_STATE]++;
@ -1247,7 +1247,7 @@ static void CB2_PreInitIngamePlayerPartnerBattle(void)
switch (gBattleCommunication[MULTIUSE_STATE])
{
case 0:
gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct2) * 3);
gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct4) * 3);
sub_80379F8(3);
gBattleCommunication[MULTIUSE_STATE]++;
*savedCallback = gMain.savedCallback;
@ -1330,7 +1330,7 @@ static void CB2_HandleStartMultiBattle(void)
ResetBlockReceivedFlags();
sub_8036EB8(4, playerMultiplayerId);
SetAllPlayersBerryData();
sub_8068AA4();
SetDeoxysStats();
var = CreateTask(sub_8035D74, 0);
gTasks[var].data[1] = 0x10E;
gTasks[var].data[2] = 0x5A;

View File

@ -1,5 +1,6 @@
#include "global.h"
#include "pokemon.h"
#include "battle.h"
#include "random.h"
#include "main.h"
#include "constants/species.h"
@ -9,6 +10,8 @@
#include "constants/moves.h"
#include "string_util.h"
#include "text.h"
#include "link.h"
#include "event_data.h"
//Extracts the upper 16 bits of a 32-bit number
#define HIHALF(n) (((n) & 0xFFFF0000) >> 16)
@ -16,7 +19,22 @@
//Extracts the lower 16 bits of a 32-bit number
#define LOHALF(n) ((n) & 0xFFFF)
extern u32 gBattleTypeFlags;
extern u8 gUnknown_0203C7B4;
extern u16 gMoveToLearn;
extern const struct UnknownPokemonStruct3 gUnknown_08610970[];
extern const u16 gUnknown_08329D48[];
extern const u16 gUnknown_08329D54[];
extern const struct BattleMove gBattleMoves[];
extern u8 sav1_map_get_name(void);
extern const u8 *sub_81A1650(u8, u8 language);
extern u8 BattleFrontierGetOpponentLvl(u8);
extern u16 sub_806EFF0(u16);
// this file's functions
union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType);
// EWRAM vars
EWRAM_DATA u8 sLearningMoveTableID = 0;
@ -311,28 +329,28 @@ void CreateMonWithEVSpread(struct Pokemon *mon, u16 species, u8 level, u8 fixedI
s32 i;
s32 statCount = 0;
u16 evAmount;
u8 temp;
u8 evsBits;
CreateMon(mon, species, level, fixedIV, 0, 0, 0, 0);
temp = evSpread;
evsBits = evSpread;
for (i = 0; i < 6; i++)
for (i = 0; i < NUM_STATS; i++)
{
if (temp & 1)
if (evsBits & 1)
statCount++;
temp >>= 1;
evsBits >>= 1;
}
evAmount = 510 / statCount;
evAmount = MAX_TOTAL_EVS / statCount;
temp = 1;
evsBits = 1;
for (i = 0; i < 6; i++)
for (i = 0; i < NUM_STATS; i++)
{
if (evSpread & temp)
if (evSpread & evsBits)
SetMonData(mon, MON_DATA_HP_EV + i, &evAmount);
temp <<= 1;
evsBits <<= 1;
}
CalculateMonStats(mon);
@ -392,8 +410,6 @@ void sub_806819C(struct Pokemon *mon, struct UnknownPokemonStruct *src)
CalculateMonStats(mon);
}
u8 BattleFrontierGetOpponentLvl(u8);
void sub_8068338(struct Pokemon *mon, struct UnknownPokemonStruct *src, bool8 lvl50)
{
s32 i;
@ -455,3 +471,566 @@ void sub_8068338(struct Pokemon *mon, struct UnknownPokemonStruct *src, bool8 lv
MonRestorePP(mon);
CalculateMonStats(mon);
}
void sub_8068528(struct Pokemon *mon, const struct UnknownPokemonStruct2 *src, u8 monId)
{
s32 i;
u16 evAmount;
u8 language;
u32 otId = gUnknown_08610970[src->field_0_0].field_30;
u32 personality = ((gUnknown_08610970[src->field_0_0].field_30 >> 8) | ((gUnknown_08610970[src->field_0_0].field_30 & 0xFF) << 8))
+ src->mons[monId].species + src->field_2;
CreateMon(mon,
src->mons[monId].species,
BattleFrontierGetOpponentLvl(src->field_0_1 - 1),
0x1F,
TRUE,
personality,
TRUE,
otId);
SetMonData(mon, MON_DATA_HELD_ITEM, &src->mons[monId].item);
for (i = 0; i < 4; i++)
SetMonMoveSlot(mon, src->mons[monId].moves[i], i);
evAmount = MAX_TOTAL_EVS / NUM_STATS;
for (i = 0; i < NUM_STATS; i++)
SetMonData(mon, MON_DATA_HP_EV + i, &evAmount);
language = src->language;
SetMonData(mon, MON_DATA_LANGUAGE, &language);
SetMonData(mon, MON_DATA_OT_NAME, sub_81A1650(src->field_0_0, language));
CalculateMonStats(mon);
}
void CreateMonWithEVSpreadPersonalityOTID(struct Pokemon *mon, u16 species, u8 level, u8 nature, u8 fixedIV, u8 evSpread, u32 otId)
{
s32 i;
s32 statCount = 0;
u8 evsBits;
u16 evAmount;
// i is reused as personality value
do
{
i = Random32();
} while (nature != GetNatureFromPersonality(i));
CreateMon(mon, species, level, fixedIV, TRUE, i, TRUE, otId);
evsBits = evSpread;
for (i = 0; i < NUM_STATS; i++)
{
if (evsBits & 1)
statCount++;
evsBits >>= 1;
}
evAmount = MAX_TOTAL_EVS / statCount;
evsBits = 1;
for (i = 0; i < NUM_STATS; i++)
{
if (evSpread & evsBits)
SetMonData(mon, MON_DATA_HP_EV + i, &evAmount);
evsBits <<= 1;
}
CalculateMonStats(mon);
}
void sub_80686FC(struct Pokemon *mon, struct UnknownPokemonStruct *dest)
{
s32 i;
u16 heldItem;
dest->species = GetMonData(mon, MON_DATA_SPECIES, NULL);
heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL);
if (heldItem == ITEM_ENIGMA_BERRY)
heldItem = 0;
dest->heldItem = heldItem;
for (i = 0; i < 4; i++)
dest->moves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, NULL);
dest->level = GetMonData(mon, MON_DATA_LEVEL, NULL);
dest->ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
dest->otId = GetMonData(mon, MON_DATA_OT_ID, NULL);
dest->hpEV = GetMonData(mon, MON_DATA_HP_EV, NULL);
dest->attackEV = GetMonData(mon, MON_DATA_ATK_EV, NULL);
dest->defenseEV = GetMonData(mon, MON_DATA_DEF_EV, NULL);
dest->speedEV = GetMonData(mon, MON_DATA_SPEED_EV, NULL);
dest->spAttackEV = GetMonData(mon, MON_DATA_SPATK_EV, NULL);
dest->spDefenseEV = GetMonData(mon, MON_DATA_SPDEF_EV, NULL);
dest->friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL);
dest->hpIV = GetMonData(mon, MON_DATA_HP_IV, NULL);
dest->attackIV = GetMonData(mon, MON_DATA_ATK_IV, NULL);
dest->defenseIV = GetMonData(mon, MON_DATA_DEF_IV, NULL);
dest->speedIV = GetMonData(mon, MON_DATA_SPEED_IV, NULL);
dest->spAttackIV = GetMonData(mon, MON_DATA_SPATK_IV, NULL);
dest->spDefenseIV = GetMonData(mon, MON_DATA_SPDEF_IV, NULL);
dest->altAbility = GetMonData(mon, MON_DATA_ALT_ABILITY, NULL);
dest->personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
GetMonData(mon, MON_DATA_NICKNAME, dest->nickname);
}
void CreateObedientMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
{
bool32 obedient = TRUE;
CreateMon(mon, species, level, fixedIV, hasFixedPersonality, fixedPersonality, otIdType, fixedOtId);
SetMonData(mon, MON_DATA_OBEDIENCE, &obedient);
}
bool8 sub_80688F8(u8 caseId, u8 battlerId)
{
switch (caseId)
{
case 0:
default:
return FALSE;
case 1:
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
return FALSE;
if (!gMain.inBattle)
return FALSE;
if (gLinkPlayers[GetMultiplayerId()].lp_field_18 == battlerId)
return FALSE;
break;
case 2:
break;
case 3:
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
return FALSE;
if (!gMain.inBattle)
return FALSE;
if (battlerId == 1 || battlerId == 4 || battlerId == 5)
return TRUE;
return FALSE;
case 4:
break;
case 5:
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{
if (!gMain.inBattle)
return FALSE;
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
if (gLinkPlayers[GetMultiplayerId()].lp_field_18 == battlerId)
return FALSE;
}
else
{
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
return FALSE;
}
}
else
{
if (!gMain.inBattle)
return FALSE;
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
return FALSE;
}
break;
}
return TRUE;
}
s32 GetDeoxysStat(struct Pokemon *mon, s32 statId)
{
s32 ivVal, evVal;
s32 statValue;
u8 nature, statId_;
if (gBattleTypeFlags & BATTLE_TYPE_20)
return 0;
if (GetMonData(mon, MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS)
return 0;
ivVal = GetMonData(mon, MON_DATA_HP_IV + statId, NULL);
evVal = GetMonData(mon, MON_DATA_HP_EV + statId, NULL);
statValue = (u16)(((gUnknown_08329D48[statId] * 2 + ivVal + evVal / 4) * mon->level) / 100 + 5);
nature = GetNature(mon);
statId_ = statId; // needed to match
statValue = ModifyStatByNature(nature, statValue, statId_);
return statValue;
}
void SetDeoxysStats(void)
{
s32 i, value;
for (i = 0; i < PARTY_SIZE; i++)
{
struct Pokemon *mon = &gPlayerParty[i];
if (GetMonData(mon, MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS)
continue;
value = GetMonData(mon, MON_DATA_ATK, NULL);
SetMonData(mon, MON_DATA_ATK, &value);
value = GetMonData(mon, MON_DATA_DEF, NULL);
SetMonData(mon, MON_DATA_DEF, &value);
value = GetMonData(mon, MON_DATA_SPEED, NULL);
SetMonData(mon, MON_DATA_SPEED, &value);
value = GetMonData(mon, MON_DATA_SPATK, NULL);
SetMonData(mon, MON_DATA_SPATK, &value);
value = GetMonData(mon, MON_DATA_SPDEF, NULL);
SetMonData(mon, MON_DATA_SPDEF, &value);
}
}
u16 sub_8068B48(void)
{
u8 linkId;
u32 arrId;
if (gBattleTypeFlags & BATTLE_TYPE_x2000000)
linkId = gUnknown_0203C7B4 ^ 1;
else
linkId = GetMultiplayerId() ^ 1;
arrId = gLinkPlayers[linkId].trainerId & 7;
arrId |= gLinkPlayers[linkId].gender << 3;
return sub_806EFF0(gUnknown_08329D54[arrId]);
}
u16 sub_8068BB0(void)
{
u8 linkId;
u32 arrId;
if (gBattleTypeFlags & BATTLE_TYPE_x2000000)
linkId = gUnknown_0203C7B4 ^ 1;
else
linkId = GetMultiplayerId() ^ 1;
arrId = gLinkPlayers[linkId].trainerId & 7;
arrId |= gLinkPlayers[linkId].gender << 3;
return gFacilityClassToTrainerClass[gUnknown_08329D54[arrId]];
}
void CreateObedientEnemyMon(void)
{
s32 species = gSpecialVar_0x8004;
s32 level = gSpecialVar_0x8005;
s32 itemId = gSpecialVar_0x8006;
ZeroEnemyPartyMons();
CreateObedientMon(&gEnemyParty[0], species, level, 32, 0, 0, 0, 0);
if (itemId)
{
u8 heldItem[2];
heldItem[0] = itemId;
heldItem[1] = itemId >> 8;
SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, heldItem);
}
}
u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon)
{
u16 checksum = 0;
union PokemonSubstruct *substruct0 = GetSubstruct(boxMon, boxMon->personality, 0);
union PokemonSubstruct *substruct1 = GetSubstruct(boxMon, boxMon->personality, 1);
union PokemonSubstruct *substruct2 = GetSubstruct(boxMon, boxMon->personality, 2);
union PokemonSubstruct *substruct3 = GetSubstruct(boxMon, boxMon->personality, 3);
s32 i;
for (i = 0; i < 6; i++)
checksum += substruct0->raw[i];
for (i = 0; i < 6; i++)
checksum += substruct1->raw[i];
for (i = 0; i < 6; i++)
checksum += substruct2->raw[i];
for (i = 0; i < 6; i++)
checksum += substruct3->raw[i];
return checksum;
}
#define CALC_STAT(base, iv, ev, statIndex, field) \
{ \
u8 baseStat = gBaseStats[species].base; \
s32 n = (((2 * baseStat + iv + ev / 4) * level) / 100) + 5; \
u8 nature = GetNature(mon); \
n = ModifyStatByNature(nature, n, statIndex); \
SetMonData(mon, field, &n); \
}
void CalculateMonStats(struct Pokemon *mon)
{
s32 oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP, NULL);
s32 currentHP = GetMonData(mon, MON_DATA_HP, NULL);
s32 hpIV = GetMonData(mon, MON_DATA_HP_IV, NULL);
s32 hpEV = GetMonData(mon, MON_DATA_HP_EV, NULL);
s32 attackIV = GetMonData(mon, MON_DATA_ATK_IV, NULL);
s32 attackEV = GetMonData(mon, MON_DATA_ATK_EV, NULL);
s32 defenseIV = GetMonData(mon, MON_DATA_DEF_IV, NULL);
s32 defenseEV = GetMonData(mon, MON_DATA_DEF_EV, NULL);
s32 speedIV = GetMonData(mon, MON_DATA_SPEED_IV, NULL);
s32 speedEV = GetMonData(mon, MON_DATA_SPEED_EV, NULL);
s32 spAttackIV = GetMonData(mon, MON_DATA_SPATK_IV, NULL);
s32 spAttackEV = GetMonData(mon, MON_DATA_SPATK_EV, NULL);
s32 spDefenseIV = GetMonData(mon, MON_DATA_SPDEF_IV, NULL);
s32 spDefenseEV = GetMonData(mon, MON_DATA_SPDEF_EV, NULL);
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
s32 level = GetLevelFromMonExp(mon);
s32 newMaxHP;
SetMonData(mon, MON_DATA_LEVEL, &level);
if (species == SPECIES_SHEDINJA)
{
newMaxHP = 1;
}
else
{
s32 n = 2 * gBaseStats[species].baseHP + hpIV;
newMaxHP = (((n + hpEV / 4) * level) / 100) + level + 10;
}
gBattleScripting.field_23 = newMaxHP - oldMaxHP;
if (gBattleScripting.field_23 == 0)
gBattleScripting.field_23 = 1;
SetMonData(mon, MON_DATA_MAX_HP, &newMaxHP);
CALC_STAT(baseAttack, attackIV, attackEV, 1, MON_DATA_ATK)
CALC_STAT(baseDefense, defenseIV, defenseEV, 2, MON_DATA_DEF)
CALC_STAT(baseSpeed, speedIV, speedEV, 3, MON_DATA_SPEED)
CALC_STAT(baseSpAttack, spAttackIV, spAttackEV, 4, MON_DATA_SPATK)
CALC_STAT(baseSpDefense, spDefenseIV, spDefenseEV, 5, MON_DATA_SPDEF)
if (species == SPECIES_SHEDINJA)
{
if (currentHP != 0 || oldMaxHP == 0)
currentHP = 1;
else
return;
}
else
{
if (currentHP == 0 && oldMaxHP == 0)
currentHP = newMaxHP;
else if (currentHP != 0)
currentHP += newMaxHP - oldMaxHP;
else
return;
}
SetMonData(mon, MON_DATA_HP, &currentHP);
}
void BoxMonToMon(const struct BoxPokemon *src, struct Pokemon *dest)
{
u32 value = 0;
dest->box = *src;
SetMonData(dest, MON_DATA_STATUS, &value);
SetMonData(dest, MON_DATA_HP, &value);
SetMonData(dest, MON_DATA_MAX_HP, &value);
value = 255;
SetMonData(dest, MON_DATA_MAIL, &value);
CalculateMonStats(dest);
}
u8 GetLevelFromMonExp(struct Pokemon *mon)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
u32 exp = GetMonData(mon, MON_DATA_EXP, NULL);
s32 level = 1;
while (level <= MAX_MON_LEVEL && gExperienceTables[gBaseStats[species].growthRate][level] <= exp)
level++;
return level - 1;
}
u8 GetLevelFromBoxMonExp(struct BoxPokemon *boxMon)
{
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
u32 exp = GetBoxMonData(boxMon, MON_DATA_EXP, NULL);
s32 level = 1;
while (level <= MAX_MON_LEVEL && gExperienceTables[gBaseStats[species].growthRate][level] <= exp)
level++;
return level - 1;
}
u16 GiveMoveToMon(struct Pokemon *mon, u16 move)
{
return GiveMoveToBoxMon(&mon->box, move);
}
u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
{
s32 i;
for (i = 0; i < 4; i++)
{
u16 existingMove = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, NULL);
if (!existingMove)
{
SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &move);
SetBoxMonData(boxMon, MON_DATA_PP1 + i, &gBattleMoves[move].pp);
return move;
}
if (existingMove == move)
return -2;
}
return -1;
}
u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move)
{
s32 i;
for (i = 0; i < 4; i++)
{
if (!mon->moves[i])
{
mon->moves[i] = move;
mon->pp[i] = gBattleMoves[move].pp;
return move;
}
}
return -1;
}
void SetMonMoveSlot(struct Pokemon *mon, u16 move, u8 slot)
{
SetMonData(mon, MON_DATA_MOVE1 + slot, &move);
SetMonData(mon, MON_DATA_PP1 + slot, &gBattleMoves[move].pp);
}
void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot)
{
mon->moves[slot] = move;
mon->pp[slot] = gBattleMoves[move].pp;
}
void GiveMonInitialMoveset(struct Pokemon *mon)
{
GiveBoxMonInitialMoveset(&mon->box);
}
void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon)
{
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
s32 level = GetLevelFromBoxMonExp(boxMon);
s32 i;
for (i = 0; gLevelUpLearnsets[species][i] != (u16)-1; i++)
{
u16 moveLevel;
u16 move;
moveLevel = (gLevelUpLearnsets[species][i] & 0xFE00);
if (moveLevel > (level << 9))
break;
move = (gLevelUpLearnsets[species][i] & 0x1FF);
if (GiveMoveToBoxMon(boxMon, move) == (u16)-1)
DeleteFirstMoveAndGiveMoveToBoxMon(boxMon, move);
}
}
u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove)
{
u32 retVal = 0;
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
u8 level = GetMonData(mon, MON_DATA_LEVEL, NULL);
// since you can learn more than one move per level
// the game needs to know whether you decided to
// learn it or keep the old set to avoid asking
// you to learn the same move over and over again
if (firstMove)
{
sLearningMoveTableID = 0;
while ((gLevelUpLearnsets[species][sLearningMoveTableID] & 0xFE00) != (level << 9))
{
sLearningMoveTableID++;
if (gLevelUpLearnsets[species][sLearningMoveTableID] == 0xFFFF)
return 0;
}
}
if ((gLevelUpLearnsets[species][sLearningMoveTableID] & 0xFE00) == (level << 9))
{
gMoveToLearn = (gLevelUpLearnsets[species][sLearningMoveTableID] & 0x1FF);
sLearningMoveTableID++;
retVal = GiveMoveToMon(mon, gMoveToLearn);
}
return retVal;
}
void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move)
{
s32 i;
u16 moves[4];
u8 pp[4];
u8 ppBonuses;
for (i = 0; i < 3; i++)
{
moves[i] = GetMonData(mon, MON_DATA_MOVE2 + i, NULL);
pp[i] = GetMonData(mon, MON_DATA_PP2 + i, NULL);
}
ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
ppBonuses >>= 2;
moves[3] = move;
pp[3] = gBattleMoves[move].pp;
for (i = 0; i < 4; i++)
{
SetMonData(mon, MON_DATA_MOVE1 + i, &moves[i]);
SetMonData(mon, MON_DATA_PP1 + i, &pp[i]);
}
SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
}
void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
{
s32 i;
u16 moves[4];
u8 pp[4];
u8 ppBonuses;
for (i = 0; i < 3; i++)
{
moves[i] = GetBoxMonData(boxMon, MON_DATA_MOVE2 + i, NULL);
pp[i] = GetBoxMonData(boxMon, MON_DATA_PP2 + i, NULL);
}
ppBonuses = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, NULL);
ppBonuses >>= 2;
moves[3] = move;
pp[3] = gBattleMoves[move].pp;
for (i = 0; i < 4; i++)
{
SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &moves[i]);
SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp[i]);
}
SetBoxMonData(boxMon, MON_DATA_PP_BONUSES, &ppBonuses);
}

View File

@ -633,7 +633,7 @@ u8 GetTrainerEncounterMusicId(u16 trainerOpponentId)
return TRAINER_ENCOUNTER_MUSIC(trainerOpponentId);
}
u16 nature_stat_mod(u8 nature, u16 n, u8 statIndex)
u16 ModifyStatByNature(u8 nature, u16 n, u8 statIndex)
{
if (statIndex < 1 || statIndex > 5)
{