diff options
author | Cleverking2003 <30466983+Cleverking2003@users.noreply.github.com> | 2020-08-28 20:03:59 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-28 20:03:59 +0300 |
commit | 98d8b5afbffbd248d3d8bd1358f1f1b9ed0f4150 (patch) | |
tree | d92f5e462b64a05b45e08e00cd17790fabb54acf /arm9/src | |
parent | 186aa237dd5d843d119a3e0e1d404fe031f89dcf (diff) | |
parent | cd2529e8855bdf5bb725b40524478cf197b27a62 (diff) |
Merge pull request #271 from PikalaxALT/pikalax_work
player_data, daycare, use_item_on_mon, item_data.json
Diffstat (limited to 'arm9/src')
-rw-r--r-- | arm9/src/daycare.c | 114 | ||||
-rw-r--r-- | arm9/src/itemtool.c | 220 | ||||
-rw-r--r-- | arm9/src/nutdata.c | 3 | ||||
-rw-r--r-- | arm9/src/player_data.c | 232 | ||||
-rw-r--r-- | arm9/src/save_arrays.c | 14 | ||||
-rw-r--r-- | arm9/src/scrcmd_18_c.c | 3 | ||||
-rw-r--r-- | arm9/src/script_pokemon_util.c | 8 | ||||
-rw-r--r-- | arm9/src/unk_020254B8.c | 114 | ||||
-rw-r--r-- | arm9/src/use_item_on_mon.c | 719 |
9 files changed, 1304 insertions, 123 deletions
diff --git a/arm9/src/daycare.c b/arm9/src/daycare.c new file mode 100644 index 00000000..eff25151 --- /dev/null +++ b/arm9/src/daycare.c @@ -0,0 +1,114 @@ +#include "global.h" +#include "pokemon.h" +#include "seals.h" +#include "save_block_2.h" +#include "daycare.h" + +#pragma thumb on + +u32 Sav2_DayCare_sizeof(void) +{ + return sizeof(struct DayCare); +} + +void Sav2_DayCare_init(struct DayCare * daycare) +{ + memset(daycare, 0, sizeof(struct DayCare)); + ZeroBoxMonData(&daycare->mons[0].mon); + ZeroBoxMonData(&daycare->mons[1].mon); + daycare->egg_pid = 0; + daycare->egg_cycles = 0; +} + +struct DayCareMon * Sav2_DayCare_GetMonX(struct DayCare * daycare, s32 i) +{ + return &daycare->mons[i]; +} + +struct BoxPokemon * DayCareMon_GetBoxMon(struct DayCareMon * dcmon) +{ + return &dcmon->mon; +} + +struct DayCareMail * DayCareMon_GetExtras(struct DayCareMon * dcmon) +{ + return &dcmon->mail; +} + +u32 DayCareMon_GetSteps(struct DayCareMon * dcmon) +{ + return dcmon->steps; +} + +struct SealStruct * DayCareMail_GetCapsule(struct DayCareMail * dcmail) +{ + return &dcmail->seal; +} + +u32 Sav2_DayCare_GetEggPID(struct DayCare * daycare) +{ + return daycare->egg_pid; +} + +u8 Sav2_DayCare_GetEggCycleCounter(struct DayCare * daycare) +{ + return daycare->egg_cycles; +} + +void DayCareMon_SetSteps(struct DayCareMon * dcmon, u32 steps) +{ + dcmon->steps = steps; +} + +void DayCareMon_AddSteps(struct DayCareMon * dcmon, u32 steps) +{ + dcmon->steps += steps; +} + +void Sav2_DayCare_SetEggPID(struct DayCare * daycare, u32 pid) +{ + daycare->egg_pid = pid; +} + +void Sav2_DayCare_SetEggCycleCounter(struct DayCare * daycare, u8 count) +{ + daycare->egg_cycles = count; +} + +BOOL Sav2_DayCare_MasudaCheck(struct DayCare * daycare) +{ + // Checks if the pokemon come from different countries. + // Uses language as a proxy for country, even though it + // only accounts for European languages and Japanese. + // If true, shiny odds are increased (see overlay 05). + return GetBoxMonData(&daycare->mons[0].mon, MON_DATA_GAME_LANGUAGE, NULL) != GetBoxMonData(&daycare->mons[1].mon, MON_DATA_GAME_LANGUAGE, NULL); +} + +void DayCareMon_Copy(struct DayCareMon * dest, const struct DayCareMon * src) +{ + *dest = *src; +} + +void DayCareMon_Extras_init(struct DayCareMail * mail) +{ + int i; + + for (i = 0; i < OT_NAME_LENGTH + 1; i++) + mail->ot_name[i] = 0; + for (i = 0; i < POKEMON_NAME_LENGTH + 1; i++) + mail->nickname[i] = 0; + mail->ot_name[0] = EOS; + mail->nickname[0] = EOS; +} + +void DayCareMon_Init(struct DayCareMon * mon) +{ + ZeroBoxMonData(&mon->mon); + mon->steps = 0; + DayCareMon_Extras_init(&mon->mail); +} + +struct DayCare * Sav2_DayCare_get(struct SaveBlock2 * sav2) +{ + return (struct DayCare *)SavArray_get(sav2, 8); +} diff --git a/arm9/src/itemtool.c b/arm9/src/itemtool.c index 9cd7552d..75785ee8 100644 --- a/arm9/src/itemtool.c +++ b/arm9/src/itemtool.c @@ -786,141 +786,141 @@ u32 GetItemAttr_PreloadedItemData(struct ItemData * itemData, u32 attr) { switch (attr) { - case 0: + case ITEMATTR_PRICE: return itemData->price; - case 1: + case ITEMATTR_HOLD_EFFECT: return itemData->holdEffect; - case 2: + case ITEMATTR_HOLD_EFFECT_PARAM: return itemData->holdEffectParam; - case 3: - return itemData->unk8_5; - case 4: - return itemData->unk8_6; - case 5: + case ITEMATTR_PREVENT_TOSS: + return itemData->prevent_toss; + case ITEMATTR_SELECTABLE: + return itemData->selectable; + case ITEMATTR_POCKET: return itemData->pocket; - case 6: + case ITEMATTR_UNKA: return itemData->unkA; - case 7: + case ITEMATTR_UNKB: return itemData->unkB; - case 8: + case ITEMATTR_UNK4: return itemData->unk4; - case 9: + case ITEMATTR_UNK5: return itemData->unk5; - case 10: + case ITEMATTR_UNK6: return itemData->unk6; - case 11: + case ITEMATTR_NATURAL_GIFT_POWER: return itemData->naturalGiftPower; - case 12: + case ITEMATTR_UNK8_0: return itemData->unk8_0; - case 13: + case ITEMATTR_UNK8_B: return itemData->unk8_B; - case 14: - return itemData->unkC; + case ITEMATTR_PARTY_USE: + return itemData->partyUse; default: - switch (itemData->unkC) + switch (itemData->partyUse) { case 0: - return itemData->unkE.flat; + return itemData->partyUseParam.flat; case 1: - return GetItemAttrSub(&itemData->unkE.sub, attr); + return GetItemAttrSub(&itemData->partyUseParam.sub, attr); default: return 0; } } } -u32 GetItemAttrSub(struct ItemDataSub * sub, u32 attr) +u32 GetItemAttrSub(struct ItemPartyUseParam * sub, u32 attr) { switch (attr) { - case 15: - return sub->unk0_0; - case 16: - return sub->unk0_1; - case 17: - return sub->unk0_2; - case 18: - return sub->unk0_3; - case 19: - return sub->unk0_4; - case 20: - return sub->unk0_5; - case 21: - return sub->unk0_6; - case 22: - return sub->unk0_7; - case 23: - return sub->unk1_0; - case 24: - return sub->unk1_1; - case 25: - return sub->unk1_2; - case 26: - return sub->unk1_3; - case 27: - return sub->unk1_4; - case 28: - return sub->unk2_0; - case 29: - return sub->unk2_4; - case 30: - return sub->unk3_0; - case 31: - return sub->unk3_4; - case 32: - return sub->unk4_0; - case 33: - return sub->unk4_4; - case 34: - return sub->unk4_6; - case 35: - return sub->unk4_7; - case 36: - return sub->unk5_0; - case 37: - return sub->unk5_1; - case 38: - return sub->unk5_2; - case 39: - return sub->unk5_3; - case 40: - return sub->unk5_4; - case 41: - return sub->unk5_5; - case 42: - return sub->unk5_6; - case 43: - return sub->unk5_7; - case 44: - return sub->unk6_0; - case 45: - return sub->unk6_1; - case 46: - return sub->unk6_2; - case 47: - return sub->unk6_3; - case 48: - return sub->unk7; - case 49: - return sub->unk8; - case 50: - return sub->unk9; - case 51: - return sub->unkA; - case 52: - return sub->unkB; - case 53: - return sub->unkC; - case 54: - return sub->unkD; - case 55: - return sub->unkE; - case 56: - return sub->unkF; - case 57: - return sub->unk10; - case 58: - return sub->unk11; + case ITEMATTR_SLP_HEAL: + return sub->slp_heal; + case ITEMATTR_PSN_HEAL: + return sub->psn_heal; + case ITEMATTR_BRN_HEAL: + return sub->brn_heal; + case ITEMATTR_FRZ_HEAL: + return sub->frz_heal; + case ITEMATTR_PRZ_HEAL: + return sub->prz_heal; + case ITEMATTR_CFS_HEAL: + return sub->cfs_heal; + case ITEMATTR_INF_HEAL: + return sub->inf_heal; + case ITEMATTR_GUARD_SPEC: + return sub->guard_spec; + case ITEMATTR_REVIVE: + return sub->revive; + case ITEMATTR_REVIVE_ALL: + return sub->revive_all; + case ITEMATTR_LEVEL_UP: + return sub->level_up; + case ITEMATTR_EVOLVE: + return sub->evolve; + case ITEMATTR_ATK_STAGES: + return sub->atk_stages; + case ITEMATTR_DEF_STAGES: + return sub->def_stages; + case ITEMATTR_SPATK_STAGES: + return sub->spatk_stages; + case ITEMATTR_SPDEF_STAGES: + return sub->spdef_stages; + case ITEMATTR_SPEED_STAGES: + return sub->speed_stages; + case ITEMATTR_ACCURACY_STAGES: + return sub->accuracy_stages; + case ITEMATTR_CRITRATE_STAGES: + return sub->critrate_stages; + case ITEMATTR_PP_UP: + return sub->pp_up; + case ITEMATTR_PP_MAX: + return sub->pp_max; + case ITEMATTR_PP_RESTORE: + return sub->pp_restore; + case ITEMATTR_PP_RESTORE_ALL: + return sub->pp_restore_all; + case ITEMATTR_HP_RESTORE: + return sub->hp_restore; + case ITEMATTR_HP_EV_UP: + return sub->hp_ev_up; + case ITEMATTR_ATK_EV_UP: + return sub->atk_ev_up; + case ITEMATTR_DEF_EV_UP: + return sub->def_ev_up; + case ITEMATTR_SPEED_EV_UP: + return sub->speed_ev_up; + case ITEMATTR_SPATK_EV_UP: + return sub->spatk_ev_up; + case ITEMATTR_SPDEF_EV_UP: + return sub->spdef_ev_up; + case ITEMATTR_FRIENDSHIP_MOD_LO: + return sub->friendship_mod_lo; + case ITEMATTR_FRIENDSHIP_MOD_MED: + return sub->friendship_mod_med; + case ITEMATTR_FRIENDSHIP_MOD_HI: + return sub->friendship_mod_hi; + case ITEMATTR_HP_EV_UP_PARAM: + return sub->hp_ev_up_param; + case ITEMATTR_ATK_EV_UP_PARAM: + return sub->atk_ev_up_param; + case ITEMATTR_DEF_EV_UP_PARAM: + return sub->def_ev_up_param; + case ITEMATTR_SPEED_EV_UP_PARAM: + return sub->speed_ev_up_param; + case ITEMATTR_SPATK_EV_UP_PARAM: + return sub->spatk_ev_up_param; + case ITEMATTR_SPDEF_EV_UP_PARAM: + return sub->spdef_ev_up_param; + case ITEMATTR_HP_RESTORE_PARAM: + return sub->hp_restore_param; + case ITEMATTR_PP_RESTORE_PARAM: + return sub->pp_restore_param; + case ITEMATTR_FRIENDSHIP_MOD_LO_PARAM: + return sub->friendship_mod_lo_param; + case ITEMATTR_FRIENDSHIP_MOD_MED_PARAM: + return sub->friendship_mod_med_param; + case ITEMATTR_FRIENDSHIP_MOD_HI_PARAM: + return sub->friendship_mod_hi_param; default: return 0; } diff --git a/arm9/src/nutdata.c b/arm9/src/nutdata.c index a8f916e2..27c600fa 100644 --- a/arm9/src/nutdata.c +++ b/arm9/src/nutdata.c @@ -1,7 +1,8 @@ #include "global.h" #include "filesystem.h" -#include "itemtool.h" +#include "nutdata.h" #include "msgdata.h" +#include "constants/items.h" #pragma thumb on diff --git a/arm9/src/player_data.c b/arm9/src/player_data.c new file mode 100644 index 00000000..ea5802aa --- /dev/null +++ b/arm9/src/player_data.c @@ -0,0 +1,232 @@ +#include "global.h" +#include "save_block_2.h" +#include "player_data.h" +#include "MI_memory.h" +#include "heap.h" +#include "string16.h" +#include "options.h" +#include "coins.h" + +#pragma thumb on + +void PlayerProfile_init(struct PlayerData * data); + +u32 Sav2_PlayerData_sizeof(void) +{ + return sizeof(struct PlayerDataSav); +} + +void Sav2_PlayerData_init(struct PlayerDataSav * pds) +{ + MI_CpuClearFast(pds, sizeof(struct PlayerDataSav)); + Options_init(&pds->options); + PlayerProfile_init(&pds->data); + InitCoins(&pds->coins); + InitIGT(&pds->igt); +} + +struct PlayerData * Sav2_PlayerData_GetProfileAddr(struct SaveBlock2 * sav2) +{ + return &((struct PlayerDataSav *)SavArray_get(sav2, 1))->data; +} + +struct Options * Sav2_PlayerData_GetOptionsAddr(struct SaveBlock2 * sav2) +{ + return &((struct PlayerDataSav *)SavArray_get(sav2, 1))->options; +} + +u16 * Sav2_PlayerData_GetCoinsAddr(struct SaveBlock2 * sav2) +{ + return &((struct PlayerDataSav *)SavArray_get(sav2, 1))->coins; +} + +struct IGT * Sav2_PlayerData_GetIGTAddr(struct SaveBlock2 * sav2) +{ + return &((struct PlayerDataSav *)SavArray_get(sav2, 1))->igt; +} + +u32 PlayerProfile_sizeof(void) +{ + return sizeof(struct PlayerData); +} + +struct PlayerData * PlayerProfile_new(u32 heap_id) +{ + struct PlayerData * ret = (struct PlayerData *)AllocFromHeap(heap_id, sizeof(struct PlayerData)); + PlayerProfile_init(ret); + return ret; +} + +void PlayerProfile_Copy(const struct PlayerData * src, struct PlayerData * dest) +{ + MI_CpuCopy8(src, dest, sizeof(struct PlayerData)); +} + +void PlayerProfile_init(struct PlayerData * data) +{ + memset(data, 0, sizeof(struct PlayerData)); + data->language = LANGUAGE_ENGLISH; +} + +void CopyPlayerName(u16 * dest, struct PlayerData * data) +{ + GF_ASSERT((s32)StringLength(data->playerName) < OT_NAME_LENGTH + 1); + CopyU16StringArray(dest, data->playerName); +} + +void PlayerName_StringToFlat(struct PlayerData * data, struct String * str) +{ + CopyStringToU16Array(str, data->playerName, OT_NAME_LENGTH + 1); +} + +u16 * PlayerProfile_GetNamePtr(struct PlayerData * data) +{ + return data->playerName; +} + +void PlayerName_FlatToString(struct PlayerData * data, struct String * str) +{ + CopyU16ArrayToString(str, data->playerName); +} + +struct String * PlayerProfile_GetPlayerName_NewString(struct PlayerData * data, u32 heap_id) +{ + struct String * str = String_ctor(OT_NAME_LENGTH + 1, heap_id); + PlayerName_FlatToString(data, str); + return str; +} + +void PlayerProfile_SetTrainerID(struct PlayerData * data, u32 otid) +{ + data->playerId = otid; +} + +u32 PlayerProfile_GetTrainerID(struct PlayerData * data) +{ + return data->playerId; +} + +u16 PlayerProfile_GetTrainerID_VisibleHalf(struct PlayerData * data) +{ + return (u16)data->playerId; +} + +void PlayerProfile_SetTrainerGender(struct PlayerData * data, u8 gender) +{ + data->gender = gender; +} + +u32 PlayerProfile_GetTrainerGender(struct PlayerData * data) +{ + return data->gender; +} + +BOOL PlayerProfile_TestBadgeFlag(struct PlayerData * data, u32 badgeno) +{ + return (data->badges & (1 << badgeno)) != 0; +} + +void PlayerProfile_SetBadgeFlag(struct PlayerData * data, u32 badgeno) +{ + data->badges |= (1 << badgeno); +} + +u32 PlayerProfile_CountBadges(struct PlayerData * data) +{ + u32 count; + u32 badges; + for (count = 0, badges = data->badges; badges != 0; badges >>= 1) + { + if (badges & 1) + count++; + } + return count; +} + +u32 PlayerProfile_GetMoney(struct PlayerData * data) +{ + return data->money; +} + +u32 PlayerProfile_SetMoney(struct PlayerData * data, u32 amount) +{ + if (amount > 999999) + amount = 999999; + data->money = amount; + return amount; +} + +u8 PlayerProfile_GetAvatar(struct PlayerData * data) +{ + return data->avatar; +} + +void PlayerProfile_SetAvatar(struct PlayerData * data, u8 avatar) +{ + data->avatar = avatar; +} + +u32 PlayerProfile_AddMoney(struct PlayerData * data, u32 amount) +{ + if (amount > 999999) + data->money = 999999; + else + data->money += amount; + if (data->money > 999999) + data->money = 999999; + return data->money; +} + +u32 PlayerProfile_SubMoney(struct PlayerData * data, u32 amount) +{ + if (data->money < amount) + data->money = 0; + else + data->money -= amount; + return data->money; +} + +u8 PlayerProfile_GetVersion(struct PlayerData * data) +{ + return data->version; +} + +void PlayerProfile_SetVersion(struct PlayerData * data, u8 a1) +{ + data->version = a1; +} + +u8 PlayerProfile_GetLanguage(struct PlayerData * data) +{ + return data->language; +} + +void PlayerProfile_SetLanguage(struct PlayerData * data, u8 language) +{ + data->language = language; +} + +void PlayerProfile_SetGameClearFlag(struct PlayerData * data) +{ + data->gameCleared = 1; +} + +BOOL PlayerProfile_GetGameClearFlag(struct PlayerData * data) +{ + return data->gameCleared; +} + +void PlayerProfile_SetNatDexFlag(struct PlayerData * data) +{ + data->nationalDex = 1; +} + +BOOL PlayerProfile_GetNatDexFlag(struct PlayerData * data) +{ + return data->nationalDex; +} + +BOOL PlayerProfile_NameAndOTIDMatchPlayer(struct PlayerData * a, struct PlayerData * b) +{ + return !StringNotEqualN(a->playerName, b->playerName, OT_NAME_LENGTH) && a->playerId == b->playerId; +} diff --git a/arm9/src/save_arrays.c b/arm9/src/save_arrays.c index 797539d2..bccdcc11 100644 --- a/arm9/src/save_arrays.c +++ b/arm9/src/save_arrays.c @@ -9,12 +9,12 @@ #include "poketch.h" #include "hall_of_fame.h" #include "unk_020286F8.h" +#include "unk_020254B8.h" +#include "daycare.h" extern u32 FUN_0202AC20(void); extern u32 FUN_02034D7C(void); -extern u32 FUN_02023D64(void); -extern u32 FUN_02023C40(void); -extern u32 FUN_020254B8(void); +extern u32 Sav2_Pokedex_sizeof(void); extern u32 FUN_02024E64(void); extern u32 FUN_02034D80(void); extern u32 FUN_02025954(void); @@ -40,9 +40,7 @@ extern u32 FUN_0202C0E0(void); extern u32 FUN_02013B28(void); extern void FUN_0202AC28(void *); extern void FUN_02034D98(void *); -extern void FUN_02024378(void *); -extern void FUN_02023C48(void *); -extern void FUN_020254CC(void *); +extern void Sav2_Pokedex_init(void *); extern void FUN_02024E6C(void *); extern void FUN_02034D88(void *); extern void FUN_0202597C(void *); @@ -80,8 +78,8 @@ const struct SaveChunkHeader UNK_020EE700[] = { { 4, 0, (SAVSIZEFN)SavArray_Flags_sizeof, (SAVINITFN)SavArray_Flags_init }, { 5, 0, (SAVSIZEFN)Sav2_Poketch_sizeof, (SAVINITFN)Sav2_Poketch_init }, { 6, 0, (SAVSIZEFN)FUN_02034D7C, (SAVINITFN)FUN_02034D98 }, - { 7, 0, (SAVSIZEFN)FUN_02023D64, (SAVINITFN)FUN_02024378 }, - { 8, 0, (SAVSIZEFN)FUN_02023C40, (SAVINITFN)FUN_02023C48 }, + { 7, 0, (SAVSIZEFN)Sav2_Pokedex_sizeof, (SAVINITFN)Sav2_Pokedex_init }, + { 8, 0, (SAVSIZEFN)Sav2_DayCare_sizeof, (SAVINITFN)Sav2_DayCare_init }, { 9, 0, (SAVSIZEFN)FUN_020254B8, (SAVINITFN)FUN_020254CC }, { 10, 0, (SAVSIZEFN)FUN_02024E64, (SAVINITFN)FUN_02024E6C }, { 11, 0, (SAVSIZEFN)FUN_02034D80, (SAVINITFN)FUN_02034D88 }, diff --git a/arm9/src/scrcmd_18_c.c b/arm9/src/scrcmd_18_c.c index d2753587..b8bbbcdd 100644 --- a/arm9/src/scrcmd_18_c.c +++ b/arm9/src/scrcmd_18_c.c @@ -4,6 +4,7 @@ #include "save_block_2.h"
#include "unk_0204639C.h"
#include "map_header.h"
+#include "scrcmd.h"
extern u16 VarGet(struct UnkStruct_0204639C* arg, u16 wk);
extern u16 *GetVarPointer(struct UnkStruct_0204639C* arg, u16);
@@ -18,6 +19,6 @@ THUMB_FUNC BOOL ScrCmd_givemon(struct ScriptContext* ctx) u16 item = VarGet(ctx->unk80, ScriptReadHalfword(ctx));
u16 * varPtr = GetVarPointer(ctx->unk80, ScriptReadHalfword(ctx));
struct PlayerParty * party = SavArray_PlayerParty_get((struct SaveBlock2 *) savePtr->unkC);
- *varPtr = GiveMon(11, (struct SaveBlock2 *) savePtr->unkC, species, level, item, mapSec, 12);
+ *varPtr = (u16)GiveMon(11, (struct SaveBlock2 *) savePtr->unkC, species, (u8)level, item, mapSec, 12);
return FALSE;
}
diff --git a/arm9/src/script_pokemon_util.c b/arm9/src/script_pokemon_util.c index fccdb15e..a3518bf4 100644 --- a/arm9/src/script_pokemon_util.c +++ b/arm9/src/script_pokemon_util.c @@ -7,6 +7,7 @@ #include "unk_02015CC0.h"
#include "unk_0202C144.h"
#include "module_05.h"
+#include "script_pokemon_util.h"
#include "constants/items.h"
#include "constants/script_pokemon_util.h"
@@ -44,6 +45,7 @@ BOOL GiveMon(u32 heap_id, struct SaveBlock2 * sav2, u16 species, u8 level, u16 i /* Seems to have something to do with Manaphy Egg*/
BOOL GiveEgg(u32 heapId, struct SaveBlock2 * sav2, u16 species, int level, int metLocIndex, int a3)
{
+#pragma unused(heapId)
struct PlayerData * data = Sav2_PlayerData_GetProfileAddr(sav2);
struct PlayerParty * party = SavArray_PlayerParty_get(sav2);
struct Pokemon * mon = AllocMonZeroed(32);
@@ -57,7 +59,7 @@ BOOL GiveEgg(u32 heapId, struct SaveBlock2 * sav2, u16 species, int level, int m void PartyMonSetMoveInSlot(struct PlayerParty * party, int partySlot, int moveSlot, u16 move)
{
struct Pokemon * mon = GetPartyMonByIndex(party, partySlot);
- MonSetMoveInSlot(mon, move, moveSlot);
+ MonSetMoveInSlot(mon, move, (u8)moveSlot);
}
int GetIdxOfFirstPartyMonWithMove(struct PlayerParty * party, int move)
@@ -114,7 +116,7 @@ struct Pokemon * GetFirstAliveMonInParty_CrashIfNone(struct PlayerParty * party) struct Pokemon * GetFirstNonEggInParty(struct PlayerParty * party)
{
u16 i;
- u16 partyCount = GetPartyCount(party);
+ u16 partyCount = (u16)GetPartyCount(party);
for (i = 0; i < partyCount; i++)
{
@@ -172,7 +174,7 @@ int ApplyPoisonStep(struct PlayerParty * party, int location) if (hp == 1)
{
numHealed++;
- MonApplyFriendshipMod(mon, FRIENDSHIP_EVENT_HEAL_FIELD_PSN, location);
+ MonApplyFriendshipMod(mon, FRIENDSHIP_EVENT_HEAL_FIELD_PSN, (u32)location);
}
numPoisoned++;
}
diff --git a/arm9/src/unk_020254B8.c b/arm9/src/unk_020254B8.c new file mode 100644 index 00000000..ed323965 --- /dev/null +++ b/arm9/src/unk_020254B8.c @@ -0,0 +1,114 @@ +#include "global.h" +#include "string_util.h" +#include "save_block_2.h" +#include "heap.h" +#include "unk_020254B8.h" + +#pragma thumb on + +u32 FUN_020254B8(void) +{ + return 16 * sizeof(struct UnkStruct_020254B8); +} + +struct UnkStruct_020254B8 * FUN_020254C0(struct SaveBlock2 * sav2) +{ + return (struct UnkStruct_020254B8 *)SavArray_get(sav2, 9); +} + +void FUN_020254CC(struct UnkStruct_020254B8 * arr) +{ + s32 i; + + for (i = 0; i < 16; i++) + { + memset(&arr[i], 0, sizeof(struct UnkStruct_020254B8)); + arr[i].field_00[0] = EOS; + } +} + +u16 * FUN_020254F0(struct UnkStruct_020254B8 * arr, s32 i) +{ + return arr[i].field_00; +} + +u8 FUN_020254F8(struct UnkStruct_020254B8 * unk, s32 i) +{ + return unk->field_68[i]; +} + +BOOL FUN_02025500(struct UnkStruct_020254B8 * a, struct UnkStruct_020254B8 * b) +{ + return !StringNotEqual(a->field_00, b->field_00) && a->field_10 == b->field_10; +} + +void FUN_02025520(struct UnkStruct_020254B8 * sp0, struct UnkStruct_020254B8 * sp4, s32 n, u32 heap_id) +{ + s32 sp18[5]; + s32 sp14; + struct UnkStruct_020254B8 * sp10; + s32 r12; + s32 spC; + s32 r4; + s32 r4_2; + + // auto buffer = new UnkStruct_020254B8[16] + sp10 = AllocFromHeap(heap_id, 16 * sizeof(struct UnkStruct_020254B8)); + FUN_020254CC(sp10); + + // Look up each element of sp4 in sp0 + for (sp14 = 0; sp14 < n; sp14++) + { + sp18[sp14] = -1; + for (r4_2 = 0; r4_2 < 16; r4_2++) + { + if (FUN_02025500(&sp0[r4_2], &sp4[sp14])) + sp18[sp14] = r4_2; + } + } + + // Copy sp4 to buffer and mask matching entries in sp0 + r4 = 0; + for (spC = 0; spC < n; spC++) + { + sp10[r4] = sp4[spC]; + if (sp18[spC] >= 0) + sp0[sp18[spC]].field_00[0] = EOS; + r4++; + } + + // Copy unmasked entries from sp0 to buffer + for (r12 = 0; r12 < 16; r12++) + { + if (sp0[r12].field_00[0] != EOS) + { + sp10[r4] = sp0[r12]; + r4++; + if (r4 >= 16) + break; + } + } + // Copy buffer to sp0 and destroy buffer + memcpy(sp0, sp10, 16 * sizeof(struct UnkStruct_020254B8)); + FreeToHeap(sp10); +} + +s32 FUN_02025614(struct UnkStruct_020254B8 * a0, u32 a1) +{ + s32 i, j; + + for (i = 0; i < 16; i++) + { + if (a1 == a0[i].field_10) + return 1; + } + for (i = 0; i < 16; i++) + { + for (j = 0; j < 16; j++) + { + if (a1 == a0[i].field_18[j]) + return i + 2; + } + } + return 0; +} diff --git a/arm9/src/use_item_on_mon.c b/arm9/src/use_item_on_mon.c new file mode 100644 index 00000000..9e11e4bf --- /dev/null +++ b/arm9/src/use_item_on_mon.c @@ -0,0 +1,719 @@ +#include "global.h" +#include "pokemon.h" +#include "heap.h" +#include "itemtool.h" +#include "move_data.h" +#include "party.h" +#include "use_item_on_mon.h" +#include "constants/moves.h" + +#pragma thumb on + +BOOL CanUseItemOnPokemon(struct Pokemon * pokemon, u16 itemId, s32 moveId, u32 heap_id) +{ + s32 atkEv; + s32 defEv; + s32 speedEv; + s32 spAtkEv; + s32 spDefEv; + s32 hpEv; + u32 hp; + struct ItemData * itemData; + u32 status; + + itemData = LoadItemDataOrGfx(itemId, ITEMDATA_DATA, heap_id); + + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PARTY_USE) != 1) + { + FreeToHeap(itemData); + return FALSE; + } + status = GetMonData(pokemon, MON_DATA_STATUS, NULL); + // slp + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SLP_HEAL) && (status & MON_STATUS_SLP_MASK)) + { + FreeToHeap(itemData); + return TRUE; + } + // psn + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PSN_HEAL) && (status & (MON_STATUS_PSN_MASK | MON_STATUS_TOX_MASK))) + { + FreeToHeap(itemData); + return TRUE; + } + // brn + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_BRN_HEAL) && (status & MON_STATUS_BRN_MASK)) + { + FreeToHeap(itemData); + return TRUE; + } + // frz + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRZ_HEAL) && (status & MON_STATUS_FRZ_MASK)) + { + FreeToHeap(itemData); + return TRUE; + } + // prz + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PRZ_HEAL) && (status & MON_STATUS_PRZ_MASK)) + { + FreeToHeap(itemData); + return TRUE; + } + hp = GetMonData(pokemon, MON_DATA_HP, NULL); + if ((GetItemAttr_PreloadedItemData(itemData, ITEMATTR_REVIVE) || GetItemAttr_PreloadedItemData(itemData, ITEMATTR_REVIVE_ALL)) && !GetItemAttr_PreloadedItemData(itemData, ITEMATTR_LEVEL_UP)) + { + if (hp == 0) + { + FreeToHeap(itemData); + return TRUE; + } + } + else if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_HP_RESTORE) &&hp != 0 && hp < GetMonData(pokemon, MON_DATA_MAXHP, NULL)) + { + FreeToHeap(itemData); + return TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_LEVEL_UP) && GetMonData(pokemon, MON_DATA_LEVEL, NULL) < MAX_LEVEL) + { + FreeToHeap(itemData); + return TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_EVOLVE) && GetMonEvolution(NULL, pokemon, 3, itemId, NULL) != SPECIES_NONE) + { + FreeToHeap(itemData); + return TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PP_UP) || GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PP_MAX)) + { + if (GetMonData(pokemon, MON_DATA_MOVE1PPUP + moveId, NULL) < 3 && WazaGetMaxPp((u16)GetMonData(pokemon, MON_DATA_MOVE1 + moveId, NULL), 0) >= 5) + { + FreeToHeap(itemData); + return TRUE; + } + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PP_RESTORE) && MonMoveCanRestorePP(pokemon, moveId) == TRUE) + { + FreeToHeap(itemData); + return TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PP_RESTORE_ALL)) + { + for (int i = 0; i < MON_MOVES; i++) + { + if (MonMoveCanRestorePP(pokemon, i) == TRUE) + { + FreeToHeap(itemData); + return TRUE; + } + } + } + hpEv = (s32)GetMonData(pokemon, MON_DATA_HP_EV, NULL); + atkEv = (s32)GetMonData(pokemon, MON_DATA_ATK_EV, NULL); + defEv = (s32)GetMonData(pokemon, MON_DATA_DEF_EV, NULL); + speedEv = (s32)GetMonData(pokemon, MON_DATA_SPEED_EV, NULL); + spAtkEv = (s32)GetMonData(pokemon, MON_DATA_SPATK_EV, NULL); + spDefEv = (s32)GetMonData(pokemon, MON_DATA_SPDEF_EV, NULL); + if (GetMonData(pokemon, MON_DATA_SPECIES, NULL) != SPECIES_SHEDINJA && GetItemAttr_PreloadedItemData(itemData, ITEMATTR_HP_EV_UP)) + { + s32 dHpEv = (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_HP_EV_UP_PARAM); + if (dHpEv > 0) + { + if (hpEv < MAX_EV && (hpEv + atkEv + defEv + speedEv + spAtkEv + spDefEv) < MAX_EV_SUM) + { + FreeToHeap(itemData); + return TRUE; + } + } + else if (dHpEv < 0) + { + if (hpEv > 0) + { + FreeToHeap(itemData); + return TRUE; + } + else if (CanItemModFriendship(pokemon, itemData) == TRUE) + { + FreeToHeap(itemData); + return TRUE; + } + } + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_ATK_EV_UP)) + { + s32 dAtkEv = (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_ATK_EV_UP_PARAM); + if (dAtkEv > 0) + { + if (atkEv < MAX_EV && (hpEv + atkEv + defEv + speedEv + spAtkEv + spDefEv) < MAX_EV_SUM) + { + FreeToHeap(itemData); + return TRUE; + } + } + else if (dAtkEv < 0) + { + if (atkEv > 0) + { + FreeToHeap(itemData); + return TRUE; + } + else if (CanItemModFriendship(pokemon, itemData) == TRUE) + { + FreeToHeap(itemData); + return TRUE; + } + } + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_DEF_EV_UP)) + { + s32 dDefEv = (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_DEF_EV_UP_PARAM); + if (dDefEv > 0) + { + if (defEv < MAX_EV && (hpEv + atkEv + defEv + speedEv + spAtkEv + spDefEv) < MAX_EV_SUM) + { + FreeToHeap(itemData); + return TRUE; + } + } + else if (dDefEv < 0) + { + if (defEv > 0) + { + FreeToHeap(itemData); + return TRUE; + } + else if (CanItemModFriendship(pokemon, itemData) == TRUE) + { + FreeToHeap(itemData); + return TRUE; + } + } + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPEED_EV_UP)) + { + s32 dSpeedEv = (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPEED_EV_UP_PARAM); + if (dSpeedEv > 0) + { + if (speedEv < MAX_EV && (hpEv + atkEv + defEv + speedEv + spAtkEv + spDefEv) < MAX_EV_SUM) + { + FreeToHeap(itemData); + return TRUE; + } + } + else if (dSpeedEv < 0) + { + if (speedEv > 0) + { + FreeToHeap(itemData); + return TRUE; + } + else if (CanItemModFriendship(pokemon, itemData) == TRUE) + { + FreeToHeap(itemData); + return TRUE; + } + } + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPATK_EV_UP)) + { + s32 dSpAtkEv = (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPATK_EV_UP_PARAM); + if (dSpAtkEv > 0) + { + if (spAtkEv < MAX_EV && (hpEv + atkEv + defEv + speedEv + spAtkEv + spDefEv) < MAX_EV_SUM) + { + FreeToHeap(itemData); + return TRUE; + } + } + else if (dSpAtkEv < 0) + { + if (spAtkEv > 0) + { + FreeToHeap(itemData); + return TRUE; + } + else if (CanItemModFriendship(pokemon, itemData) == TRUE) + { + FreeToHeap(itemData); + return TRUE; + } + } + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPDEF_EV_UP)) + { + + s32 dSpDefEv = (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPDEF_EV_UP_PARAM); + if (dSpDefEv > 0) + { + if (spDefEv < MAX_EV && (hpEv + atkEv + defEv + speedEv + spAtkEv + spDefEv) < MAX_EV_SUM) + { + FreeToHeap(itemData); + return TRUE; + } + } + else if (dSpDefEv < 0) + { + if (spDefEv > 0) + { + FreeToHeap(itemData); + return TRUE; + } + else if (CanItemModFriendship(pokemon, itemData) == TRUE) + { + FreeToHeap(itemData); + return TRUE; + } + } + } + FreeToHeap(itemData); + return FALSE; +} + +BOOL CanUseItemOnMonInParty(struct PlayerParty * party, u16 itemId, s32 partyIdx, s32 moveIdx, u32 heap_id) +{ + struct Pokemon * pokemon = GetPartyMonByIndex(party, partyIdx); + return CanUseItemOnPokemon(pokemon, itemId, moveIdx, heap_id); +} + +BOOL UseItemOnPokemon(struct Pokemon * pokemon, u16 itemId, s32 moveIdx, u16 location, u32 heap_id) +{ + s32 stack_data[8]; +#define sp6C stack_data[7] +#define sp68 stack_data[6] +#define sp64 stack_data[5] +#define sp60 stack_data[4] +#define sp5C stack_data[3] +#define sp58 stack_data[2] +#define sp54 stack_data[1] +#define sp50 stack_data[0] + BOOL hadEffect; + BOOL effectFound; + + struct ItemData * itemData = LoadItemDataOrGfx(itemId, ITEMDATA_DATA, heap_id); + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PARTY_USE) != 1) + { + FreeToHeap(itemData); + return FALSE; + } + hadEffect = FALSE; + effectFound = FALSE; + { + sp54 = sp50 = (int)GetMonData(pokemon, MON_DATA_STATUS, NULL); + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SLP_HEAL)) + { + sp54 &= ~MON_STATUS_SLP_MASK; + effectFound = TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PSN_HEAL)) + { + sp54 &= ~(MON_STATUS_PSN_MASK | MON_STATUS_TOX_MASK | 0xF00); + effectFound = TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_BRN_HEAL)) + { + sp54 &= ~MON_STATUS_BRN_MASK; + effectFound = TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRZ_HEAL)) + { + sp54 &= ~MON_STATUS_FRZ_MASK; + effectFound = TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PRZ_HEAL)) + { + sp54 &= ~MON_STATUS_PRZ_MASK; + effectFound = TRUE; + } + if (sp50 != sp54) + { + SetMonData(pokemon, MON_DATA_STATUS, &sp54); + hadEffect = TRUE; + } + } + { + sp50 = (int)GetMonData(pokemon, MON_DATA_HP, NULL); + sp54 = (int)GetMonData(pokemon, MON_DATA_MAXHP, NULL); + if ((GetItemAttr_PreloadedItemData(itemData, ITEMATTR_REVIVE) || GetItemAttr_PreloadedItemData(itemData, ITEMATTR_REVIVE_ALL)) && GetItemAttr_PreloadedItemData(itemData, ITEMATTR_LEVEL_UP)) + { + if (sp50 == 0) + { + RestoreMonHPBy(pokemon, (u32)sp50, (u32)sp54, GetItemAttr_PreloadedItemData(itemData, ITEMATTR_HP_RESTORE_PARAM)); + hadEffect = TRUE; + } + effectFound = TRUE; + } + else if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_HP_RESTORE)) + { + if (sp50 < sp54) + { + RestoreMonHPBy(pokemon, (u32)sp50, (u32)sp54, GetItemAttr_PreloadedItemData(itemData, ITEMATTR_HP_RESTORE_PARAM)); + hadEffect = TRUE; + } + effectFound = TRUE; + } + sp58 = (s32)GetMonData(pokemon, MON_DATA_LEVEL, NULL); + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_LEVEL_UP)) + { + if (sp58 < MAX_LEVEL) + { + AddMonData(pokemon, MON_DATA_EXPERIENCE, (int)CalcMonExpToNextLevel(pokemon)); + CalcMonLevelAndStats(pokemon); + if (sp50 == 0) + { + sp5C = (s32)GetMonData(pokemon, MON_DATA_MAXHP, NULL); + RestoreMonHPBy(pokemon, (u32)sp50, (u32)sp5C, (u32)(sp5C - sp54)); + } + hadEffect = TRUE; + } + effectFound = TRUE; + } + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_EVOLVE)) + effectFound = TRUE; + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PP_UP)) + { + if (BoostMonMovePpUpBy(pokemon, moveIdx, 1) == TRUE) + hadEffect = TRUE; + effectFound = TRUE; + } + else if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PP_MAX)) + { + if (BoostMonMovePpUpBy(pokemon, moveIdx, 3) == TRUE) + hadEffect = TRUE; + effectFound = TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PP_RESTORE)) + { + if (MonMoveRestorePP(pokemon, moveIdx, (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PP_RESTORE_PARAM)) == 1) + hadEffect = TRUE; + effectFound = TRUE; + } + else if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PP_RESTORE_ALL)) + { + sp50 = 0; + for (; sp50 < MON_MOVES; sp50++) + { + if (MonMoveRestorePP(pokemon, sp50, (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_PP_RESTORE_PARAM)) == 1) + hadEffect = TRUE; + } + effectFound = TRUE; + } + { + sp50 = (s32)GetMonData(pokemon, MON_DATA_HP_EV, NULL); + sp54 = (s32)GetMonData(pokemon, MON_DATA_ATK_EV, NULL); + sp58 = (s32)GetMonData(pokemon, MON_DATA_DEF_EV, NULL); + sp5C = (s32)GetMonData(pokemon, MON_DATA_SPEED_EV, NULL); + sp60 = (s32)GetMonData(pokemon, MON_DATA_SPATK_EV, NULL); + sp64 = (s32)GetMonData(pokemon, MON_DATA_SPDEF_EV, NULL); + if (GetMonData(pokemon, MON_DATA_SPECIES, NULL) != SPECIES_SHEDINJA &&GetItemAttr_PreloadedItemData(itemData, ITEMATTR_HP_EV_UP)) + { + sp6C = (int)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_HP_EV_UP_PARAM); + sp68 = TryModEV(sp50, sp54 + sp58 + sp5C + sp60 + sp64, sp6C); + if (sp68 != -1) + { + sp50 = sp68; + SetMonData(pokemon, MON_DATA_HP_EV, &sp50); + CalcMonLevelAndStats(pokemon); + hadEffect = TRUE; + } + if (sp6C > 0) + effectFound = TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_ATK_EV_UP)) + { + sp6C = (int)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_ATK_EV_UP_PARAM); + sp68 = TryModEV(sp54, sp50 + sp58 + sp5C + sp60 + sp64, sp6C); + if (sp68 != -1) + { + sp54 = sp68; + SetMonData(pokemon, MON_DATA_ATK_EV, &sp54); + CalcMonLevelAndStats(pokemon); + hadEffect = TRUE; + } + if (sp6C > 0) + effectFound = TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_DEF_EV_UP)) + { + sp6C = (int)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_DEF_EV_UP_PARAM); + sp68 = TryModEV(sp58, sp50 + sp54 + sp5C + sp60 + sp64, sp6C); + if (sp68 != -1) + { + sp58 = sp68; + SetMonData(pokemon, MON_DATA_DEF_EV, &sp58); + CalcMonLevelAndStats(pokemon); + hadEffect = TRUE; + } + if (sp6C > 0) + effectFound = TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPEED_EV_UP)) + { + sp6C = (int)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPEED_EV_UP_PARAM); + sp68 = TryModEV(sp5C, sp50 + sp54 + sp58 + sp60 + sp64, sp6C); + if (sp68 != -1) + { + sp5C = sp68; + SetMonData(pokemon, MON_DATA_SPEED_EV, &sp5C); + CalcMonLevelAndStats(pokemon); + hadEffect = TRUE; + } + if (sp6C > 0) + effectFound = TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPATK_EV_UP)) + { + sp6C = (int)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPATK_EV_UP_PARAM); + sp68 = TryModEV(sp60, sp50 + sp54 + sp58 + sp5C + sp64, sp6C); + if (sp68 != -1) + { + sp60 = sp68; + SetMonData(pokemon, MON_DATA_SPATK_EV, &sp60); + CalcMonLevelAndStats(pokemon); + hadEffect = TRUE; + } + if (sp6C > 0) + effectFound = TRUE; + } + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPDEF_EV_UP)) + { + sp6C = (int)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_SPDEF_EV_UP_PARAM); + sp68 = TryModEV(sp64, sp50 + sp54 + sp58 + sp5C + sp60, sp6C); + if (sp68 != -1) + { + sp64 = sp68; + SetMonData(pokemon, MON_DATA_SPDEF_EV, &sp64); + CalcMonLevelAndStats(pokemon); + hadEffect = TRUE; + } + if (sp6C > 0) + effectFound = TRUE; + } + } + if (hadEffect == FALSE && effectFound == TRUE) + { + FreeToHeap(itemData); + return FALSE; + } + { + sp50 = (s32)GetMonData(pokemon, MON_DATA_FRIENDSHIP, NULL); + if (sp50 < 100) + { + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_LO)) + { + DoItemFriendshipMod(pokemon, sp50, (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_LO_PARAM), location, heap_id); + FreeToHeap(itemData); + return hadEffect; + } + } + else if (sp50 >= 100 && sp50 < 200) + { + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_MED)) + { + DoItemFriendshipMod(pokemon, sp50, (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_MED_PARAM), location, heap_id); + FreeToHeap(itemData); + return hadEffect; + } + } + else if (sp50 >= 200 && sp50 <= 255) + { + if (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_HI)) + { + DoItemFriendshipMod(pokemon, sp50, (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_HI_PARAM), location, heap_id); + FreeToHeap(itemData); + return hadEffect; + } + } + } + FreeToHeap(itemData); + return hadEffect; +} +#undef sp6C +#undef sp68 +#undef sp64 +#undef sp60 +#undef sp5C +#undef sp58 +#undef sp54 +#undef sp50 + +BOOL UseItemOnMonInParty(struct PlayerParty * party, u16 itemId, s32 partyIdx, s32 moveIdx, u16 location, u32 heap_id) +{ + struct Pokemon * pokemon = GetPartyMonByIndex(party, partyIdx); + return UseItemOnPokemon(pokemon, itemId, moveIdx, location, heap_id); +} + +u8 MonMoveCanRestorePP(struct Pokemon * pokemon, s32 moveIdx) +{ + u16 move_id = (u16)GetMonData(pokemon, MON_DATA_MOVE1 + moveIdx, NULL); + if (move_id == MOVE_NONE) + return FALSE; + u8 pp = (u8)GetMonData(pokemon, MON_DATA_MOVE1PP + moveIdx, NULL); + u8 ppUp = (u8)GetMonData(pokemon, MON_DATA_MOVE1PPUP + moveIdx, NULL); + return (u8)(pp < WazaGetMaxPp(move_id, ppUp)); +} + +BOOL MonMoveRestorePP(struct Pokemon * pokemon, s32 moveIdx, s32 ppRestore) +{ + u16 move_id; + u8 pp; + u8 maxPp; + s32 ppAttr; + s32 ppUpAttr; + + move_id = (u16)GetMonData(pokemon, MON_DATA_MOVE1 + moveIdx, NULL); + if (move_id == MOVE_NONE) + return FALSE; + ppAttr = MON_DATA_MOVE1PP + moveIdx; + pp = (u8)GetMonData(pokemon, ppAttr, NULL); + ppUpAttr = MON_DATA_MOVE1PPUP + moveIdx; + maxPp = WazaGetMaxPp(move_id, (u8)GetMonData(pokemon, ppUpAttr, NULL)); + if (pp < maxPp) + { + if (ppRestore == PP_RESTORE_ALL) + pp = maxPp; + else + { + pp += ppRestore; + if (pp > maxPp) + pp = maxPp; + } + SetMonData(pokemon, ppAttr, &pp); + return TRUE; + } + return FALSE; +} + +BOOL BoostMonMovePpUpBy(struct Pokemon * pokemon, s32 moveIdx, u32 nPpUp) +{ + u16 move; + u8 pp, ppUp, maxPp, newMaxPp; + s32 ppUpAttr; + s32 ppAttr; + + ppUpAttr = MON_DATA_MOVE1PPUP + moveIdx; + ppUp = (u8)GetMonData(pokemon, ppUpAttr, NULL); + if (ppUp == 3) + return FALSE; + move = (u16)GetMonData(pokemon, MON_DATA_MOVE1 + moveIdx, NULL); + if (WazaGetMaxPp(move, 0) < 5) + return FALSE; + ppAttr = MON_DATA_MOVE1PP + moveIdx; + pp = (u8)GetMonData(pokemon, ppAttr, NULL); + maxPp = WazaGetMaxPp(move, ppUp); + if (ppUp + nPpUp > 3) + ppUp = 3; + else + ppUp = (u8)(ppUp + nPpUp); + newMaxPp = WazaGetMaxPp(move, ppUp); + pp = (u8)(pp + newMaxPp - maxPp); + SetMonData(pokemon, ppUpAttr, &ppUp); + SetMonData(pokemon, ppAttr, &pp); + return TRUE; +} + +void RestoreMonHPBy(struct Pokemon * pokemon, u32 hp, u32 maxHp, u32 restoration) +{ + if (maxHp == 1) + restoration = 1; + else if (restoration == HP_RESTORE_ALL) + restoration = maxHp; + else if (restoration == HP_RESTORE_HALF) + restoration = maxHp / 2; + else if (restoration == HP_RESTORE_QTR) + restoration = maxHp / 4; + if (hp + restoration > maxHp) + hp = maxHp; + else + hp = hp + restoration; + SetMonData(pokemon, MON_DATA_HP, &hp); +} + +s32 TryModEV(s32 ev, s32 evSum, s32 by) +{ + if (ev == 0 && by < 0) + return -1; + if (ev >= MAX_EV && by > 0) + return -1; + if (ev + evSum >= MAX_EV_SUM && by > 0) + return -1; + ev += by; + if (ev > MAX_EV) + ev = MAX_EV; + else if (ev < 0) + ev = 0; + if (ev + evSum > MAX_EV_SUM) + ev = MAX_EV_SUM - evSum; + return ev; +} + +BOOL CanItemModFriendship(struct Pokemon * pokemon, struct ItemData * itemData) +{ + s32 friendship = (s32)GetMonData(pokemon, MON_DATA_FRIENDSHIP, NULL); + if (friendship >= 255) + return FALSE; + if (friendship < 100) + { + return (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_LO) && (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_LO_PARAM) > 0); + } + if (friendship >= 100 && friendship < 200) + { + return (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_MED) && (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_MED_PARAM) > 0); + } + if (friendship >= 200 && friendship < 255) + { + return (GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_HI) && (s32)GetItemAttr_PreloadedItemData(itemData, ITEMATTR_FRIENDSHIP_MOD_HI_PARAM) > 0); + } + return FALSE; +} + +BOOL DoItemFriendshipMod(struct Pokemon * pokemon, s32 friendship, s32 mod, u16 location, u32 heap_id) +{ + if (friendship == 255 && mod > 0) + return FALSE; + if (friendship == 0 && mod < 0) + return FALSE; + if (mod > 0) + { + if (GetItemAttr((u16)GetMonData(pokemon, MON_DATA_HELD_ITEM, NULL), ITEMATTR_HOLD_EFFECT, heap_id) == HOLD_EFFECT_FRIENDSHIP_UP) + mod = mod * 150 / 100; + if (GetMonData(pokemon, MON_DATA_POKEBALL, NULL) == ITEM_LUXURY_BALL) + mod++; + if (location == GetMonData(pokemon, MON_DATA_EGG_MET_LOCATION, NULL)) + mod++; + } + mod += friendship; + if (mod > 255) + mod = 255; + if (mod < 0) + mod = 0; + SetMonData(pokemon, MON_DATA_FRIENDSHIP, &mod); + return TRUE; +} + +void HealParty(struct PlayerParty * party) +{ + u32 sp8; + s32 nmons; + s32 i; + s32 j; + + nmons = GetPartyCount(party); + for (i = 0; i < nmons; i++) + { + struct Pokemon * pokemon = GetPartyMonByIndex(party, i); + if (GetMonData(pokemon, MON_DATA_SPECIES_EXISTS, NULL)) + { + sp8 = GetMonData(pokemon, MON_DATA_MAXHP, NULL); + SetMonData(pokemon, MON_DATA_HP, &sp8); + + sp8 = 0; + SetMonData(pokemon, MON_DATA_STATUS, &sp8); + + for (j = 0; j < MON_MOVES; j++) + { + if (MonMoveCanRestorePP(pokemon, j) == 1) + MonMoveRestorePP(pokemon, j, PP_RESTORE_ALL); + } + } + } +} |