#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); } } } }