Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented a CannotUseItemsInBattle function #3524

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/item_use.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ enum {
};

bool32 CanThrowBall(void);
bool32 CannotUseItemsInBattle(u16 itemId, struct Pokemon *mon);

#endif // GUARD_ITEM_USE_H
135 changes: 82 additions & 53 deletions src/item_use.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ static void SetDistanceOfClosestHiddenItem(u8, s16, s16);
static void CB2_OpenPokeblockFromBag(void);
static void ItemUseOnFieldCB_Honey(u8 taskId);
static bool32 IsValidLocationForVsSeeker(void);
static bool32 CannotUseBagBattleItem(u16 itemId);

// EWRAM variables
EWRAM_DATA static void(*sItemUseOnFieldCB)(u8 taskId) = NULL;
Expand Down Expand Up @@ -1142,89 +1141,119 @@ void ItemUseInBattle_PartyMenuChooseMove(u8 taskId)
}

// Returns whether an item can be used in battle and sets the fail text.
static bool32 CannotUseBagBattleItem(u16 itemId)
bool32 CannotUseItemsInBattle(u16 itemId, struct Pokemon *mon)
{
u8 cannotUse = FALSE;
u16 battleUsage = ItemId_GetBattleUsage(itemId);
bool8 cannotUse = FALSE;
const u8* failStr = NULL;
u32 i;
u16 hp = GetMonData(mon, MON_DATA_HP);

// Embargo Check
if ((gPartyMenu.slotId == 0 && gStatuses3[B_POSITION_PLAYER_LEFT] & STATUS3_EMBARGO)
|| (gPartyMenu.slotId == 1 && gStatuses3[B_POSITION_PLAYER_RIGHT] & STATUS3_EMBARGO))
{
return TRUE;
}
// X-Items
if (battleUsage == EFFECT_ITEM_INCREASE_STAT
&& gBattleMons[gBattlerInMenuId].statStages[gItemEffectTable[itemId][1]] == MAX_STAT_STAGE)
{
cannotUse++;
}
// Dire Hit
if (battleUsage == EFFECT_ITEM_SET_FOCUS_ENERGY
&& (gBattleMons[gBattlerInMenuId].status2 & STATUS2_FOCUS_ENERGY))
{
cannotUse++;
}
// Guard Spec
if (battleUsage == EFFECT_ITEM_SET_MIST
&& gSideStatuses[GetBattlerSide(gBattlerInMenuId)] & SIDE_STATUS_MIST)
{
cannotUse++;
}
// Escape Items
if (battleUsage == EFFECT_ITEM_ESCAPE
&& gBattleTypeFlags & BATTLE_TYPE_TRAINER)
{
cannotUse++;
}
// Poke Balls
if (battleUsage == EFFECT_ITEM_THROW_BALL)

// battleUsage checks
switch (battleUsage)
{
case EFFECT_ITEM_INCREASE_STAT:
if (gBattleMons[gBattlerInMenuId].statStages[gItemEffectTable[itemId][1]] == MAX_STAT_STAGE)
cannotUse = TRUE;
break;
case EFFECT_ITEM_SET_FOCUS_ENERGY:
if (gBattleMons[gBattlerInMenuId].status2 & STATUS2_FOCUS_ENERGY)
cannotUse = TRUE;
break;
case EFFECT_ITEM_SET_MIST:
if (gSideStatuses[GetBattlerSide(gBattlerInMenuId)] & SIDE_STATUS_MIST)
cannotUse = TRUE;
break;
case EFFECT_ITEM_ESCAPE:
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
cannotUse = TRUE;
break;
case EFFECT_ITEM_THROW_BALL:
switch (GetBallThrowableState())
{
case BALL_THROW_UNABLE_TWO_MONS:
failStr = sText_CantThrowPokeBall_TwoMons;
cannotUse++;
break;
case BALL_THROW_UNABLE_NO_ROOM:
failStr = gText_BoxFull;
cannotUse++;
break;
case BALL_THROW_UNABLE_SEMI_INVULNERABLE:
failStr = sText_CantThrowPokeBall_SemiInvulnerable;
cannotUse++;
break;
case BALL_THROW_UNABLE_DISABLED_FLAG:
failStr = sText_CantThrowPokeBall_Disabled;
cannotUse++;
break;
case BALL_THROW_UNABLE_TWO_MONS:
failStr = sText_CantThrowPokeBall_TwoMons;
cannotUse = TRUE;
break;
case BALL_THROW_UNABLE_NO_ROOM:
failStr = gText_BoxFull;
cannotUse = TRUE;
break;
case BALL_THROW_UNABLE_SEMI_INVULNERABLE:
failStr = sText_CantThrowPokeBall_SemiInvulnerable;
cannotUse = TRUE;
break;
case BALL_THROW_UNABLE_DISABLED_FLAG:
failStr = sText_CantThrowPokeBall_Disabled;
cannotUse = TRUE;
break;
}
}
// Max Mushrooms
if (battleUsage == EFFECT_ITEM_INCREASE_ALL_STATS)
{
u32 i;
for (i = 1; i < NUM_STATS; i++)
break;
case EFFECT_ITEM_INCREASE_ALL_STATS:
for (i = STAT_ATK; i < NUM_STATS; i++)
{
if (CompareStat(gBattlerInMenuId, i, MAX_STAT_STAGE, CMP_EQUAL))
{
cannotUse++;
cannotUse = TRUE;
break;
}
}
break;
case EFFECT_ITEM_RESTORE_HP:
if (hp == 0 || hp == GetMonData(mon, MON_DATA_MAX_HP))
cannotUse = TRUE;
break;
case EFFECT_ITEM_CURE_STATUS:
if (!((GetMonData(mon, MON_DATA_STATUS) & GetItemStatus1Mask(itemId))
|| (gPartyMenu.slotId == 0 && gBattleMons[gBattlerInMenuId].status2 & GetItemStatus2Mask(itemId))))
cannotUse = TRUE;
break;
case EFFECT_ITEM_HEAL_AND_CURE_STATUS:
if ((hp == 0 || hp == GetMonData(mon, MON_DATA_MAX_HP))
&& !((GetMonData(mon, MON_DATA_STATUS) & GetItemStatus1Mask(itemId))
|| (gPartyMenu.slotId == 0 && gBattleMons[gBattlerInMenuId].status2 & GetItemStatus2Mask(itemId))))
cannotUse = TRUE;
break;
case EFFECT_ITEM_REVIVE:
if (hp != 0)
cannotUse = TRUE;
break;
case EFFECT_ITEM_RESTORE_PP:
if (GetItemEffect(itemId)[6] == ITEM4_HEAL_PP)
{
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (GetMonData(mon, MON_DATA_PP1 + i) < CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + i), GetMonData(mon, MON_DATA_PP_BONUSES), i));
break;
}
if (i == MAX_MON_MOVES)
cannotUse = TRUE;
}
else if (GetMonData(mon, MON_DATA_PP1 + gPartyMenu.data1) == CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + gPartyMenu.data1), GetMonData(mon, MON_DATA_PP_BONUSES), gPartyMenu.data1))
{
cannotUse = TRUE;
}
break;
}

if (failStr != NULL)
StringExpandPlaceholders(gStringVar4, failStr);
else
StringExpandPlaceholders(gStringVar4, gText_WontHaveEffect);

return cannotUse;
}

void ItemUseInBattle_BagMenu(u8 taskId)
{
if (CannotUseBagBattleItem(gSpecialVar_ItemId))
if (CannotUseItemsInBattle(gSpecialVar_ItemId, NULL))
{
if (!InBattlePyramid())
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage);
Expand Down
64 changes: 2 additions & 62 deletions src/party_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,6 @@ static bool8 SetUpFieldMove_Dive(void);
void TryItemHoldFormChange(struct Pokemon *mon);
static void ShowMoveSelectWindow(u8 slot);
static void Task_HandleWhichMoveInput(u8 taskId);
static bool32 CannotUsePartyBattleItem(u16 itemId, struct Pokemon* mon);

// static const data
#include "data/party_menu.h"
Expand Down Expand Up @@ -4557,70 +4556,11 @@ static bool8 IsItemFlute(u16 item)
return FALSE;
}

static bool32 CannotUsePartyBattleItem(u16 itemId, struct Pokemon* mon)
{
u8 i;
u8 cannotUse = FALSE;
u16 battleUsage = ItemId_GetBattleUsage(itemId);
u16 hp = GetMonData(mon, MON_DATA_HP);

// Embargo Check
if ((gPartyMenu.slotId == 0 && gStatuses3[B_POSITION_PLAYER_LEFT] & STATUS3_EMBARGO)
|| (gPartyMenu.slotId == 1 && gStatuses3[B_POSITION_PLAYER_RIGHT] & STATUS3_EMBARGO))
{
return FALSE;
}
// Items that restore HP (Potions, Sitrus Berry, etc.)
if (battleUsage == EFFECT_ITEM_RESTORE_HP && (hp == 0 || hp == GetMonData(mon, MON_DATA_MAX_HP)))
{
cannotUse++;
}
// Items that cure status (Burn Heal, Awakening, etc.)
if (battleUsage == EFFECT_ITEM_CURE_STATUS
&& !((GetMonData(mon, MON_DATA_STATUS) & GetItemStatus1Mask(itemId))
|| (gPartyMenu.slotId == 0 && gBattleMons[gBattlerInMenuId].status2 & GetItemStatus2Mask(itemId))))
{
cannotUse++;
}
// Items that restore HP and cure status (Full Restore)
if (battleUsage == EFFECT_ITEM_HEAL_AND_CURE_STATUS
&& (hp == 0 || hp == GetMonData(mon, MON_DATA_MAX_HP))
&& !((GetMonData(mon, MON_DATA_STATUS) & GetItemStatus1Mask(itemId))
|| (gPartyMenu.slotId == 0 && gBattleMons[gBattlerInMenuId].status2 & GetItemStatus2Mask(itemId))))
{
cannotUse++;
}
// Items that revive a party member
if (battleUsage == EFFECT_ITEM_REVIVE && hp != 0)
{
cannotUse++;
}
// Items that restore PP (Elixir, Ether, Leppa Berry)
if (battleUsage == EFFECT_ITEM_RESTORE_PP)
{
if (GetItemEffect(itemId)[6] == ITEM4_HEAL_PP)
{
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (GetMonData(mon, MON_DATA_PP1 + i) < CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + i), GetMonData(mon, MON_DATA_PP_BONUSES), i));
break;
}
if (i == MAX_MON_MOVES)
cannotUse++;
}
else if (GetMonData(mon, MON_DATA_PP1 + gPartyMenu.data1) == CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + gPartyMenu.data1), GetMonData(mon, MON_DATA_PP_BONUSES), gPartyMenu.data1))
{
cannotUse++;
}
}
return cannotUse;
}

// Battle scripts called in HandleAction_UseItem
void ItemUseCB_BattleScript(u8 taskId, TaskFunc task)
{
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
if (CannotUsePartyBattleItem(gSpecialVar_ItemId, mon))
if (CannotUseItemsInBattle(gSpecialVar_ItemId, mon))
{
gPartyMenuUseExitCallback = FALSE;
PlaySE(SE_SELECT);
Expand Down Expand Up @@ -5129,7 +5069,7 @@ static void TryUseItemOnMove(u8 taskId)
// In battle, set appropriate variables to be used in battle script.
if (gMain.inBattle)
{
if (CannotUsePartyBattleItem(gSpecialVar_ItemId, mon))
if (CannotUseItemsInBattle(gSpecialVar_ItemId, mon))
{
gPartyMenuUseExitCallback = FALSE;
PlaySE(SE_SELECT);
Expand Down
Loading