mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 03:34:15 +01:00
Battle Item Refactor (#2902)
* items that can be used in battle now use battlescripts * removed ExecuteTableBasedItemEffect_ * taught AI how to use items, removed AI_itemtype/flag * X-Items store stages raised in holdEffectParam * USE_ITEM in tests
This commit is contained in:
parent
48fba7a35c
commit
2eabcea86e
@ -1330,6 +1330,22 @@
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro itemrestorehp
|
||||
callnative BS_ItemRestoreHP
|
||||
.endm
|
||||
|
||||
.macro itemcurestatus
|
||||
callnative BS_ItemCureStatus
|
||||
.endm
|
||||
|
||||
.macro itemincreasestat
|
||||
callnative BS_ItemIncreaseStat
|
||||
.endm
|
||||
|
||||
.macro itemrestorepp
|
||||
callnative BS_ItemRestorePP
|
||||
.endm
|
||||
|
||||
@ various command changed to more readable macros
|
||||
.macro cancelmultiturnmoves battler:req
|
||||
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES
|
||||
|
@ -3,219 +3,256 @@
|
||||
#include "constants/battle_script_commands.h"
|
||||
#include "constants/battle_anim.h"
|
||||
#include "constants/battle_string_ids.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/moves.h"
|
||||
#include "constants/songs.h"
|
||||
#include "constants/game_stat.h"
|
||||
.include "asm/macros.inc"
|
||||
.include "asm/macros/battle_script.inc"
|
||||
.include "constants/constants.inc"
|
||||
.include "asm/macros.inc"
|
||||
.include "asm/macros/battle_script.inc"
|
||||
.include "constants/constants.inc"
|
||||
|
||||
.section script_data, "aw", %progbits
|
||||
.section script_data, "aw", %progbits
|
||||
|
||||
.align 2
|
||||
.align 2
|
||||
gBattlescriptsForUsingItem::
|
||||
.4byte BattleScript_PlayerUsesItem
|
||||
.4byte BattleScript_OpponentUsesHealItem @ AI_ITEM_FULL_RESTORE
|
||||
.4byte BattleScript_OpponentUsesHealItem @ AI_ITEM_HEAL_HP
|
||||
.4byte BattleScript_OpponentUsesStatusCureItem @ AI_ITEM_CURE_CONDITION
|
||||
.4byte BattleScript_OpponentUsesXItem @ AI_ITEM_X_STAT
|
||||
.4byte BattleScript_OpponentUsesGuardSpec @ AI_ITEM_GUARD_SPEC
|
||||
.4byte BattleScript_ItemRestoreHP @ EFFECT_ITEM_RESTORE_HP
|
||||
.4byte BattleScript_ItemCureStatus @ EFFECT_ITEM_CURE_STATUS
|
||||
.4byte BattleScript_ItemHealAndCureStatus @ EFFECT_ITEM_HEAL_AND_CURE_STATUS
|
||||
.4byte BattleScript_ItemIncreaseStat @ EFFECT_ITEM_INCREASE_STAT
|
||||
.4byte BattleScript_ItemSetMist @ EFFECT_ITEM_SET_MIST
|
||||
.4byte BattleScript_ItemSetFocusEnergy @ EFFECT_ITEM_SET_FOCUS_ENERGY
|
||||
.4byte BattleScript_RunByUsingItem @ EFFECT_ITEM_ESCAPE
|
||||
.4byte BattleScript_BallThrow @ EFFECT_ITEM_THROW_BALL
|
||||
.4byte BattleScript_ItemRestoreHP @ EFFECT_ITEM_REVIVE
|
||||
.4byte BattleScript_ItemRestorePP @ EFFECT_ITEM_RESTORE_PP
|
||||
.4byte BattleScript_ItemIncreaseAllStats @ EFFECT_ITEM_INCREASE_ALL_STATS
|
||||
|
||||
.align 2
|
||||
gBattlescriptsForRunningByItem::
|
||||
.4byte BattleScript_RunByUsingItem
|
||||
|
||||
.align 2
|
||||
.align 2
|
||||
gBattlescriptsForSafariActions::
|
||||
.4byte BattleScript_ActionWatchesCarefully
|
||||
.4byte BattleScript_ActionGetNear
|
||||
.4byte BattleScript_ActionThrowPokeblock
|
||||
.4byte BattleScript_ActionWallyThrow
|
||||
.4byte BattleScript_ActionWatchesCarefully
|
||||
.4byte BattleScript_ActionGetNear
|
||||
.4byte BattleScript_ActionThrowPokeblock
|
||||
.4byte BattleScript_ActionWallyThrow
|
||||
|
||||
BattleScript_ItemEnd:
|
||||
end
|
||||
|
||||
BattleScript_UseItemMessage:
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
pause B_WAIT_TIME_MED
|
||||
playse SE_USE_ITEM
|
||||
getbattlerside BS_ATTACKER
|
||||
copybyte cMULTISTRING_CHOOSER, gBattleCommunication
|
||||
printfromtable gTrainerUsedItemStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_ItemRestoreHP::
|
||||
call BattleScript_UseItemMessage
|
||||
itemrestorehp
|
||||
printstring STRINGID_ITEMRESTOREDSPECIESHEALTH
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_ItemRestoreHP_SendOutRevivedBattler
|
||||
bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
|
||||
healthbarupdate BS_ATTACKER
|
||||
datahpupdate BS_ATTACKER
|
||||
updatestatusicon BS_ATTACKER
|
||||
end
|
||||
|
||||
BattleScript_ItemRestoreHP_SendOutRevivedBattler:
|
||||
switchinanim BS_ATTACKER, FALSE
|
||||
waitstate
|
||||
switchineffects BS_ATTACKER
|
||||
end
|
||||
|
||||
BattleScript_ItemCureStatus::
|
||||
call BattleScript_UseItemMessage
|
||||
itemcurestatus
|
||||
printstring STRINGID_ITEMCUREDSPECIESSTATUS
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
updatestatusicon BS_ATTACKER
|
||||
end
|
||||
|
||||
BattleScript_ItemHealAndCureStatus::
|
||||
call BattleScript_UseItemMessage
|
||||
itemrestorehp
|
||||
curestatus BS_ATTACKER
|
||||
printstring STRINGID_ITEMRESTOREDSPECIESHEALTH
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
|
||||
healthbarupdate BS_ATTACKER
|
||||
datahpupdate BS_ATTACKER
|
||||
updatestatusicon BS_ATTACKER
|
||||
end
|
||||
|
||||
BattleScript_ItemIncreaseStat::
|
||||
call BattleScript_UseItemMessage
|
||||
itemincreasestat
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_ItemEnd
|
||||
setgraphicalstatchangevalues
|
||||
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end
|
||||
|
||||
BattleScript_ItemSetMist::
|
||||
call BattleScript_UseItemMessage
|
||||
setmist
|
||||
playmoveanimation BS_ATTACKER, MOVE_MIST
|
||||
waitanimation
|
||||
printfromtable gMistUsedStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end
|
||||
|
||||
BattleScript_ItemSetFocusEnergy::
|
||||
call BattleScript_UseItemMessage
|
||||
jumpifstatus2 BS_ATTACKER, STATUS2_FOCUS_ENERGY, BattleScript_ButItFailed
|
||||
setfocusenergy
|
||||
playmoveanimation BS_ATTACKER, MOVE_FOCUS_ENERGY
|
||||
waitanimation
|
||||
printstring STRINGID_PKMNUSEDXTOGETPUMPED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end
|
||||
|
||||
BattleScript_ItemRestorePP::
|
||||
call BattleScript_UseItemMessage
|
||||
itemrestorepp
|
||||
printstring STRINGID_ITEMRESTOREDSPECIESPP
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end
|
||||
|
||||
BattleScript_ItemIncreaseAllStats::
|
||||
call BattleScript_UseItemMessage
|
||||
call BattleScript_AllStatsUp
|
||||
end
|
||||
|
||||
BattleScript_BallThrow::
|
||||
jumpifword CMP_COMMON_BITS, gBattleTypeFlags, BATTLE_TYPE_WALLY_TUTORIAL, BattleScript_BallThrowByWally
|
||||
printstring STRINGID_PLAYERUSEDITEM
|
||||
handleballthrow
|
||||
jumpifword CMP_COMMON_BITS, gBattleTypeFlags, BATTLE_TYPE_WALLY_TUTORIAL, BattleScript_BallThrowByWally
|
||||
printstring STRINGID_PLAYERUSEDITEM
|
||||
handleballthrow
|
||||
|
||||
BattleScript_BallThrowByWally::
|
||||
printstring STRINGID_WALLYUSEDITEM
|
||||
handleballthrow
|
||||
printstring STRINGID_WALLYUSEDITEM
|
||||
handleballthrow
|
||||
|
||||
BattleScript_SafariBallThrow::
|
||||
printstring STRINGID_PLAYERUSEDITEM
|
||||
updatestatusicon BS_ATTACKER
|
||||
handleballthrow
|
||||
printstring STRINGID_PLAYERUSEDITEM
|
||||
updatestatusicon BS_ATTACKER
|
||||
handleballthrow
|
||||
|
||||
BattleScript_SuccessBallThrow::
|
||||
setbyte sMON_CAUGHT, TRUE
|
||||
incrementgamestat GAME_STAT_POKEMON_CAPTURES
|
||||
setbyte sMON_CAUGHT, TRUE
|
||||
incrementgamestat GAME_STAT_POKEMON_CAPTURES
|
||||
BattleScript_PrintCaughtMonInfo::
|
||||
printstring STRINGID_GOTCHAPKMNCAUGHTPLAYER
|
||||
jumpifbyte CMP_NOT_EQUAL, sEXP_CATCH, TRUE, BattleScript_TryPrintCaughtMonInfo
|
||||
setbyte sGIVEEXP_STATE, 0
|
||||
getexp BS_TARGET
|
||||
sethword gBattle_BG2_X, 0
|
||||
printstring STRINGID_GOTCHAPKMNCAUGHTPLAYER
|
||||
jumpifbyte CMP_NOT_EQUAL, sEXP_CATCH, TRUE, BattleScript_TryPrintCaughtMonInfo
|
||||
setbyte sGIVEEXP_STATE, 0
|
||||
getexp BS_TARGET
|
||||
sethword gBattle_BG2_X, 0
|
||||
BattleScript_TryPrintCaughtMonInfo:
|
||||
trysetcaughtmondexflags BattleScript_TryNicknameCaughtMon
|
||||
printstring STRINGID_PKMNDATAADDEDTODEX
|
||||
waitstate
|
||||
setbyte gBattleCommunication, 0
|
||||
displaydexinfo
|
||||
trysetcaughtmondexflags BattleScript_TryNicknameCaughtMon
|
||||
printstring STRINGID_PKMNDATAADDEDTODEX
|
||||
waitstate
|
||||
setbyte gBattleCommunication, 0
|
||||
displaydexinfo
|
||||
BattleScript_TryNicknameCaughtMon::
|
||||
printstring STRINGID_GIVENICKNAMECAPTURED
|
||||
waitstate
|
||||
setbyte gBattleCommunication, 0
|
||||
trygivecaughtmonnick BattleScript_GiveCaughtMonEnd
|
||||
givecaughtmon
|
||||
printfromtable gCaughtMonStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_SuccessBallThrowEnd
|
||||
printstring STRINGID_GIVENICKNAMECAPTURED
|
||||
waitstate
|
||||
setbyte gBattleCommunication, 0
|
||||
trygivecaughtmonnick BattleScript_GiveCaughtMonEnd
|
||||
givecaughtmon
|
||||
printfromtable gCaughtMonStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_SuccessBallThrowEnd
|
||||
BattleScript_GiveCaughtMonEnd::
|
||||
givecaughtmon
|
||||
givecaughtmon
|
||||
BattleScript_SuccessBallThrowEnd::
|
||||
setbyte gBattleOutcome, B_OUTCOME_CAUGHT
|
||||
finishturn
|
||||
setbyte gBattleOutcome, B_OUTCOME_CAUGHT
|
||||
finishturn
|
||||
|
||||
BattleScript_WallyBallThrow::
|
||||
printstring STRINGID_GOTCHAPKMNCAUGHTWALLY
|
||||
setbyte gBattleOutcome, B_OUTCOME_CAUGHT
|
||||
finishturn
|
||||
printstring STRINGID_GOTCHAPKMNCAUGHTWALLY
|
||||
setbyte gBattleOutcome, B_OUTCOME_CAUGHT
|
||||
finishturn
|
||||
|
||||
BattleScript_ShakeBallThrow::
|
||||
printfromtable gBallEscapeStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
jumpifword CMP_NO_COMMON_BITS, gBattleTypeFlags, BATTLE_TYPE_SAFARI, BattleScript_ShakeBallThrowEnd
|
||||
jumpifbyte CMP_NOT_EQUAL, gNumSafariBalls, 0, BattleScript_ShakeBallThrowEnd
|
||||
printstring STRINGID_OUTOFSAFARIBALLS
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
setbyte gBattleOutcome, B_OUTCOME_NO_SAFARI_BALLS
|
||||
printfromtable gBallEscapeStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
jumpifword CMP_NO_COMMON_BITS, gBattleTypeFlags, BATTLE_TYPE_SAFARI, BattleScript_ShakeBallThrowEnd
|
||||
jumpifbyte CMP_NOT_EQUAL, gNumSafariBalls, 0, BattleScript_ShakeBallThrowEnd
|
||||
printstring STRINGID_OUTOFSAFARIBALLS
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
setbyte gBattleOutcome, B_OUTCOME_NO_SAFARI_BALLS
|
||||
BattleScript_ShakeBallThrowEnd::
|
||||
finishaction
|
||||
finishaction
|
||||
|
||||
BattleScript_TrainerBallBlock::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
printstring STRINGID_TRAINERBLOCKEDBALL
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
printstring STRINGID_DONTBEATHIEF
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
finishaction
|
||||
|
||||
BattleScript_PlayerUsesItem::
|
||||
moveendcase MOVEEND_MIRROR_MOVE
|
||||
end
|
||||
|
||||
BattleScript_OpponentUsesHealItem::
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
pause B_WAIT_TIME_MED
|
||||
playse SE_USE_ITEM
|
||||
printstring STRINGID_TRAINER1USEDITEM
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
|
||||
useitemonopponent
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
|
||||
healthbarupdate BS_ATTACKER
|
||||
datahpupdate BS_ATTACKER
|
||||
printstring STRINGID_PKMNSITEMRESTOREDHEALTH
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
updatestatusicon BS_ATTACKER
|
||||
moveendcase MOVEEND_MIRROR_MOVE
|
||||
finishaction
|
||||
|
||||
BattleScript_OpponentUsesStatusCureItem::
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
pause B_WAIT_TIME_MED
|
||||
playse SE_USE_ITEM
|
||||
printstring STRINGID_TRAINER1USEDITEM
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
useitemonopponent
|
||||
printfromtable gTrainerItemCuredStatusStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
updatestatusicon BS_ATTACKER
|
||||
moveendcase MOVEEND_MIRROR_MOVE
|
||||
finishaction
|
||||
|
||||
BattleScript_OpponentUsesXItem::
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
pause B_WAIT_TIME_MED
|
||||
playse SE_USE_ITEM
|
||||
printstring STRINGID_TRAINER1USEDITEM
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
useitemonopponent
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
moveendcase MOVEEND_MIRROR_MOVE
|
||||
finishaction
|
||||
|
||||
BattleScript_OpponentUsesGuardSpec::
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
pause B_WAIT_TIME_MED
|
||||
playse SE_USE_ITEM
|
||||
printstring STRINGID_TRAINER1USEDITEM
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
useitemonopponent
|
||||
printfromtable gMistUsedStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
moveendcase MOVEEND_MIRROR_MOVE
|
||||
finishaction
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
printstring STRINGID_TRAINERBLOCKEDBALL
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
printstring STRINGID_DONTBEATHIEF
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
finishaction
|
||||
|
||||
BattleScript_RunByUsingItem::
|
||||
playse SE_FLEE
|
||||
setbyte gBattleOutcome, B_OUTCOME_RAN
|
||||
finishturn
|
||||
playse SE_FLEE
|
||||
setbyte gBattleOutcome, B_OUTCOME_RAN
|
||||
finishturn
|
||||
|
||||
BattleScript_ActionWatchesCarefully:
|
||||
printstring STRINGID_PKMNWATCHINGCAREFULLY
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
printstring STRINGID_PKMNWATCHINGCAREFULLY
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
|
||||
BattleScript_ActionGetNear:
|
||||
printfromtable gSafariGetNearStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
printfromtable gSafariGetNearStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
|
||||
BattleScript_ActionThrowPokeblock:
|
||||
printstring STRINGID_THREWPOKEBLOCKATPKMN
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
playanimation BS_ATTACKER, B_ANIM_POKEBLOCK_THROW, NULL
|
||||
printfromtable gSafariPokeblockResultStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
printstring STRINGID_THREWPOKEBLOCKATPKMN
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
playanimation BS_ATTACKER, B_ANIM_POKEBLOCK_THROW, NULL
|
||||
printfromtable gSafariPokeblockResultStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
|
||||
BattleScript_ActionWallyThrow:
|
||||
printstring STRINGID_RETURNMON
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
returnatktoball
|
||||
waitstate
|
||||
trainerslidein BS_TARGET
|
||||
waitstate
|
||||
printstring STRINGID_YOUTHROWABALLNOWRIGHT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
printstring STRINGID_RETURNMON
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
returnatktoball
|
||||
waitstate
|
||||
trainerslidein BS_TARGET
|
||||
waitstate
|
||||
printstring STRINGID_YOUTHROWABALLNOWRIGHT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
|
||||
BattleScript_TrainerASlideMsgRet::
|
||||
handletrainerslidemsg BS_SCRIPTING, 0
|
||||
trainerslidein B_POSITION_OPPONENT_LEFT
|
||||
handletrainerslidemsg BS_SCRIPTING, 1
|
||||
waitstate
|
||||
trainerslideout B_POSITION_OPPONENT_LEFT
|
||||
waitstate
|
||||
handletrainerslidemsg BS_SCRIPTING, 2
|
||||
return
|
||||
handletrainerslidemsg BS_SCRIPTING, 0
|
||||
trainerslidein B_POSITION_OPPONENT_LEFT
|
||||
handletrainerslidemsg BS_SCRIPTING, 1
|
||||
waitstate
|
||||
trainerslideout B_POSITION_OPPONENT_LEFT
|
||||
waitstate
|
||||
handletrainerslidemsg BS_SCRIPTING, 2
|
||||
return
|
||||
|
||||
BattleScript_TrainerASlideMsgEnd2::
|
||||
call BattleScript_TrainerASlideMsgRet
|
||||
end2
|
||||
call BattleScript_TrainerASlideMsgRet
|
||||
end2
|
||||
|
||||
BattleScript_TrainerBSlideMsgRet::
|
||||
handletrainerslidemsg BS_SCRIPTING, 0
|
||||
trainerslidein B_POSITION_OPPONENT_RIGHT
|
||||
handletrainerslidemsg BS_SCRIPTING, 1
|
||||
waitstate
|
||||
trainerslideout B_POSITION_OPPONENT_RIGHT
|
||||
waitstate
|
||||
handletrainerslidemsg BS_SCRIPTING, 2
|
||||
return
|
||||
handletrainerslidemsg BS_SCRIPTING, 0
|
||||
trainerslidein B_POSITION_OPPONENT_RIGHT
|
||||
handletrainerslidemsg BS_SCRIPTING, 1
|
||||
waitstate
|
||||
trainerslideout B_POSITION_OPPONENT_RIGHT
|
||||
waitstate
|
||||
handletrainerslidemsg BS_SCRIPTING, 2
|
||||
return
|
||||
|
||||
BattleScript_TrainerBSlideMsgEnd2::
|
||||
call BattleScript_TrainerBSlideMsgRet
|
||||
end2
|
||||
call BattleScript_TrainerBSlideMsgRet
|
||||
end2
|
||||
|
@ -581,8 +581,6 @@ struct BattleStruct
|
||||
void (*savedCallback)(void);
|
||||
u16 usedHeldItems[PARTY_SIZE][NUM_BATTLE_SIDES]; // For each party member and side. For harvest, recycle
|
||||
u16 chosenItem[MAX_BATTLERS_COUNT];
|
||||
u8 AI_itemType[2];
|
||||
u8 AI_itemFlags[2];
|
||||
u16 choicedMove[MAX_BATTLERS_COUNT];
|
||||
u16 changedItems[MAX_BATTLERS_COUNT];
|
||||
u8 switchInItemsCounter;
|
||||
@ -662,6 +660,7 @@ struct BattleStruct
|
||||
u8 storedHealingWish:4; // Each battler as a bit.
|
||||
u8 storedLunarDance:4; // Each battler as a bit.
|
||||
u16 supremeOverlordModifier[MAX_BATTLERS_COUNT];
|
||||
u8 itemPartyIndex[MAX_BATTLERS_COUNT];
|
||||
};
|
||||
|
||||
#define F_DYNAMIC_TYPE_1 (1 << 6)
|
||||
|
@ -1,36 +1,6 @@
|
||||
#ifndef GUARD_BATTLE_AI_SWITCH_ITEMS_H
|
||||
#define GUARD_BATTLE_AI_SWITCH_ITEMS_H
|
||||
|
||||
enum
|
||||
{
|
||||
AI_ITEM_FULL_RESTORE = 1,
|
||||
AI_ITEM_HEAL_HP,
|
||||
AI_ITEM_CURE_CONDITION,
|
||||
AI_ITEM_X_STAT,
|
||||
AI_ITEM_GUARD_SPEC,
|
||||
AI_ITEM_NOT_RECOGNIZABLE
|
||||
};
|
||||
|
||||
enum {
|
||||
AI_HEAL_CONFUSION,
|
||||
AI_HEAL_PARALYSIS,
|
||||
AI_HEAL_FREEZE,
|
||||
AI_HEAL_BURN,
|
||||
AI_HEAL_POISON,
|
||||
AI_HEAL_SLEEP,
|
||||
};
|
||||
|
||||
enum {
|
||||
AI_X_ATTACK,
|
||||
AI_X_DEFEND,
|
||||
AI_X_SPEED,
|
||||
AI_X_SPATK,
|
||||
AI_X_SPDEF, // Unused
|
||||
AI_X_ACCURACY,
|
||||
AI_X_EVASION, // Unused
|
||||
AI_DIRE_HIT,
|
||||
};
|
||||
|
||||
void GetAIPartyIndexes(u32 battlerId, s32 *firstId, s32 *lastId);
|
||||
void AI_TrySwitchOrUseItem(void);
|
||||
u8 GetMostSuitableMonToSwitchInto(void);
|
||||
|
@ -648,8 +648,11 @@
|
||||
#define STRINGID_COULDNTFULLYPROTECT 646
|
||||
#define STRINGID_STOCKPILEDEFFECTWOREOFF 647
|
||||
#define STRINGID_PKMNREVIVEDREADYTOFIGHT 648
|
||||
#define STRINGID_ITEMRESTOREDSPECIESHEALTH 649
|
||||
#define STRINGID_ITEMCUREDSPECIESSTATUS 650
|
||||
#define STRINGID_ITEMRESTOREDSPECIESPP 651
|
||||
|
||||
#define BATTLESTRINGS_COUNT 649
|
||||
#define BATTLESTRINGS_COUNT 652
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
|
@ -7,12 +7,12 @@
|
||||
#define ITEM0_INFATUATION 0x80
|
||||
|
||||
// new field 1 masks
|
||||
#define ITEM1_X_ATTACK 0x1
|
||||
#define ITEM1_X_DEFENSE 0x2
|
||||
#define ITEM1_X_SPEED 0x4
|
||||
#define ITEM1_X_SPATK 0x8
|
||||
#define ITEM1_X_SPDEF 0x10
|
||||
#define ITEM1_X_ACCURACY 0x20
|
||||
#define ITEM1_X_ATTACK STAT_ATK
|
||||
#define ITEM1_X_DEFENSE STAT_DEF
|
||||
#define ITEM1_X_SPEED STAT_SPEED
|
||||
#define ITEM1_X_SPATK STAT_SPATK
|
||||
#define ITEM1_X_SPDEF STAT_SPDEF
|
||||
#define ITEM1_X_ACCURACY STAT_ACC
|
||||
|
||||
// field 3 masks
|
||||
#define ITEM3_CONFUSION 0x1
|
||||
|
@ -1030,14 +1030,27 @@
|
||||
#define EXP_30000 5
|
||||
|
||||
// Item type IDs (used to determine the exit callback)
|
||||
#define ITEM_USE_MAIL 0
|
||||
#define ITEM_USE_PARTY_MENU 1
|
||||
#define ITEM_USE_FIELD 2
|
||||
#define ITEM_USE_PBLOCK_CASE 3
|
||||
#define ITEM_USE_BAG_MENU 4 // No exit callback, stays in bag menu
|
||||
#define ITEM_USE_MAIL 0
|
||||
#define ITEM_USE_PARTY_MENU 1
|
||||
#define ITEM_USE_FIELD 2
|
||||
#define ITEM_USE_PBLOCK_CASE 3
|
||||
#define ITEM_USE_BAG_MENU 4 // No exit callback, stays in bag menu
|
||||
#define ITEM_USE_PARTY_MENU_MOVES 5
|
||||
|
||||
// Item battle usage IDs (only checked to see if nonzero)
|
||||
#define ITEM_B_USE_MEDICINE 1
|
||||
#define ITEM_B_USE_OTHER 2
|
||||
// Item battle script IDs (need to be non-zero)
|
||||
#define EFFECT_ITEM_RESTORE_HP 1
|
||||
#define EFFECT_ITEM_CURE_STATUS 2
|
||||
#define EFFECT_ITEM_HEAL_AND_CURE_STATUS 3
|
||||
#define EFFECT_ITEM_INCREASE_STAT 4
|
||||
#define EFFECT_ITEM_SET_MIST 5
|
||||
#define EFFECT_ITEM_SET_FOCUS_ENERGY 6
|
||||
#define EFFECT_ITEM_ESCAPE 7
|
||||
#define EFFECT_ITEM_THROW_BALL 8
|
||||
#define EFFECT_ITEM_REVIVE 9
|
||||
#define EFFECT_ITEM_RESTORE_PP 10
|
||||
#define EFFECT_ITEM_INCREASE_ALL_STATS 11
|
||||
|
||||
// Enigma Berry dummy constant
|
||||
#define EFFECT_ITEM_ENIGMA_BERRY_EREADER 1
|
||||
|
||||
#endif // GUARD_CONSTANTS_ITEMS_H
|
||||
|
@ -19,7 +19,6 @@ struct Item
|
||||
u8 type;
|
||||
ItemUseFunc fieldUseFunc;
|
||||
u8 battleUsage;
|
||||
ItemUseFunc battleUseFunc;
|
||||
u8 secondaryId;
|
||||
u8 flingPower;
|
||||
};
|
||||
@ -72,8 +71,9 @@ u8 ItemId_GetPocket(u16 itemId);
|
||||
u8 ItemId_GetType(u16 itemId);
|
||||
ItemUseFunc ItemId_GetFieldFunc(u16 itemId);
|
||||
u8 ItemId_GetBattleUsage(u16 itemId);
|
||||
ItemUseFunc ItemId_GetBattleFunc(u16 itemId);
|
||||
u8 ItemId_GetSecondaryId(u16 itemId);
|
||||
u8 ItemId_GetFlingPower(u16 itemId);
|
||||
u32 GetItemStatus1Mask(u16 itemId);
|
||||
u32 GetItemStatus2Mask(u16 itemId);
|
||||
|
||||
#endif // GUARD_ITEM_H
|
||||
|
@ -30,12 +30,9 @@ void ItemUseOutOfBattle_FormChange(u8);
|
||||
void ItemUseOutOfBattle_FormChange_ConsumedOnUse(u8);
|
||||
void ItemUseOutOfBattle_Honey(u8);
|
||||
void ItemUseOutOfBattle_CannotUse(u8);
|
||||
void ItemUseInBattle_PokeBall(u8);
|
||||
void ItemUseInBattle_StatIncrease(u8);
|
||||
void ItemUseInBattle_Medicine(u8);
|
||||
void ItemUseInBattle_PPRecovery(u8);
|
||||
void ItemUseInBattle_Escape(u8);
|
||||
void ItemUseInBattle_EnigmaBerry(u8);
|
||||
void ItemUseInBattle_BagMenu(u8 taskId);
|
||||
void ItemUseInBattle_PartyMenu(u8 taskId);
|
||||
void ItemUseInBattle_PartyMenuChooseMove(u8 taskId);
|
||||
void Task_UseDigEscapeRopeOnField(u8 taskId);
|
||||
u8 CanUseDigOrEscapeRopeOnCurMap(void);
|
||||
u8 CheckIfItemIsTMHMOrEvolutionStone(u16 itemId);
|
||||
|
@ -48,6 +48,8 @@ void LoadHeldItemIcons(void);
|
||||
void DrawHeldItemIconsForTrade(u8 *partyCounts, u8 *partySpriteIds, u8 whichParty);
|
||||
void LoadPartyMenuAilmentGfx(void);
|
||||
void CB2_ShowPartyMenuForItemUse(void);
|
||||
void ItemUseCB_BattleScript(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_BattleChooseMove(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_Medicine(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_AbilityCapsule(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_AbilityPatch(u8 taskId, TaskFunc task);
|
||||
@ -64,6 +66,7 @@ void ItemUseCB_SacredAsh(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_EvolutionStone(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_FormChange(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_FormChange_ConsumedOnUse(u8 taskId, TaskFunc task);
|
||||
const u8* GetItemEffect(u16 item);
|
||||
u8 GetItemEffectType(u16 item);
|
||||
void CB2_PartyMenuFromStartMenu(void);
|
||||
void CB2_ChooseMonToGiveItem(void);
|
||||
|
@ -44,6 +44,7 @@ enum
|
||||
RECORDED_MOVE_TARGET,
|
||||
RECORDED_PARTY_INDEX,
|
||||
RECORDED_BATTLE_PALACE_ACTION,
|
||||
RECORDED_ITEM_ID,
|
||||
};
|
||||
|
||||
extern u32 gRecordedBattleRngSeed;
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "constants/hold_effects.h"
|
||||
#include "battle_setup.h"
|
||||
#include "data.h"
|
||||
#include "item.h"
|
||||
#include "party_menu.h"
|
||||
#include "pokemon.h"
|
||||
#include "random.h"
|
||||
#include "util.h"
|
||||
@ -995,22 +997,6 @@ u8 GetMostSuitableMonToSwitchInto(void)
|
||||
return PARTY_SIZE;
|
||||
}
|
||||
|
||||
static u8 GetAI_ItemType(u16 itemId, const u8 *itemEffect)
|
||||
{
|
||||
if (itemId == ITEM_FULL_RESTORE)
|
||||
return AI_ITEM_FULL_RESTORE;
|
||||
else if (itemEffect[4] & ITEM4_HEAL_HP)
|
||||
return AI_ITEM_HEAL_HP;
|
||||
else if (itemEffect[3] & ITEM3_STATUS_ALL)
|
||||
return AI_ITEM_CURE_CONDITION;
|
||||
else if ((itemEffect[0] & ITEM0_DIRE_HIT) || itemEffect[1])
|
||||
return AI_ITEM_X_STAT;
|
||||
else if (itemEffect[3] & ITEM3_GUARD_SPEC)
|
||||
return AI_ITEM_GUARD_SPEC;
|
||||
else
|
||||
return AI_ITEM_NOT_RECOGNIZABLE;
|
||||
}
|
||||
|
||||
static bool32 AiExpectsToFaintPlayer(void)
|
||||
{
|
||||
bool32 canFaintPlayer;
|
||||
@ -1070,96 +1056,70 @@ static bool8 ShouldUseItem(void)
|
||||
u8 paramOffset;
|
||||
u8 battlerSide;
|
||||
|
||||
if (i != 0 && validMons > (gBattleResources->battleHistory->itemsNo - i) + 1)
|
||||
continue;
|
||||
item = gBattleResources->battleHistory->trainerItems[i];
|
||||
if (item == ITEM_NONE)
|
||||
continue;
|
||||
if (gItemEffectTable[item] == NULL)
|
||||
itemEffects = GetItemEffect(item);
|
||||
if (itemEffects == NULL)
|
||||
continue;
|
||||
|
||||
if (item == ITEM_ENIGMA_BERRY_E_READER)
|
||||
itemEffects = gSaveBlock1Ptr->enigmaBerry.itemEffect;
|
||||
else
|
||||
itemEffects = gItemEffectTable[item];
|
||||
|
||||
*(gBattleStruct->AI_itemType + gActiveBattler / 2) = GetAI_ItemType(item, itemEffects);
|
||||
|
||||
switch (*(gBattleStruct->AI_itemType + gActiveBattler / 2))
|
||||
switch (ItemId_GetBattleUsage(item))
|
||||
{
|
||||
case AI_ITEM_FULL_RESTORE:
|
||||
case EFFECT_ITEM_HEAL_AND_CURE_STATUS:
|
||||
shouldUse = AI_ShouldHeal(0);
|
||||
break;
|
||||
case AI_ITEM_HEAL_HP:
|
||||
case EFFECT_ITEM_RESTORE_HP:
|
||||
shouldUse = AI_ShouldHeal(itemEffects[GetItemEffectParamOffset(item, 4, 4)]);
|
||||
break;
|
||||
case AI_ITEM_CURE_CONDITION:
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) = 0;
|
||||
case EFFECT_ITEM_CURE_STATUS:
|
||||
if (itemEffects[3] & ITEM3_SLEEP && gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_HEAL_SLEEP);
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
if (itemEffects[3] & ITEM3_POISON && (gBattleMons[gActiveBattler].status1 & STATUS1_POISON
|
||||
|| gBattleMons[gActiveBattler].status1 & STATUS1_TOXIC_POISON))
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_HEAL_POISON);
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
if (itemEffects[3] & ITEM3_BURN && gBattleMons[gActiveBattler].status1 & STATUS1_BURN)
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_HEAL_BURN);
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
if (itemEffects[3] & ITEM3_FREEZE && gBattleMons[gActiveBattler].status1 & STATUS1_FREEZE)
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_HEAL_FREEZE);
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
if (itemEffects[3] & ITEM3_PARALYSIS && gBattleMons[gActiveBattler].status1 & STATUS1_PARALYSIS)
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_HEAL_PARALYSIS);
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
if (itemEffects[3] & ITEM3_CONFUSION && gBattleMons[gActiveBattler].status2 & STATUS2_CONFUSION)
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_HEAL_CONFUSION);
|
||||
shouldUse = TRUE;
|
||||
}
|
||||
break;
|
||||
case AI_ITEM_X_STAT:
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) = 0;
|
||||
if (gDisableStructs[gActiveBattler].isFirstTurn == 0)
|
||||
case EFFECT_ITEM_INCREASE_STAT:
|
||||
case EFFECT_ITEM_INCREASE_ALL_STATS:
|
||||
if (!gDisableStructs[gActiveBattler].isFirstTurn
|
||||
|| AI_OpponentCanFaintAiWithMod(0))
|
||||
break;
|
||||
if (itemEffects[1] & ITEM1_X_ATTACK)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_X_ATTACK);
|
||||
if (itemEffects[1] & ITEM1_X_DEFENSE)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_X_DEFEND);
|
||||
if (itemEffects[1] & ITEM1_X_SPEED)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_X_SPEED);
|
||||
if (itemEffects[1] & ITEM1_X_SPATK)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_X_SPATK);
|
||||
if (itemEffects[1] & ITEM1_X_SPDEF)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_X_SPDEF);
|
||||
if (itemEffects[1] & ITEM1_X_ACCURACY)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_X_ACCURACY);
|
||||
if (itemEffects[0] & ITEM0_DIRE_HIT)
|
||||
*(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= (1 << AI_DIRE_HIT);
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
case AI_ITEM_GUARD_SPEC:
|
||||
case EFFECT_ITEM_SET_FOCUS_ENERGY:
|
||||
if (!gDisableStructs[gActiveBattler].isFirstTurn
|
||||
|| gBattleMons[gActiveBattler].status2 & STATUS2_FOCUS_ENERGY
|
||||
|| AI_OpponentCanFaintAiWithMod(0))
|
||||
break;
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
case EFFECT_ITEM_SET_MIST:
|
||||
battlerSide = GetBattlerSide(gActiveBattler);
|
||||
if (gDisableStructs[gActiveBattler].isFirstTurn != 0 && gSideTimers[battlerSide].mistTimer == 0)
|
||||
if (gDisableStructs[gActiveBattler].isFirstTurn && gSideTimers[battlerSide].mistTimer == 0)
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
case AI_ITEM_NOT_RECOGNIZABLE:
|
||||
case EFFECT_ITEM_REVIVE:
|
||||
gBattleStruct->itemPartyIndex[gActiveBattler] = GetFirstFaintedPartyIndex(gActiveBattler);
|
||||
if (gBattleStruct->itemPartyIndex[gActiveBattler] != PARTY_SIZE) // Revive if possible.
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (shouldUse)
|
||||
{
|
||||
// Set selected party ID to current battler if none chosen.
|
||||
if (gBattleStruct->itemPartyIndex[gActiveBattler] == PARTY_SIZE)
|
||||
gBattleStruct->itemPartyIndex[gActiveBattler] = gBattlerPartyIndexes[gActiveBattler];
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_USE_ITEM, 0);
|
||||
*(gBattleStruct->chosenItem + (gActiveBattler / 2) * 2) = item;
|
||||
gBattleStruct->chosenItem[gActiveBattler] = item;
|
||||
gBattleResources->battleHistory->trainerItems[i] = 0;
|
||||
return shouldUse;
|
||||
}
|
||||
|
@ -1667,7 +1667,7 @@ static void OpponentHandleChooseMove(void)
|
||||
|
||||
static void OpponentHandleChooseItem(void)
|
||||
{
|
||||
BtlController_EmitOneReturnValue(BUFFER_B, *(gBattleStruct->chosenItem + (gActiveBattler / 2) * 2));
|
||||
BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]);
|
||||
OpponentBufferExecCompleted();
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "battle_tv.h"
|
||||
#include "bg.h"
|
||||
#include "data.h"
|
||||
#include "item_menu.h"
|
||||
#include "item_use.h"
|
||||
#include "link.h"
|
||||
#include "main.h"
|
||||
@ -1437,6 +1438,10 @@ static void RecordedOpponentHandleChooseMove(void)
|
||||
|
||||
static void RecordedOpponentHandleChooseItem(void)
|
||||
{
|
||||
u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler);
|
||||
u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler);
|
||||
gBattleStruct->chosenItem[gActiveBattler] = (byte1 << 8) | byte2;
|
||||
BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]);
|
||||
RecordedOpponentBufferExecCompleted();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "battle_interface.h"
|
||||
#include "bg.h"
|
||||
#include "data.h"
|
||||
#include "item_menu.h"
|
||||
#include "item_use.h"
|
||||
#include "link.h"
|
||||
#include "main.h"
|
||||
@ -1461,6 +1462,10 @@ static void RecordedPlayerHandleChooseMove(void)
|
||||
|
||||
static void RecordedPlayerHandleChooseItem(void)
|
||||
{
|
||||
u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler);
|
||||
u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler);
|
||||
gBattleStruct->chosenItem[gActiveBattler] = (byte1 << 8) | byte2;
|
||||
BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]);
|
||||
RecordedPlayerBufferExecCompleted();
|
||||
}
|
||||
|
||||
|
@ -4162,6 +4162,7 @@ static void HandleTurnActionSelectionState(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleStruct->itemPartyIndex[gActiveBattler] = PARTY_SIZE;
|
||||
BtlController_EmitChooseAction(BUFFER_A, gChosenActionByBattler[0], gBattleResources->bufferB[0][1] | (gBattleResources->bufferB[0][2] << 8));
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
gBattleCommunication[gActiveBattler]++;
|
||||
@ -4229,10 +4230,11 @@ static void HandleTurnActionSelectionState(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((gBattleTypeFlags & (BATTLE_TYPE_LINK
|
||||
if (((gBattleTypeFlags & (BATTLE_TYPE_LINK
|
||||
| BATTLE_TYPE_FRONTIER_NO_PYRAMID
|
||||
| BATTLE_TYPE_EREADER_TRAINER
|
||||
| BATTLE_TYPE_RECORDED_LINK))
|
||||
&& !gTestRunnerEnabled)
|
||||
// Or if currently held by Sky Drop
|
||||
|| gStatuses3[gActiveBattler] & STATUS3_SKY_DROPPED)
|
||||
{
|
||||
|
@ -467,7 +467,7 @@ const u8 *const gPokeblockWasTooXStringTable[FLAVOR_COUNT] =
|
||||
|
||||
static const u8 sText_PlayerUsedItem[] = _("{B_PLAYER_NAME} used\n{B_LAST_ITEM}!");
|
||||
static const u8 sText_WallyUsedItem[] = _("WALLY used\n{B_LAST_ITEM}!");
|
||||
static const u8 sText_Trainer1UsedItem[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME}\nused {B_LAST_ITEM}!");
|
||||
static const u8 sText_Trainer1UsedItem[] = _("{B_ATK_TRAINER_CLASS} {B_ATK_TRAINER_NAME}\nused {B_LAST_ITEM}!");
|
||||
static const u8 sText_TrainerBlockedBall[] = _("The TRAINER blocked the BALL!");
|
||||
static const u8 sText_DontBeAThief[] = _("Don't be a thief!");
|
||||
static const u8 sText_ItDodgedBall[] = _("It dodged the thrown BALL!\nThis POKéMON can't be caught!");
|
||||
@ -783,9 +783,15 @@ static const u8 sText_ShellTrapDidntWork[] = _("{B_ATK_NAME_WITH_PREFIX}'s shell
|
||||
static const u8 sText_CouldntFullyProtect[] = _("{B_DEF_NAME_WITH_PREFIX} couldn't fully protect\nitself and got hurt!");
|
||||
static const u8 sText_StockpiledEffectWoreOff[] = _("{B_ATK_NAME_WITH_PREFIX}'s stockpiled\neffect wore off!");
|
||||
static const u8 sText_PkmnRevivedReadyToFight[] = _("{B_BUFF1} was revived and\nis ready to fight again!");
|
||||
static const u8 sText_ItemRestoredSpeciesHealth[] = _("{B_LAST_ITEM} restored\n{B_BUFF1}'s health!");
|
||||
static const u8 sText_ItemCuredSpeciesStatus[] = _("{B_LAST_ITEM} cured\n{B_BUFF1}'s status!");
|
||||
static const u8 sText_ItemRestoredSpeciesPP[] = _("{B_LAST_ITEM} restored\n{B_BUFF1}'s PP!");
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_ITEMRESTOREDSPECIESHEALTH - BATTLESTRINGS_TABLE_START] = sText_ItemRestoredSpeciesHealth,
|
||||
[STRINGID_ITEMCUREDSPECIESSTATUS - BATTLESTRINGS_TABLE_START] = sText_ItemCuredSpeciesStatus,
|
||||
[STRINGID_ITEMRESTOREDSPECIESPP - BATTLESTRINGS_TABLE_START] = sText_ItemRestoredSpeciesPP,
|
||||
[STRINGID_PKMNREVIVEDREADYTOFIGHT - BATTLESTRINGS_TABLE_START] = sText_PkmnRevivedReadyToFight,
|
||||
[STRINGID_STOCKPILEDEFFECTWOREOFF - BATTLESTRINGS_TABLE_START] = sText_StockpiledEffectWoreOff,
|
||||
[STRINGID_COULDNTFULLYPROTECT - BATTLESTRINGS_TABLE_START] = sText_CouldntFullyProtect,
|
||||
@ -1424,6 +1430,11 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
[STRINGID_PKMNSABILITYPREVENTSABILITY - BATTLESTRINGS_TABLE_START] = sText_PkmnsAbilityPreventsAbility,
|
||||
};
|
||||
|
||||
const u16 gTrainerUsedItemStringIds[] =
|
||||
{
|
||||
STRINGID_PLAYERUSEDITEM, STRINGID_TRAINER1USEDITEM
|
||||
};
|
||||
|
||||
const u16 gZEffectStringIds[] =
|
||||
{
|
||||
[B_MSG_Z_RESET_STATS] = STRINGID_ZMOVERESETSSTATS,
|
||||
@ -1820,16 +1831,6 @@ const u16 gSafariPokeblockResultStringIds[] =
|
||||
[B_MSG_MON_IGNORED] = STRINGID_PKMNIGNOREDX
|
||||
};
|
||||
|
||||
const u16 gTrainerItemCuredStatusStringIds[] =
|
||||
{
|
||||
[AI_HEAL_CONFUSION] = STRINGID_PKMNSITEMSNAPPEDOUT,
|
||||
[AI_HEAL_PARALYSIS] = STRINGID_PKMNSITEMCUREDPARALYSIS,
|
||||
[AI_HEAL_FREEZE] = STRINGID_PKMNSITEMDEFROSTEDIT,
|
||||
[AI_HEAL_BURN] = STRINGID_PKMNSITEMHEALEDBURN,
|
||||
[AI_HEAL_POISON] = STRINGID_PKMNSITEMCUREDPOISON,
|
||||
[AI_HEAL_SLEEP] = STRINGID_PKMNSITEMWOKEIT
|
||||
};
|
||||
|
||||
const u16 gBerryEffectStringIds[] =
|
||||
{
|
||||
[B_MSG_CURED_PROBLEM] = STRINGID_PKMNSITEMCUREDPROBLEM,
|
||||
|
@ -1299,11 +1299,18 @@ static void TryCloseBagToGiveItem(u8 taskId)
|
||||
|
||||
static void BagAction_UseInBattle(u8 taskId)
|
||||
{
|
||||
if (ItemId_GetBattleFunc(gSpecialVar_ItemId) != NULL)
|
||||
{
|
||||
CloseMenuActionWindow();
|
||||
ItemId_GetBattleFunc(gSpecialVar_ItemId)(taskId);
|
||||
}
|
||||
// Safety check
|
||||
u16 type = ItemId_GetType(gSpecialVar_ItemId);
|
||||
if (!ItemId_GetBattleUsage(gSpecialVar_ItemId))
|
||||
return;
|
||||
|
||||
CloseMenuActionWindow();
|
||||
if (type == ITEM_USE_BAG_MENU)
|
||||
ItemUseInBattle_BagMenu(taskId);
|
||||
else if (type == ITEM_USE_PARTY_MENU)
|
||||
ItemUseInBattle_PartyMenu(taskId);
|
||||
else if (type == ITEM_USE_PARTY_MENU_MOVES)
|
||||
ItemUseInBattle_PartyMenuChooseMove(taskId);
|
||||
}
|
||||
|
||||
static void Task_BeginItemSwap(u8 taskId)
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "constants/battle_string_ids.h"
|
||||
#include "constants/hold_effects.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/item_effects.h"
|
||||
#include "constants/map_types.h"
|
||||
#include "constants/moves.h"
|
||||
#include "constants/party_menu.h"
|
||||
@ -11264,7 +11265,7 @@ static void Cmd_various(void)
|
||||
// Open party menu, wait to go to next instruction.
|
||||
else
|
||||
{
|
||||
BtlController_EmitChoosePokemon(BUFFER_A, PARTY_ACTION_CHOOSE_FAINTED_MON, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[gActiveBattler]);
|
||||
BtlController_EmitChoosePokemon(BUFFER_A, PARTY_ACTION_CHOOSE_FAINTED_MON, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[gBattlerAttacker]);
|
||||
MarkBattlerForControllerExec(gBattlerAttacker);
|
||||
}
|
||||
return;
|
||||
@ -16427,3 +16428,144 @@ u8 GetFirstFaintedPartyIndex(u8 battlerId)
|
||||
// Returns PARTY_SIZE if none found.
|
||||
return PARTY_SIZE;
|
||||
}
|
||||
|
||||
void BS_ItemRestoreHP(void) {
|
||||
NATIVE_ARGS();
|
||||
u16 healAmount;
|
||||
u32 battlerId = MAX_BATTLERS_COUNT;
|
||||
u32 healParam = GetItemEffect(gLastUsedItem)[6];
|
||||
u32 side = GetBattlerSide(gBattlerAttacker);
|
||||
struct Pokemon *party = (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
|
||||
u16 hp = GetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_HP);
|
||||
u16 maxHP = GetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_MAX_HP);
|
||||
gBattleCommunication[MULTIUSE_STATE] = 0;
|
||||
|
||||
// Track the number of Revives used in a battle.
|
||||
if (hp == 0 && side == B_SIDE_PLAYER && gBattleResults.numRevivesUsed < 255)
|
||||
gBattleResults.numRevivesUsed++;
|
||||
|
||||
// Check if the recipient is an active battler.
|
||||
if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker])
|
||||
battlerId = gBattlerAttacker;
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
|
||||
battlerId = BATTLE_PARTNER(gBattlerAttacker);
|
||||
|
||||
// Get amount to heal.
|
||||
switch (healParam)
|
||||
{
|
||||
case ITEM6_HEAL_HP_FULL:
|
||||
healAmount = maxHP;
|
||||
break;
|
||||
case ITEM6_HEAL_HP_HALF:
|
||||
healAmount = maxHP / 2;
|
||||
break;
|
||||
case ITEM6_HEAL_HP_QUARTER:
|
||||
healAmount = maxHP / 4;
|
||||
break;
|
||||
default:
|
||||
healAmount = healParam;
|
||||
break;
|
||||
}
|
||||
if (hp + healAmount > maxHP)
|
||||
healAmount = maxHP - hp;
|
||||
|
||||
// Heal is applied as move damage if battler is active.
|
||||
if (battlerId != MAX_BATTLERS_COUNT && hp != 0)
|
||||
{
|
||||
gBattleMoveDamage = -healAmount;
|
||||
}
|
||||
else
|
||||
{
|
||||
hp += healAmount;
|
||||
SetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_HP, &hp);
|
||||
|
||||
// Revived battlers on the field need to be brought back.
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && battlerId != MAX_BATTLERS_COUNT)
|
||||
{
|
||||
gAbsentBattlerFlags &= ~gBitTable[battlerId];
|
||||
gBattleCommunication[MULTIUSE_STATE] = TRUE;
|
||||
}
|
||||
}
|
||||
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_SPECIES));
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_ItemCureStatus(void) {
|
||||
NATIVE_ARGS();
|
||||
struct Pokemon *party = (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
|
||||
|
||||
// Heal Status1 conditions.
|
||||
HealStatusConditions(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], gBattleStruct->itemPartyIndex[gBattlerAttacker], GetItemStatus1Mask(gLastUsedItem), gBattlerAttacker);
|
||||
|
||||
// Heal Status2 conditions if battler is active.
|
||||
if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker])
|
||||
gBattleMons[gBattleStruct->itemPartyIndex[gBattlerAttacker]].status2 &= ~GetItemStatus2Mask(gLastUsedItem);
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~GetItemStatus2Mask(gLastUsedItem);
|
||||
gBattlerTarget = BATTLE_PARTNER(gBattlerAttacker);
|
||||
if (GetItemStatus1Mask(gLastUsedItem) & STATUS1_SLEEP)
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
|
||||
}
|
||||
|
||||
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_SPECIES));
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_ItemIncreaseStat(void) {
|
||||
NATIVE_ARGS();
|
||||
u16 statId = GetItemEffect(gLastUsedItem)[1];
|
||||
u16 stages = ItemId_GetHoldEffectParam(gLastUsedItem);
|
||||
SET_STATCHANGER(statId, stages, FALSE);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_ItemRestorePP(void) {
|
||||
NATIVE_ARGS();
|
||||
const u8 *effect = GetItemEffect(gLastUsedItem);
|
||||
u32 i, pp, maxPP, moveId;
|
||||
u32 loopEnd = MAX_MON_MOVES;
|
||||
u32 battlerId = MAX_BATTLERS_COUNT;
|
||||
struct Pokemon *mon = (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) ? &gPlayerParty[gBattleStruct->itemPartyIndex[gBattlerAttacker]] : &gEnemyParty[gBattleStruct->itemPartyIndex[gBattlerAttacker]];
|
||||
|
||||
// Check whether to apply to all moves.
|
||||
if (effect[4] & ITEM4_HEAL_PP_ONE)
|
||||
{
|
||||
i = gChosenMovePos;
|
||||
loopEnd = gChosenMovePos + 1;
|
||||
}
|
||||
|
||||
// Check if the recipient is an active battler.
|
||||
if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker])
|
||||
battlerId = gBattlerAttacker;
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
|
||||
battlerId = BATTLE_PARTNER(gBattlerAttacker);
|
||||
|
||||
// Heal PP!
|
||||
for (i = 0; i < loopEnd; i++)
|
||||
{
|
||||
pp = GetMonData(mon, MON_DATA_PP1 + i, NULL);
|
||||
moveId = GetMonData(mon, MON_DATA_MOVE1 + i, NULL);
|
||||
maxPP = CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), i);
|
||||
if (pp != maxPP)
|
||||
{
|
||||
pp += effect[6];
|
||||
if (pp > maxPP)
|
||||
pp = maxPP;
|
||||
SetMonData(mon, MON_DATA_PP1 + i, &pp);
|
||||
|
||||
// Update battler PP if needed.
|
||||
if (battlerId != MAX_BATTLERS_COUNT
|
||||
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[battlerId]
|
||||
&& MOVE_IS_PERMANENT(battlerId, i))
|
||||
{
|
||||
gBattleMons[battlerId].pp[i] = pp;
|
||||
}
|
||||
}
|
||||
}
|
||||
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(mon, MON_DATA_SPECIES));
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "sprite.h"
|
||||
#include "string_util.h"
|
||||
#include "task.h"
|
||||
#include "test_runner.h"
|
||||
#include "trig.h"
|
||||
#include "window.h"
|
||||
#include "battle_message.h"
|
||||
@ -550,93 +551,13 @@ void HandleAction_Switch(void)
|
||||
|
||||
void HandleAction_UseItem(void)
|
||||
{
|
||||
gBattlerAttacker = gBattlerTarget = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
||||
gActiveBattler = gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
||||
gBattle_BG0_X = 0;
|
||||
gBattle_BG0_Y = 0;
|
||||
ClearFuryCutterDestinyBondGrudge(gBattlerAttacker);
|
||||
|
||||
gLastUsedItem = gBattleResources->bufferB[gBattlerAttacker][1] | (gBattleResources->bufferB[gBattlerAttacker][2] << 8);
|
||||
|
||||
if (gLastUsedItem <= LAST_BALL) // is ball
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_BallThrow;
|
||||
}
|
||||
else if (gLastUsedItem == ITEM_POKE_DOLL || gLastUsedItem == ITEM_FLUFFY_TAIL)
|
||||
{
|
||||
gBattlescriptCurrInstr = gBattlescriptsForRunningByItem[0]; // BattleScript_RunByUsingItem
|
||||
}
|
||||
else if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
|
||||
{
|
||||
gBattlescriptCurrInstr = gBattlescriptsForUsingItem[0]; // BattleScript_PlayerUsesItem
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleScripting.battler = gBattlerAttacker;
|
||||
|
||||
switch (*(gBattleStruct->AI_itemType + (gBattlerAttacker >> 1)))
|
||||
{
|
||||
case AI_ITEM_FULL_RESTORE:
|
||||
case AI_ITEM_HEAL_HP:
|
||||
break;
|
||||
case AI_ITEM_CURE_CONDITION:
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = AI_HEAL_CONFUSION;
|
||||
if (*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & (1 << AI_HEAL_CONFUSION))
|
||||
{
|
||||
if (*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & 0x3E)
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = AI_HEAL_SLEEP;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for other statuses, stopping at first (shouldn't be more than one)
|
||||
while (!(*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & 1))
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) >>= 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER]++;
|
||||
// MULTISTRING_CHOOSER will be either AI_HEAL_PARALYSIS, AI_HEAL_FREEZE,
|
||||
// AI_HEAL_BURN, AI_HEAL_POISON, or AI_HEAL_SLEEP
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AI_ITEM_X_STAT:
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STAT_ROSE_ITEM;
|
||||
if (*(gBattleStruct->AI_itemFlags + (gBattlerAttacker >> 1)) & (1 << AI_DIRE_HIT))
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_USED_DIRE_HIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK)
|
||||
PREPARE_STRING_BUFFER(gBattleTextBuff2, CHAR_X)
|
||||
|
||||
while (!((*(gBattleStruct->AI_itemFlags + (gBattlerAttacker >> 1))) & 1))
|
||||
{
|
||||
*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) >>= 1;
|
||||
gBattleTextBuff1[2]++;
|
||||
}
|
||||
|
||||
gBattleScripting.animArg1 = gBattleTextBuff1[2] + 14;
|
||||
gBattleScripting.animArg2 = 0;
|
||||
}
|
||||
break;
|
||||
case AI_ITEM_GUARD_SPEC:
|
||||
// It seems probable that at some point there was a special message for
|
||||
// an AI trainer using Guard Spec in a double battle.
|
||||
// There isn't now however, and the assignment to 2 below goes out of
|
||||
// bounds for gMistUsedStringIds and instead prints "{mon} is getting pumped"
|
||||
// from the next table, gFocusEnergyUsedStringIds.
|
||||
// In any case this isn't an issue in the retail version, as no trainers
|
||||
// are ever given any Guard Spec to use.
|
||||
#ifndef UBFIX
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
||||
else
|
||||
#endif
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_MIST;
|
||||
break;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = gBattlescriptsForUsingItem[*(gBattleStruct->AI_itemType + gBattlerAttacker / 2)];
|
||||
}
|
||||
gBattlescriptCurrInstr = gBattlescriptsForUsingItem[ItemId_GetBattleUsage(gLastUsedItem) - 1];
|
||||
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
|
||||
}
|
||||
|
||||
@ -914,7 +835,7 @@ void HandleAction_ActionFinished(void)
|
||||
u32 i, j;
|
||||
bool32 afterYouActive = gSpecialStatuses[gBattlerByTurnOrder[gCurrentTurnActionNumber + 1]].afterYou;
|
||||
#endif
|
||||
*(gBattleStruct->monToSwitchIntoId + gBattlerByTurnOrder[gCurrentTurnActionNumber]) = PARTY_SIZE;
|
||||
*(gBattleStruct->monToSwitchIntoId + gBattlerByTurnOrder[gCurrentTurnActionNumber]) = gSelectedMonPartyId = PARTY_SIZE;
|
||||
gCurrentTurnActionNumber++;
|
||||
gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
|
||||
SpecialStatusesClear();
|
||||
@ -8207,7 +8128,6 @@ u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating)
|
||||
return ItemId_GetHoldEffect(gBattleMons[battlerId].item);
|
||||
}
|
||||
|
||||
//
|
||||
static u32 GetBattlerItemHoldEffectParam(u8 battlerId, u16 item)
|
||||
{
|
||||
if (item == ITEM_ENIGMA_BERRY_E_READER)
|
||||
|
337
src/data/items.h
337
src/data/items.h
@ -20,9 +20,8 @@ const struct Item gItems[] =
|
||||
.price = 200,
|
||||
.description = sPokeBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_POKE_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_POKE_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -33,9 +32,8 @@ const struct Item gItems[] =
|
||||
.price = 600,
|
||||
.description = sGreatBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_GREAT_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_GREAT_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -46,9 +44,8 @@ const struct Item gItems[] =
|
||||
.price = 800,
|
||||
.description = sUltraBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_ULTRA_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_ULTRA_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -59,9 +56,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sMasterBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_MASTER_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_MASTER_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -72,9 +68,8 @@ const struct Item gItems[] =
|
||||
.price = 20,
|
||||
.description = sPremierBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_PREMIER_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_PREMIER_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -85,9 +80,8 @@ const struct Item gItems[] =
|
||||
.price = 300,
|
||||
.description = sHealBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_HEAL_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_HEAL_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -98,9 +92,8 @@ const struct Item gItems[] =
|
||||
.price = 1000,
|
||||
.description = sNetBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_NET_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_NET_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -111,9 +104,8 @@ const struct Item gItems[] =
|
||||
.price = 1000,
|
||||
.description = sNestBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_NEST_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_NEST_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -124,9 +116,8 @@ const struct Item gItems[] =
|
||||
.price = 1000,
|
||||
.description = sDiveBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_DIVE_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_DIVE_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -137,9 +128,8 @@ const struct Item gItems[] =
|
||||
.price = 1000,
|
||||
.description = sDuskBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_DUSK_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_DUSK_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -150,9 +140,8 @@ const struct Item gItems[] =
|
||||
.price = 1000,
|
||||
.description = sTimerBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_TIMER_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_TIMER_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -163,9 +152,8 @@ const struct Item gItems[] =
|
||||
.price = 1000,
|
||||
.description = sQuickBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_QUICK_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_QUICK_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -176,9 +164,8 @@ const struct Item gItems[] =
|
||||
.price = 1000,
|
||||
.description = sRepeatBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_REPEAT_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_REPEAT_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -189,9 +176,8 @@ const struct Item gItems[] =
|
||||
.price = 1000,
|
||||
.description = sLuxuryBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_LUXURY_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_LUXURY_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -202,9 +188,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sLevelBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_LEVEL_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_LEVEL_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -215,9 +200,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sLureBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_LURE_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_LURE_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -228,9 +212,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sMoonBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_MOON_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_MOON_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -241,9 +224,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sFriendBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_FRIEND_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_FRIEND_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -254,9 +236,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sLoveBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_LOVE_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_LOVE_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -267,9 +248,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sFastBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_FAST_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_FAST_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -280,9 +260,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sHeavyBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_HEAVY_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_HEAVY_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -293,9 +272,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sDreamBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_DREAM_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_DREAM_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -306,9 +284,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sSafariBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_SAFARI_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_SAFARI_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -319,9 +296,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sSportBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_SPORT_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_SPORT_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -332,9 +308,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sParkBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_PARK_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_PARK_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -345,9 +320,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sBeastBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_BEAST_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_BEAST_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -358,9 +332,8 @@ const struct Item gItems[] =
|
||||
.price = 0,
|
||||
.description = sCherishBallDesc,
|
||||
.pocket = POCKET_POKE_BALLS,
|
||||
.type = ITEM_CHERISH_BALL - FIRST_BALL,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_PokeBall,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.battleUsage = EFFECT_ITEM_THROW_BALL,
|
||||
.secondaryId = ITEM_CHERISH_BALL - FIRST_BALL,
|
||||
},
|
||||
|
||||
@ -376,8 +349,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -391,8 +363,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -406,8 +377,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -421,8 +391,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -436,8 +405,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_HEAL_AND_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -450,8 +418,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_REVIVE,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -464,8 +431,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_REVIVE,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -479,8 +445,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -494,8 +459,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -509,8 +473,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -524,8 +487,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -538,8 +500,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -552,8 +513,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -566,8 +526,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -580,8 +539,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_REVIVE,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -594,8 +552,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -608,8 +565,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -622,8 +578,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -636,8 +591,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -650,8 +604,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -664,8 +617,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -677,10 +629,9 @@ const struct Item gItems[] =
|
||||
.holdEffectParam = 10,
|
||||
.description = sEtherDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.type = ITEM_USE_PARTY_MENU_MOVES,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_PPRecovery,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_PPRecovery,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_PP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -692,10 +643,9 @@ const struct Item gItems[] =
|
||||
.holdEffectParam = 255,
|
||||
.description = sMaxEtherDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.type = ITEM_USE_PARTY_MENU_MOVES,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_PPRecovery,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_PPRecovery,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_PP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -709,8 +659,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_PPRecovery,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_PPRecovery,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_PP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -724,8 +673,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_PPRecovery,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_PPRecovery,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_PP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -740,8 +688,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -767,8 +714,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -781,8 +727,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_REVIVE,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -797,8 +742,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -811,8 +755,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -825,8 +768,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -839,8 +781,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -853,8 +794,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -867,8 +807,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -881,8 +820,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -895,8 +833,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1454,8 +1391,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1468,8 +1404,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1482,8 +1417,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1618,17 +1552,19 @@ const struct Item gItems[] =
|
||||
|
||||
// X Items
|
||||
|
||||
#define X_ITEM_STAGES (B_X_ITEMS_BUFF >= GEN_7) ? 2 : 1
|
||||
|
||||
[ITEM_X_ATTACK] =
|
||||
{
|
||||
.name = _("X Attack"),
|
||||
.itemId = ITEM_X_ATTACK,
|
||||
.price = 1000,
|
||||
.holdEffectParam = X_ITEM_STAGES,
|
||||
.description = sXAttackDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_StatIncrease,
|
||||
.battleUsage = EFFECT_ITEM_INCREASE_STAT,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1637,12 +1573,12 @@ const struct Item gItems[] =
|
||||
.name = _("X Defense"),
|
||||
.itemId = ITEM_X_DEFENSE,
|
||||
.price = 2000,
|
||||
.holdEffectParam = X_ITEM_STAGES,
|
||||
.description = sXDefenseDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_StatIncrease,
|
||||
.battleUsage = EFFECT_ITEM_INCREASE_STAT,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1651,12 +1587,12 @@ const struct Item gItems[] =
|
||||
.name = _("X Sp. Atk"),
|
||||
.itemId = ITEM_X_SP_ATK,
|
||||
.price = 1000,
|
||||
.holdEffectParam = X_ITEM_STAGES,
|
||||
.description = sXSpAtkDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_StatIncrease,
|
||||
.battleUsage = EFFECT_ITEM_INCREASE_STAT,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1665,12 +1601,12 @@ const struct Item gItems[] =
|
||||
.name = _("X Sp. Def"),
|
||||
.itemId = ITEM_X_SP_DEF,
|
||||
.price = 2000,
|
||||
.holdEffectParam = X_ITEM_STAGES,
|
||||
.description = sXSpDefDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_StatIncrease,
|
||||
.battleUsage = EFFECT_ITEM_INCREASE_STAT,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1679,12 +1615,12 @@ const struct Item gItems[] =
|
||||
.name = _("X Speed"),
|
||||
.itemId = ITEM_X_SPEED,
|
||||
.price = 1000,
|
||||
.holdEffectParam = X_ITEM_STAGES,
|
||||
.description = sXSpeedDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_StatIncrease,
|
||||
.battleUsage = EFFECT_ITEM_INCREASE_STAT,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1693,12 +1629,12 @@ const struct Item gItems[] =
|
||||
.name = _("X Accuracy"),
|
||||
.itemId = ITEM_X_ACCURACY,
|
||||
.price = 1000,
|
||||
.holdEffectParam = X_ITEM_STAGES,
|
||||
.description = sXAccuracyDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_StatIncrease,
|
||||
.battleUsage = EFFECT_ITEM_INCREASE_STAT,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1711,8 +1647,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_StatIncrease,
|
||||
.battleUsage = EFFECT_ITEM_SET_FOCUS_ENERGY,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1725,8 +1660,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_StatIncrease,
|
||||
.battleUsage = EFFECT_ITEM_SET_MIST,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1739,8 +1673,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_Escape,
|
||||
.battleUsage = EFFECT_ITEM_ESCAPE,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1753,8 +1686,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_Escape,
|
||||
.battleUsage = EFFECT_ITEM_ESCAPE,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1767,8 +1699,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_Escape,
|
||||
.battleUsage = EFFECT_ITEM_ESCAPE,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
@ -1781,11 +1712,12 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_OTHER,
|
||||
.battleUseFunc = ItemUseInBattle_StatIncrease, // Todo
|
||||
.battleUsage = EFFECT_ITEM_INCREASE_ALL_STATS,
|
||||
.flingPower = 30,
|
||||
},
|
||||
|
||||
#undef X_ITEM_STAGES
|
||||
|
||||
// Treasures
|
||||
|
||||
[ITEM_BOTTLE_CAP] =
|
||||
@ -6874,8 +6806,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_BERRIES,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 10,
|
||||
},
|
||||
|
||||
@ -6889,8 +6820,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_BERRIES,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 10,
|
||||
},
|
||||
|
||||
@ -6904,8 +6834,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_BERRIES,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 10,
|
||||
},
|
||||
|
||||
@ -6919,8 +6848,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_BERRIES,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 10,
|
||||
},
|
||||
|
||||
@ -6934,8 +6862,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_BERRIES,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 10,
|
||||
},
|
||||
|
||||
@ -6948,10 +6875,9 @@ const struct Item gItems[] =
|
||||
.holdEffectParam = 10,
|
||||
.description = sLeppaBerryDesc,
|
||||
.pocket = POCKET_BERRIES,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.type = ITEM_USE_PARTY_MENU_MOVES,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_PPRecovery,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_PPRecovery,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_PP,
|
||||
.flingPower = 10,
|
||||
},
|
||||
|
||||
@ -6966,8 +6892,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_BERRIES,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 10,
|
||||
},
|
||||
|
||||
@ -6981,8 +6906,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_BERRIES,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 10,
|
||||
},
|
||||
|
||||
@ -6996,8 +6920,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_BERRIES,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_CURE_STATUS,
|
||||
.flingPower = 10,
|
||||
},
|
||||
|
||||
@ -7017,8 +6940,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_BERRIES,
|
||||
.type = ITEM_USE_PARTY_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_Medicine,
|
||||
.battleUsage = EFFECT_ITEM_RESTORE_HP,
|
||||
.flingPower = 10,
|
||||
},
|
||||
|
||||
@ -7794,8 +7716,7 @@ const struct Item gItems[] =
|
||||
.pocket = POCKET_BERRIES,
|
||||
.type = ITEM_USE_BAG_MENU, // Type handled by ItemUseOutOfBattle_EnigmaBerry
|
||||
.fieldUseFunc = ItemUseOutOfBattle_EnigmaBerry,
|
||||
.battleUsage = ITEM_B_USE_MEDICINE,
|
||||
.battleUseFunc = ItemUseInBattle_EnigmaBerry,
|
||||
.battleUsage = EFFECT_ITEM_ENIGMA_BERRY_EREADER,
|
||||
.flingPower = 10,
|
||||
},
|
||||
|
||||
|
@ -533,8 +533,6 @@ const u8 *const gItemEffectTable[ITEMS_COUNT] =
|
||||
[ITEM_DIRE_HIT] = gItemEffect_DireHit,
|
||||
[ITEM_GUARD_SPEC] = gItemEffect_GuardSpec,
|
||||
|
||||
//[ITEM_MAX_MUSHROOMS] = gItemEffect_MaxMushrooms, // Todo
|
||||
|
||||
// Evolution Items
|
||||
[ITEM_FIRE_STONE] = gItemEffect_EvoItem,
|
||||
[ITEM_WATER_STONE] = gItemEffect_EvoItem,
|
||||
|
70
src/item.c
70
src/item.c
@ -7,12 +7,15 @@
|
||||
#include "malloc.h"
|
||||
#include "secret_base.h"
|
||||
#include "item_menu.h"
|
||||
#include "party_menu.h"
|
||||
#include "strings.h"
|
||||
#include "load_save.h"
|
||||
#include "item_use.h"
|
||||
#include "battle_pyramid.h"
|
||||
#include "battle_pyramid_bag.h"
|
||||
#include "constants/battle.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/item_effects.h"
|
||||
#include "constants/hold_effects.h"
|
||||
|
||||
static bool8 CheckPyramidBagHasItem(u16 itemId, u16 count);
|
||||
@ -922,14 +925,36 @@ ItemUseFunc ItemId_GetFieldFunc(u16 itemId)
|
||||
return gItems[SanitizeItemId(itemId)].fieldUseFunc;
|
||||
}
|
||||
|
||||
// Returns an item's battle effect script ID.
|
||||
u8 ItemId_GetBattleUsage(u16 itemId)
|
||||
{
|
||||
return gItems[SanitizeItemId(itemId)].battleUsage;
|
||||
}
|
||||
|
||||
ItemUseFunc ItemId_GetBattleFunc(u16 itemId)
|
||||
{
|
||||
return gItems[SanitizeItemId(itemId)].battleUseFunc;
|
||||
u16 item = SanitizeItemId(itemId);
|
||||
// Handle E-Reader berries.
|
||||
if (item == ITEM_ENIGMA_BERRY_E_READER)
|
||||
{
|
||||
switch (GetItemEffectType(gSpecialVar_ItemId))
|
||||
{
|
||||
case ITEM_EFFECT_X_ITEM:
|
||||
return EFFECT_ITEM_INCREASE_STAT;
|
||||
case ITEM_EFFECT_HEAL_HP:
|
||||
return EFFECT_ITEM_RESTORE_HP;
|
||||
case ITEM_EFFECT_CURE_POISON:
|
||||
case ITEM_EFFECT_CURE_SLEEP:
|
||||
case ITEM_EFFECT_CURE_BURN:
|
||||
case ITEM_EFFECT_CURE_FREEZE:
|
||||
case ITEM_EFFECT_CURE_PARALYSIS:
|
||||
case ITEM_EFFECT_CURE_ALL_STATUS:
|
||||
case ITEM_EFFECT_CURE_CONFUSION:
|
||||
case ITEM_EFFECT_CURE_INFATUATION:
|
||||
return EFFECT_ITEM_CURE_STATUS;
|
||||
case ITEM_EFFECT_HEAL_PP:
|
||||
return EFFECT_ITEM_RESTORE_PP;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
return gItems[item].battleUsage;
|
||||
}
|
||||
|
||||
u8 ItemId_GetSecondaryId(u16 itemId)
|
||||
@ -941,3 +966,36 @@ u8 ItemId_GetFlingPower(u16 itemId)
|
||||
{
|
||||
return gItems[SanitizeItemId(itemId)].flingPower;
|
||||
}
|
||||
|
||||
|
||||
u32 GetItemStatus1Mask(u16 itemId)
|
||||
{
|
||||
const u8 *effect = GetItemEffect(itemId);
|
||||
switch (effect[3])
|
||||
{
|
||||
case ITEM3_FREEZE:
|
||||
return STATUS1_FREEZE;
|
||||
case ITEM3_BURN:
|
||||
return STATUS1_BURN;
|
||||
case ITEM3_POISON:
|
||||
return STATUS1_POISON | STATUS1_TOXIC_POISON;
|
||||
case ITEM3_SLEEP:
|
||||
return STATUS1_SLEEP;
|
||||
case ITEM3_STATUS_ALL:
|
||||
return STATUS1_ANY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 GetItemStatus2Mask(u16 itemId)
|
||||
{
|
||||
const u8 *effect = GetItemEffect(itemId);
|
||||
if (effect[3] & ITEM3_STATUS_ALL)
|
||||
return STATUS2_INFATUATION | STATUS2_CONFUSION;
|
||||
else if (effect[0] & ITEM0_INFATUATION)
|
||||
return STATUS2_INFATUATION;
|
||||
else if (effect[3] & ITEM3_CONFUSION)
|
||||
return STATUS2_CONFUSION;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -1985,11 +1985,18 @@ static void ItemMenu_Cancel(u8 taskId)
|
||||
|
||||
static void ItemMenu_UseInBattle(u8 taskId)
|
||||
{
|
||||
if (ItemId_GetBattleFunc(gSpecialVar_ItemId))
|
||||
{
|
||||
RemoveContextWindow();
|
||||
ItemId_GetBattleFunc(gSpecialVar_ItemId)(taskId);
|
||||
}
|
||||
// Safety check
|
||||
u16 type = ItemId_GetType(gSpecialVar_ItemId);
|
||||
if (!ItemId_GetBattleUsage(gSpecialVar_ItemId))
|
||||
return;
|
||||
|
||||
RemoveContextWindow();
|
||||
if (type == ITEM_USE_BAG_MENU)
|
||||
ItemUseInBattle_BagMenu(taskId);
|
||||
else if (type == ITEM_USE_PARTY_MENU)
|
||||
ItemUseInBattle_PartyMenu(taskId);
|
||||
else if (type == ITEM_USE_PARTY_MENU_MOVES)
|
||||
ItemUseInBattle_PartyMenuChooseMove(taskId);
|
||||
}
|
||||
|
||||
void CB2_ReturnToBagMenuPocket(void)
|
||||
|
168
src/item_use.c
168
src/item_use.c
@ -75,6 +75,7 @@ static void Task_CloseCantUseKeyItemMessage(u8);
|
||||
static void SetDistanceOfClosestHiddenItem(u8, s16, s16);
|
||||
static void CB2_OpenPokeblockFromBag(void);
|
||||
static void ItemUseOnFieldCB_Honey(u8 taskId);
|
||||
static bool32 CannotUseBagBattleItem(u16 itemId);
|
||||
|
||||
// EWRAM variables
|
||||
EWRAM_DATA static void(*sItemUseOnFieldCB)(u8 taskId) = NULL;
|
||||
@ -86,9 +87,10 @@ EWRAM_DATA static void(*sItemUseOnFieldCB)(u8 taskId) = NULL;
|
||||
// Never occurs in vanilla, but can occur with improperly created items
|
||||
static const MainCallback sItemUseCallbacks[] =
|
||||
{
|
||||
[ITEM_USE_PARTY_MENU - 1] = CB2_ShowPartyMenuForItemUse,
|
||||
[ITEM_USE_FIELD - 1] = CB2_ReturnToField,
|
||||
[ITEM_USE_PBLOCK_CASE - 1] = NULL,
|
||||
[ITEM_USE_PARTY_MENU - 1] = CB2_ShowPartyMenuForItemUse,
|
||||
[ITEM_USE_FIELD - 1] = CB2_ReturnToField,
|
||||
[ITEM_USE_PBLOCK_CASE - 1] = NULL,
|
||||
[ITEM_USE_PARTY_MENU_MOVES - 1] = CB2_ShowPartyMenuForItemUse,
|
||||
};
|
||||
|
||||
static const u8 sClockwiseDirections[] = {DIR_NORTH, DIR_EAST, DIR_SOUTH, DIR_WEST};
|
||||
@ -1105,25 +1107,6 @@ static void Task_UseStatIncreaseItem(u8 taskId)
|
||||
}
|
||||
}
|
||||
|
||||
// e.g. X Attack, Guard Spec
|
||||
void ItemUseInBattle_StatIncrease(u8 taskId)
|
||||
{
|
||||
u16 partyId = gBattlerPartyIndexes[gBattlerInMenuId];
|
||||
|
||||
if (ExecuteTableBasedItemEffect(&gPlayerParty[partyId], gSpecialVar_ItemId, partyId, 0) != FALSE)
|
||||
{
|
||||
if (!InBattlePyramid())
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gText_WontHaveEffect, CloseItemMessage);
|
||||
else
|
||||
DisplayItemMessageInBattlePyramid(taskId, gText_WontHaveEffect, Task_CloseBattlePyramidBagMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
gTasks[taskId].func = Task_UseStatIncreaseItem;
|
||||
gTasks[taskId].data[8] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void ItemUseInBattle_ShowPartyMenu(u8 taskId)
|
||||
{
|
||||
if (!InBattlePyramid())
|
||||
@ -1138,41 +1121,119 @@ static void ItemUseInBattle_ShowPartyMenu(u8 taskId)
|
||||
}
|
||||
}
|
||||
|
||||
void ItemUseInBattle_Medicine(u8 taskId)
|
||||
void ItemUseInBattle_PartyMenu(u8 taskId)
|
||||
{
|
||||
gItemUseCB = ItemUseCB_Medicine;
|
||||
gItemUseCB = ItemUseCB_BattleScript;
|
||||
ItemUseInBattle_ShowPartyMenu(taskId);
|
||||
}
|
||||
|
||||
// Unused. Sacred Ash cannot be used in battle
|
||||
void ItemUseInBattle_SacredAsh(u8 taskId)
|
||||
void ItemUseInBattle_PartyMenuChooseMove(u8 taskId)
|
||||
{
|
||||
gItemUseCB = ItemUseCB_SacredAsh;
|
||||
gItemUseCB = ItemUseCB_BattleChooseMove;
|
||||
ItemUseInBattle_ShowPartyMenu(taskId);
|
||||
}
|
||||
|
||||
void ItemUseInBattle_PPRecovery(u8 taskId)
|
||||
// Returns whether an item can be used in battle and sets the fail text.
|
||||
static bool32 CannotUseBagBattleItem(u16 itemId)
|
||||
{
|
||||
gItemUseCB = ItemUseCB_PPRecovery;
|
||||
ItemUseInBattle_ShowPartyMenu(taskId);
|
||||
}
|
||||
u8 cannotUse = FALSE;
|
||||
u16 battleUsage = ItemId_GetBattleUsage(itemId);
|
||||
const u8* failStr = NULL;
|
||||
|
||||
// Fluffy Tail / Poke Doll
|
||||
void ItemUseInBattle_Escape(u8 taskId)
|
||||
{
|
||||
|
||||
if((gBattleTypeFlags & BATTLE_TYPE_TRAINER) == FALSE)
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
#if B_SEMI_INVULNERABLE_CATCH >= GEN_4
|
||||
case BALL_THROW_UNABLE_SEMI_INVULNERABLE:
|
||||
failStr = sText_CantThrowPokeBall_SemiInvulnerable;
|
||||
cannotUse++;
|
||||
break;
|
||||
#endif
|
||||
case BALL_THROW_UNABLE_DISABLED_FLAG:
|
||||
failStr = sText_CantThrowPokeBall_Disabled;
|
||||
cannotUse++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Max Mushrooms
|
||||
if (battleUsage == EFFECT_ITEM_INCREASE_ALL_STATS)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 1; i < NUM_STATS; i++)
|
||||
{
|
||||
if (CompareStat(gBattlerInMenuId, i, MAX_STAT_STAGE, CMP_EQUAL))
|
||||
{
|
||||
cannotUse++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (failStr != NULL)
|
||||
StringExpandPlaceholders(gStringVar4, failStr);
|
||||
else
|
||||
StringExpandPlaceholders(gStringVar4, gText_WontHaveEffect);
|
||||
return cannotUse;
|
||||
}
|
||||
|
||||
void ItemUseInBattle_BagMenu(u8 taskId)
|
||||
{
|
||||
if (CannotUseBagBattleItem(gSpecialVar_ItemId))
|
||||
{
|
||||
if (!InBattlePyramid())
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage);
|
||||
else
|
||||
DisplayItemMessageInBattlePyramid(taskId, gStringVar4, Task_CloseBattlePyramidBagMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
RemoveUsedItem();
|
||||
if (!InBattlePyramid())
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, Task_FadeAndCloseBagMenu);
|
||||
else
|
||||
DisplayItemMessageInBattlePyramid(taskId, gStringVar4, CloseBattlePyramidBag);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem);
|
||||
}
|
||||
}
|
||||
|
||||
void ItemUseOutOfBattle_EnigmaBerry(u8 taskId)
|
||||
@ -1219,33 +1280,6 @@ void ItemUseOutOfBattle_EnigmaBerry(u8 taskId)
|
||||
}
|
||||
}
|
||||
|
||||
void ItemUseInBattle_EnigmaBerry(u8 taskId)
|
||||
{
|
||||
switch (GetItemEffectType(gSpecialVar_ItemId))
|
||||
{
|
||||
case ITEM_EFFECT_X_ITEM:
|
||||
ItemUseInBattle_StatIncrease(taskId);
|
||||
break;
|
||||
case ITEM_EFFECT_HEAL_HP:
|
||||
case ITEM_EFFECT_CURE_POISON:
|
||||
case ITEM_EFFECT_CURE_SLEEP:
|
||||
case ITEM_EFFECT_CURE_BURN:
|
||||
case ITEM_EFFECT_CURE_FREEZE:
|
||||
case ITEM_EFFECT_CURE_PARALYSIS:
|
||||
case ITEM_EFFECT_CURE_ALL_STATUS:
|
||||
case ITEM_EFFECT_CURE_CONFUSION:
|
||||
case ITEM_EFFECT_CURE_INFATUATION:
|
||||
ItemUseInBattle_Medicine(taskId);
|
||||
break;
|
||||
case ITEM_EFFECT_HEAL_PP:
|
||||
ItemUseInBattle_PPRecovery(taskId);
|
||||
break;
|
||||
default:
|
||||
ItemUseOutOfBattle_CannotUse(taskId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ItemUseOutOfBattle_FormChange(u8 taskId)
|
||||
{
|
||||
gItemUseCB = ItemUseCB_FormChange;
|
||||
|
222
src/party_menu.c
222
src/party_menu.c
@ -390,8 +390,8 @@ static void Task_DisplayHPRestoredMessage(u8);
|
||||
static u16 ItemEffectToMonEv(struct Pokemon *, u8);
|
||||
static void ItemEffectToStatString(u8, u8 *);
|
||||
static void ReturnToUseOnWhichMon(u8);
|
||||
static void SetSelectedMoveForPPItem(u8);
|
||||
static void TryUsePPItem(u8);
|
||||
static void SetSelectedMoveForItem(u8);
|
||||
static void TryUseItemOnMove(u8);
|
||||
static void Task_LearnedMove(u8);
|
||||
static void Task_ReplaceMoveYesNo(u8);
|
||||
static void Task_DoLearnedMoveFanfareAfterText(u8);
|
||||
@ -480,6 +480,9 @@ static bool8 SetUpFieldMove_Fly(void);
|
||||
static bool8 SetUpFieldMove_Waterfall(void);
|
||||
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"
|
||||
@ -4301,12 +4304,7 @@ static void Task_SetSacredAshCB(u8 taskId)
|
||||
|
||||
static bool8 IsHPRecoveryItem(u16 item)
|
||||
{
|
||||
const u8 *effect;
|
||||
|
||||
if (item == ITEM_ENIGMA_BERRY_E_READER)
|
||||
effect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
|
||||
else
|
||||
effect = gItemEffectTable[item];
|
||||
const u8 *effect = GetItemEffect(item);
|
||||
|
||||
if (effect == NULL)
|
||||
return FALSE;
|
||||
@ -4396,18 +4394,97 @@ static bool8 IsItemFlute(u16 item)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool8 ExecuteTableBasedItemEffect_(u8 partyMonIndex, u16 item, u8 monMoveIndex)
|
||||
static bool32 CannotUsePartyBattleItem(u16 itemId, struct Pokemon* mon)
|
||||
{
|
||||
if (gMain.inBattle)
|
||||
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))
|
||||
{
|
||||
if ((partyMonIndex == 0 && gStatuses3[B_POSITION_PLAYER_LEFT] & STATUS3_EMBARGO)
|
||||
|| (partyMonIndex == 1 && gStatuses3[B_POSITION_PLAYER_RIGHT] & STATUS3_EMBARGO))
|
||||
return TRUE; // cannot use on this mon
|
||||
else
|
||||
return ExecuteTableBasedItemEffect(&gPlayerParty[partyMonIndex], item, GetPartyIdFromBattleSlot(partyMonIndex), monMoveIndex);
|
||||
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))
|
||||
{
|
||||
gPartyMenuUseExitCallback = FALSE;
|
||||
PlaySE(SE_SELECT);
|
||||
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
gTasks[taskId].func = task;
|
||||
}
|
||||
else
|
||||
return ExecuteTableBasedItemEffect(&gPlayerParty[partyMonIndex], item, partyMonIndex, monMoveIndex);
|
||||
{
|
||||
gBattleStruct->itemPartyIndex[gBattlerInMenuId] = GetPartyIdFromBattleSlot(gPartyMenu.slotId);
|
||||
gPartyMenuUseExitCallback = TRUE;
|
||||
PlaySE(SE_SELECT);
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar2);
|
||||
StringExpandPlaceholders(gStringVar4, gText_PlayerUsedVar2);
|
||||
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
RemoveBagItem(gSpecialVar_ItemId, 1);
|
||||
gTasks[taskId].func = task;
|
||||
}
|
||||
}
|
||||
|
||||
void ItemUseCB_BattleChooseMove(u8 taskId, TaskFunc task)
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
DisplayPartyMenuStdMessage(PARTY_MSG_RESTORE_WHICH_MOVE);
|
||||
ShowMoveSelectWindow(gPartyMenu.slotId);
|
||||
gTasks[taskId].func = Task_HandleWhichMoveInput;
|
||||
}
|
||||
|
||||
void ItemUseCB_Medicine(u8 taskId, TaskFunc task)
|
||||
@ -4430,7 +4507,7 @@ void ItemUseCB_Medicine(u8 taskId, TaskFunc task)
|
||||
if (hp == GetMonData(mon, MON_DATA_MAX_HP))
|
||||
canHeal = FALSE;
|
||||
}
|
||||
cannotUse = ExecuteTableBasedItemEffect_(gPartyMenu.slotId, item, 0);
|
||||
cannotUse = ExecuteTableBasedItemEffect(mon, item, gPartyMenu.slotId, 0);
|
||||
}
|
||||
|
||||
if (cannotUse != FALSE)
|
||||
@ -4691,7 +4768,7 @@ void ItemUseCB_ReduceEV(u8 taskId, TaskFunc task)
|
||||
u8 effectType = GetItemEffectType(item);
|
||||
u16 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP);
|
||||
u16 ev = ItemEffectToMonEv(mon, effectType);
|
||||
bool8 cannotUseEffect = ExecuteTableBasedItemEffect_(gPartyMenu.slotId, item, 0);
|
||||
bool8 cannotUseEffect = ExecuteTableBasedItemEffect(mon, item, gPartyMenu.slotId, 0);
|
||||
u16 newFriendship = GetMonData(mon, MON_DATA_FRIENDSHIP);
|
||||
u16 newEv = ItemEffectToMonEv(mon, effectType);
|
||||
|
||||
@ -4807,25 +4884,19 @@ static void Task_HandleWhichMoveInput(u8 taskId)
|
||||
else
|
||||
{
|
||||
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
||||
SetSelectedMoveForPPItem(taskId);
|
||||
SetSelectedMoveForItem(taskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ItemUseCB_PPRecovery(u8 taskId, TaskFunc task)
|
||||
{
|
||||
const u8 *effect;
|
||||
u16 item = gSpecialVar_ItemId;
|
||||
|
||||
if (item == ITEM_ENIGMA_BERRY_E_READER)
|
||||
effect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
|
||||
else
|
||||
effect = gItemEffectTable[item];
|
||||
const u8 *effect = GetItemEffect(gSpecialVar_ItemId);
|
||||
|
||||
if (effect == NULL || !(effect[4] & ITEM4_HEAL_PP_ONE))
|
||||
{
|
||||
gPartyMenu.data1 = 0;
|
||||
TryUsePPItem(taskId);
|
||||
TryUseItemOnMove(taskId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4836,11 +4907,11 @@ void ItemUseCB_PPRecovery(u8 taskId, TaskFunc task)
|
||||
}
|
||||
}
|
||||
|
||||
static void SetSelectedMoveForPPItem(u8 taskId)
|
||||
static void SetSelectedMoveForItem(u8 taskId)
|
||||
{
|
||||
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
||||
gPartyMenu.data1 = Menu_GetCursorPos();
|
||||
TryUsePPItem(taskId);
|
||||
TryUseItemOnMove(taskId);
|
||||
}
|
||||
|
||||
static void ReturnToUseOnWhichMon(u8 taskId)
|
||||
@ -4851,34 +4922,61 @@ static void ReturnToUseOnWhichMon(u8 taskId)
|
||||
DisplayPartyMenuStdMessage(PARTY_MSG_USE_ON_WHICH_MON);
|
||||
}
|
||||
|
||||
static void TryUsePPItem(u8 taskId)
|
||||
static void TryUseItemOnMove(u8 taskId)
|
||||
{
|
||||
u16 move = MOVE_NONE;
|
||||
s16 *moveSlot = &gPartyMenu.data1;
|
||||
u16 item = gSpecialVar_ItemId;
|
||||
struct PartyMenu *ptr = &gPartyMenu;
|
||||
struct Pokemon *mon;
|
||||
|
||||
if (ExecuteTableBasedItemEffect_(ptr->slotId, item, *moveSlot))
|
||||
struct Pokemon *mon = &gPlayerParty[ptr->slotId];
|
||||
// In battle, set appropriate variables to be used in battle script.
|
||||
if (gMain.inBattle)
|
||||
{
|
||||
gPartyMenuUseExitCallback = FALSE;
|
||||
PlaySE(SE_SELECT);
|
||||
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
||||
if (CannotUsePartyBattleItem(gSpecialVar_ItemId, mon))
|
||||
{
|
||||
gPartyMenuUseExitCallback = FALSE;
|
||||
PlaySE(SE_SELECT);
|
||||
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleStruct->itemPartyIndex[gBattlerInMenuId] = GetPartyIdFromBattleSlot(gPartyMenu.slotId);
|
||||
gChosenMovePos = ptr->data1;
|
||||
gPartyMenuUseExitCallback = TRUE;
|
||||
RemoveBagItem(gSpecialVar_ItemId, 1);
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar2);
|
||||
StringExpandPlaceholders(gStringVar4, gText_PlayerUsedVar2);
|
||||
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
||||
}
|
||||
}
|
||||
// Outside of battle, only PP items are used on moves.
|
||||
else
|
||||
{
|
||||
gPartyMenuUseExitCallback = TRUE;
|
||||
mon = &gPlayerParty[ptr->slotId];
|
||||
PlaySE(SE_USE_ITEM);
|
||||
RemoveBagItem(item, 1);
|
||||
move = GetMonData(mon, MON_DATA_MOVE1 + *moveSlot);
|
||||
StringCopy(gStringVar1, gMoveNames[move]);
|
||||
GetMedicineItemEffectMessage(item);
|
||||
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
||||
u16 move = MOVE_NONE;
|
||||
s16 *moveSlot = &gPartyMenu.data1;
|
||||
u16 item = gSpecialVar_ItemId;
|
||||
|
||||
if (ExecuteTableBasedItemEffect(mon, item, ptr->slotId, *moveSlot))
|
||||
{
|
||||
gPartyMenuUseExitCallback = FALSE;
|
||||
PlaySE(SE_SELECT);
|
||||
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
||||
}
|
||||
else
|
||||
{
|
||||
gPartyMenuUseExitCallback = TRUE;
|
||||
PlaySE(SE_USE_ITEM);
|
||||
RemoveBagItem(item, 1);
|
||||
move = GetMonData(mon, MON_DATA_MOVE1 + *moveSlot);
|
||||
StringCopy(gStringVar1, gMoveNames[move]);
|
||||
GetMedicineItemEffectMessage(item);
|
||||
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5192,7 +5290,7 @@ void ItemUseCB_RareCandy(u8 taskId, TaskFunc task)
|
||||
if (sInitialLevel != MAX_LEVEL)
|
||||
{
|
||||
BufferMonStatsToTaskData(mon, arrayPtr);
|
||||
cannotUseEffect = ExecuteTableBasedItemEffect_(gPartyMenu.slotId, *itemPtr, 0);
|
||||
cannotUseEffect = ExecuteTableBasedItemEffect(mon, gPartyMenu.slotId, *itemPtr, 0);
|
||||
BufferMonStatsToTaskData(mon, &ptr->data[NUM_STATS]);
|
||||
}
|
||||
else
|
||||
@ -5459,7 +5557,7 @@ static void UseSacredAsh(u8 taskId)
|
||||
}
|
||||
|
||||
hp = GetMonData(mon, MON_DATA_HP);
|
||||
if (ExecuteTableBasedItemEffect_(gPartyMenu.slotId, gSpecialVar_ItemId, 0))
|
||||
if (ExecuteTableBasedItemEffect(mon, gSpecialVar_ItemId, gPartyMenu.slotId, 0))
|
||||
{
|
||||
gTasks[taskId].func = Task_SacredAshLoop;
|
||||
return;
|
||||
@ -5526,7 +5624,7 @@ void ItemUseCB_EvolutionStone(u8 taskId, TaskFunc task)
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
gCB2_AfterEvolution = gPartyMenu.exitCallback;
|
||||
if (ExecuteTableBasedItemEffect_(gPartyMenu.slotId, gSpecialVar_ItemId, 0))
|
||||
if (ExecuteTableBasedItemEffect(&gPlayerParty[gPartyMenu.slotId], gSpecialVar_ItemId, gPartyMenu.slotId, 0))
|
||||
{
|
||||
gPartyMenuUseExitCallback = FALSE;
|
||||
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
|
||||
@ -5691,16 +5789,18 @@ void TryItemHoldFormChange(struct Pokemon *mon)
|
||||
#undef tAnimWait
|
||||
#undef tNextFunc
|
||||
|
||||
const u8* GetItemEffect(u16 item)
|
||||
{
|
||||
if (item == ITEM_ENIGMA_BERRY_E_READER)
|
||||
return gSaveBlock1Ptr->enigmaBerry.itemEffect;
|
||||
else
|
||||
return gItemEffectTable[item];
|
||||
}
|
||||
|
||||
u8 GetItemEffectType(u16 item)
|
||||
{
|
||||
const u8 *itemEffect;
|
||||
u32 statusCure;
|
||||
|
||||
// Read the item's effect properties.
|
||||
if (item == ITEM_ENIGMA_BERRY_E_READER)
|
||||
itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
|
||||
else
|
||||
itemEffect = gItemEffectTable[item];
|
||||
const u8 *itemEffect = GetItemEffect(item);
|
||||
|
||||
if (itemEffect == NULL)
|
||||
return ITEM_EFFECT_NONE;
|
||||
|
220
src/pokemon.c
220
src/pokemon.c
@ -5736,55 +5736,16 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
|
||||
// Get item hold effect
|
||||
heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL);
|
||||
if (heldItem == ITEM_ENIGMA_BERRY_E_READER)
|
||||
{
|
||||
if (gMain.inBattle)
|
||||
holdEffect = gEnigmaBerries[gBattlerInMenuId].holdEffect;
|
||||
else
|
||||
holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
|
||||
}
|
||||
holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
|
||||
else
|
||||
{
|
||||
holdEffect = ItemId_GetHoldEffect(heldItem);
|
||||
}
|
||||
|
||||
// Get battler id (if relevant)
|
||||
gPotentialItemEffectBattler = gBattlerInMenuId;
|
||||
if (gMain.inBattle)
|
||||
{
|
||||
gActiveBattler = gBattlerInMenuId;
|
||||
i = (GetBattlerSide(gActiveBattler) != B_SIDE_PLAYER);
|
||||
while (i < gBattlersCount)
|
||||
{
|
||||
if (gBattlerPartyIndexes[i] == partyIndex)
|
||||
{
|
||||
battlerId = i;
|
||||
break;
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gActiveBattler = 0;
|
||||
battlerId = MAX_BATTLERS_COUNT;
|
||||
}
|
||||
|
||||
// Skip using the item if it won't do anything
|
||||
if (gItemEffectTable[item] == NULL && item != ITEM_ENIGMA_BERRY_E_READER)
|
||||
return TRUE;
|
||||
|
||||
// Get item effect
|
||||
if (item == ITEM_ENIGMA_BERRY_E_READER)
|
||||
{
|
||||
if (gMain.inBattle)
|
||||
itemEffect = gEnigmaBerries[gActiveBattler].itemEffect;
|
||||
else
|
||||
itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
|
||||
}
|
||||
else
|
||||
{
|
||||
itemEffect = gItemEffectTable[item];
|
||||
}
|
||||
itemEffect = GetItemEffect(item);
|
||||
|
||||
// Do item effect
|
||||
for (i = 0; i < ITEM_EFFECT_ARG_START; i++)
|
||||
@ -5793,85 +5754,13 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
|
||||
{
|
||||
|
||||
// Handle ITEM0 effects (infatuation, Dire Hit, X Attack). ITEM0_SACRED_ASH is handled in party_menu.c
|
||||
// Now handled in item battle scripts.
|
||||
case 0:
|
||||
// Cure infatuation
|
||||
if ((itemEffect[i] & ITEM0_INFATUATION)
|
||||
&& gMain.inBattle && battlerId != MAX_BATTLERS_COUNT && (gBattleMons[battlerId].status2 & STATUS2_INFATUATION))
|
||||
{
|
||||
gBattleMons[battlerId].status2 &= ~STATUS2_INFATUATION;
|
||||
retVal = FALSE;
|
||||
}
|
||||
|
||||
// Dire Hit
|
||||
if ((itemEffect[i] & ITEM0_DIRE_HIT)
|
||||
&& !(gBattleMons[gActiveBattler].status2 & STATUS2_FOCUS_ENERGY))
|
||||
{
|
||||
gBattleMons[gActiveBattler].status2 |= STATUS2_FOCUS_ENERGY;
|
||||
retVal = FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
// Handle ITEM1 effects (in-battle stat boosting effects)
|
||||
// Now handled in item battle scripts.
|
||||
case 1:
|
||||
// X Attack
|
||||
if ((itemEffect[i] & ITEM1_X_ATTACK)
|
||||
&& gBattleMons[gActiveBattler].statStages[STAT_ATK] < MAX_STAT_STAGE)
|
||||
{
|
||||
gBattleMons[gActiveBattler].statStages[STAT_ATK] += X_ITEM_STAGES;
|
||||
if (gBattleMons[gActiveBattler].statStages[STAT_ATK] > MAX_STAT_STAGE)
|
||||
gBattleMons[gActiveBattler].statStages[STAT_ATK] = MAX_STAT_STAGE;
|
||||
retVal = FALSE;
|
||||
}
|
||||
|
||||
// X Defense
|
||||
if ((itemEffect[i] & ITEM1_X_DEFENSE)
|
||||
&& gBattleMons[gActiveBattler].statStages[STAT_DEF] < MAX_STAT_STAGE)
|
||||
{
|
||||
gBattleMons[gActiveBattler].statStages[STAT_DEF] += X_ITEM_STAGES;
|
||||
if (gBattleMons[gActiveBattler].statStages[STAT_DEF] > MAX_STAT_STAGE)
|
||||
gBattleMons[gActiveBattler].statStages[STAT_DEF] = MAX_STAT_STAGE;
|
||||
retVal = FALSE;
|
||||
}
|
||||
|
||||
// X Speed
|
||||
if ((itemEffect[i] & ITEM1_X_SPEED)
|
||||
&& gBattleMons[gActiveBattler].statStages[STAT_SPEED] < MAX_STAT_STAGE)
|
||||
{
|
||||
gBattleMons[gActiveBattler].statStages[STAT_SPEED] += X_ITEM_STAGES;
|
||||
if (gBattleMons[gActiveBattler].statStages[STAT_SPEED] > MAX_STAT_STAGE)
|
||||
gBattleMons[gActiveBattler].statStages[STAT_SPEED] = MAX_STAT_STAGE;
|
||||
retVal = FALSE;
|
||||
}
|
||||
|
||||
// X Sp Attack
|
||||
if ((itemEffect[i] & ITEM1_X_SPATK)
|
||||
&& gBattleMons[gActiveBattler].statStages[STAT_SPATK] < MAX_STAT_STAGE)
|
||||
{
|
||||
gBattleMons[gActiveBattler].statStages[STAT_SPATK] += X_ITEM_STAGES;
|
||||
if (gBattleMons[gActiveBattler].statStages[STAT_SPATK] > MAX_STAT_STAGE)
|
||||
gBattleMons[gActiveBattler].statStages[STAT_SPATK] = MAX_STAT_STAGE;
|
||||
retVal = FALSE;
|
||||
}
|
||||
|
||||
// X Sp Defense
|
||||
if ((itemEffect[i] & ITEM1_X_SPDEF)
|
||||
&& gBattleMons[gActiveBattler].statStages[STAT_SPDEF] < MAX_STAT_STAGE)
|
||||
{
|
||||
gBattleMons[gActiveBattler].statStages[STAT_SPDEF] += X_ITEM_STAGES;
|
||||
if (gBattleMons[gActiveBattler].statStages[STAT_SPDEF] > MAX_STAT_STAGE)
|
||||
gBattleMons[gActiveBattler].statStages[STAT_SPDEF] = MAX_STAT_STAGE;
|
||||
retVal = FALSE;
|
||||
}
|
||||
|
||||
// X Accuracy
|
||||
if ((itemEffect[i] & ITEM1_X_ACCURACY)
|
||||
&& gBattleMons[gActiveBattler].statStages[STAT_ACC] < MAX_STAT_STAGE)
|
||||
{
|
||||
gBattleMons[gActiveBattler].statStages[STAT_ACC] += X_ITEM_STAGES;
|
||||
if (gBattleMons[gActiveBattler].statStages[STAT_ACC] > MAX_STAT_STAGE)
|
||||
gBattleMons[gActiveBattler].statStages[STAT_ACC] = MAX_STAT_STAGE;
|
||||
retVal = FALSE;
|
||||
}
|
||||
break;
|
||||
// Formerly used by the item effects of the X Sp. Atk and the X Accuracy
|
||||
case 2:
|
||||
@ -5879,14 +5768,6 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
|
||||
|
||||
// Handle ITEM3 effects (Guard Spec, Rare Candy, cure status)
|
||||
case 3:
|
||||
// Guard Spec
|
||||
if ((itemEffect[i] & ITEM3_GUARD_SPEC)
|
||||
&& gSideTimers[GetBattlerSide(gActiveBattler)].mistTimer == 0)
|
||||
{
|
||||
gSideTimers[GetBattlerSide(gActiveBattler)].mistTimer = 5;
|
||||
retVal = FALSE;
|
||||
}
|
||||
|
||||
// Rare Candy / EXP Candy
|
||||
if ((itemEffect[i] & ITEM3_LEVEL_UP)
|
||||
&& GetMonData(mon, MON_DATA_LEVEL, NULL) != MAX_LEVEL)
|
||||
@ -5915,13 +5796,8 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
|
||||
}
|
||||
|
||||
// Cure status
|
||||
if ((itemEffect[i] & ITEM3_SLEEP)
|
||||
&& HealStatusConditions(mon, partyIndex, STATUS1_SLEEP, battlerId) == 0)
|
||||
{
|
||||
if (battlerId != MAX_BATTLERS_COUNT)
|
||||
gBattleMons[battlerId].status2 &= ~STATUS2_NIGHTMARE;
|
||||
if ((itemEffect[i] & ITEM3_SLEEP) && HealStatusConditions(mon, partyIndex, STATUS1_SLEEP, battlerId) == 0)
|
||||
retVal = FALSE;
|
||||
}
|
||||
if ((itemEffect[i] & ITEM3_POISON) && HealStatusConditions(mon, partyIndex, STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER, battlerId) == 0)
|
||||
retVal = FALSE;
|
||||
if ((itemEffect[i] & ITEM3_BURN) && HealStatusConditions(mon, partyIndex, STATUS1_BURN, battlerId) == 0)
|
||||
@ -5930,12 +5806,6 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
|
||||
retVal = FALSE;
|
||||
if ((itemEffect[i] & ITEM3_PARALYSIS) && HealStatusConditions(mon, partyIndex, STATUS1_PARALYSIS, battlerId) == 0)
|
||||
retVal = FALSE;
|
||||
if ((itemEffect[i] & ITEM3_CONFUSION) // heal confusion
|
||||
&& gMain.inBattle && battlerId != MAX_BATTLERS_COUNT && (gBattleMons[battlerId].status2 & STATUS2_CONFUSION))
|
||||
{
|
||||
gBattleMons[battlerId].status2 &= ~STATUS2_CONFUSION;
|
||||
retVal = FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
// Handle ITEM4 effects (Change HP/Atk EVs, HP heal, PP heal, PP up, Revive, and evolution stones)
|
||||
@ -6022,38 +5892,12 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
|
||||
break;
|
||||
|
||||
case 2: // ITEM4_HEAL_HP
|
||||
// If Revive, update number of times revive has been used
|
||||
if (effectFlags & (ITEM4_REVIVE >> 2))
|
||||
// Check use validity.
|
||||
if ((effectFlags & (ITEM4_REVIVE >> 2) && GetMonData(mon, MON_DATA_HP, NULL) != 0)
|
||||
|| (!(effectFlags & (ITEM4_REVIVE >> 2)) && GetMonData(mon, MON_DATA_HP, NULL) == 0))
|
||||
{
|
||||
if (GetMonData(mon, MON_DATA_HP, NULL) != 0)
|
||||
{
|
||||
itemEffectParam++;
|
||||
break;
|
||||
}
|
||||
if (gMain.inBattle)
|
||||
{
|
||||
if (battlerId != MAX_BATTLERS_COUNT)
|
||||
{
|
||||
gAbsentBattlerFlags &= ~gBitTable[battlerId];
|
||||
CopyPlayerPartyMonToBattleData(battlerId, GetPartyIdFromBattlePartyId(gBattlerPartyIndexes[battlerId]));
|
||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleResults.numRevivesUsed < 255)
|
||||
gBattleResults.numRevivesUsed++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gAbsentBattlerFlags &= ~gBitTable[gActiveBattler ^ 2];
|
||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleResults.numRevivesUsed < 255)
|
||||
gBattleResults.numRevivesUsed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetMonData(mon, MON_DATA_HP, NULL) == 0)
|
||||
{
|
||||
itemEffectParam++;
|
||||
break;
|
||||
}
|
||||
itemEffectParam++;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get amount of HP to restore
|
||||
@ -6081,35 +5925,11 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
|
||||
// Only restore HP if not at max health
|
||||
if (GetMonData(mon, MON_DATA_MAX_HP, NULL) != GetMonData(mon, MON_DATA_HP, NULL))
|
||||
{
|
||||
if (!usedByAI)
|
||||
{
|
||||
// Restore HP
|
||||
dataUnsigned = GetMonData(mon, MON_DATA_HP, NULL) + dataUnsigned;
|
||||
if (dataUnsigned > GetMonData(mon, MON_DATA_MAX_HP, NULL))
|
||||
dataUnsigned = GetMonData(mon, MON_DATA_MAX_HP, NULL);
|
||||
SetMonData(mon, MON_DATA_HP, &dataUnsigned);
|
||||
|
||||
// Update battler (if applicable)
|
||||
if (gMain.inBattle && battlerId != MAX_BATTLERS_COUNT)
|
||||
{
|
||||
gBattleMons[battlerId].hp = dataUnsigned;
|
||||
if (!(effectFlags & (ITEM4_REVIVE >> 2)) && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
||||
{
|
||||
if (gBattleResults.numHealingItemsUsed < 255)
|
||||
gBattleResults.numHealingItemsUsed++;
|
||||
|
||||
temp2 = gActiveBattler;
|
||||
gActiveBattler = battlerId;
|
||||
BtlController_EmitGetMonData(BUFFER_A, REQUEST_ALL_BATTLE, 0);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
gActiveBattler = temp2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMoveDamage = -dataUnsigned;
|
||||
}
|
||||
// Restore HP
|
||||
dataUnsigned = GetMonData(mon, MON_DATA_HP, NULL) + dataUnsigned;
|
||||
if (dataUnsigned > GetMonData(mon, MON_DATA_MAX_HP, NULL))
|
||||
dataUnsigned = GetMonData(mon, MON_DATA_MAX_HP, NULL);
|
||||
SetMonData(mon, MON_DATA_HP, &dataUnsigned);
|
||||
retVal = FALSE;
|
||||
}
|
||||
effectFlags &= ~(ITEM4_REVIVE >> 2);
|
||||
@ -6134,11 +5954,6 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
|
||||
dataUnsigned = CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), temp2);
|
||||
}
|
||||
SetMonData(mon, MON_DATA_PP1 + temp2, &dataUnsigned);
|
||||
|
||||
// Heal battler PP too (if applicable)
|
||||
if (gMain.inBattle && battlerId != MAX_BATTLERS_COUNT && MOVE_IS_PERMANENT(battlerId, temp2))
|
||||
gBattleMons[battlerId].pp[temp2] = dataUnsigned;
|
||||
|
||||
retVal = FALSE;
|
||||
}
|
||||
}
|
||||
@ -6160,11 +5975,6 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
|
||||
dataUnsigned = CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex);
|
||||
}
|
||||
SetMonData(mon, MON_DATA_PP1 + moveIndex, &dataUnsigned);
|
||||
|
||||
// Heal battler PP too (if applicable)
|
||||
if (gMain.inBattle && battlerId != MAX_BATTLERS_COUNT && MOVE_IS_PERMANENT(battlerId, moveIndex))
|
||||
gBattleMons[battlerId].pp[moveIndex] = dataUnsigned;
|
||||
|
||||
retVal = FALSE;
|
||||
}
|
||||
}
|
||||
|
25
test/item_effect_increase_stat.c
Normal file
25
test/item_effect_increase_stat.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("X-Attack sharply raises battler's attack stat", s16 damage)
|
||||
{
|
||||
u16 useItem;
|
||||
PARAMETRIZE { useItem = FALSE; }
|
||||
PARAMETRIZE { useItem = TRUE; }
|
||||
GIVEN {
|
||||
ASSUME(gItems[ITEM_X_ATTACK].battleUsage == EFFECT_ITEM_INCREASE_STAT);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
if (useItem) TURN { USE_ITEM(player, ITEM_X_ATTACK); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Tackle!");
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
if (B_X_ITEMS_BUFF >= GEN_7)
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
|
||||
else
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
}
|
||||
}
|
37
test/item_effect_restore_hp.c
Normal file
37
test/item_effect_restore_hp.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Potion restores a battler's HP by 20")
|
||||
{
|
||||
s16 damage;
|
||||
GIVEN {
|
||||
ASSUME(gItems[ITEM_POTION].battleUsage == EFFECT_ITEM_RESTORE_HP);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(50); MaxHP(100); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { USE_ITEM(player, ITEM_POTION, partyIndex: 0); }
|
||||
} SCENE {
|
||||
HP_BAR(player, captureDamage: &damage);
|
||||
} FINALLY {
|
||||
EXPECT_EQ(damage, -20);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sitrus Berry restores a battler's HP")
|
||||
{
|
||||
s16 damage;
|
||||
GIVEN {
|
||||
ASSUME(gItems[ITEM_SITRUS_BERRY].battleUsage == EFFECT_ITEM_RESTORE_HP);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(50); MaxHP(100); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { USE_ITEM(player, ITEM_SITRUS_BERRY, partyIndex: 0); }
|
||||
} SCENE {
|
||||
HP_BAR(player, captureDamage: &damage);
|
||||
} FINALLY {
|
||||
if (I_SITRUS_BERRY_HEAL >= GEN_4)
|
||||
EXPECT_EQ(damage, -25);
|
||||
else
|
||||
EXPECT_EQ(damage, -30);
|
||||
}
|
||||
}
|
19
test/item_effect_restore_pp.c
Normal file
19
test/item_effect_restore_pp.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Ether restores the PP of one of a battler's moves")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gItems[ITEM_ETHER].battleUsage == EFFECT_ITEM_RESTORE_PP);
|
||||
ASSUME(gItems[ITEM_ETHER].type == ITEM_USE_PARTY_MENU_MOVES);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_CONFUSION); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
TURN { MOVE(player, MOVE_CONFUSION); }
|
||||
TURN { USE_ITEM(player, ITEM_ETHER, partyIndex: 0, move: MOVE_TACKLE); }
|
||||
} FINALLY {
|
||||
EXPECT_EQ(player->pp[0], 35);
|
||||
EXPECT_EQ(player->pp[1], 24);
|
||||
}
|
||||
}
|
@ -334,6 +334,13 @@
|
||||
* via Switch, e.g. after fainting or due to a U-turn.
|
||||
* SEND_OUT(player, 1);
|
||||
*
|
||||
* USE_ITEM(battler, itemId, [partyIndex:], [move:])
|
||||
* Used when the battler chooses to use an item from the Bag. The item
|
||||
* ID must be specified, and party index and move slot if applicable, e.g:
|
||||
* USE_ITEM(player, ITEM_X_ATTACK);
|
||||
* USE_ITEM(player, ITEM_POTION, partyIndex: 0);
|
||||
* USE_ITEM(player, ITEM_LEPPA_BERRY, partyIndex: 0, move: MOVE_TACKLE);
|
||||
*
|
||||
* SCENE
|
||||
* Contains an abridged description of the UI during the THEN. The order
|
||||
* of the description must match too, e.g.
|
||||
@ -765,7 +772,7 @@ enum { TURN_CLOSED, TURN_OPEN, TURN_CLOSING };
|
||||
#define SWITCH(battler, partyIndex) Switch(__LINE__, battler, partyIndex)
|
||||
#define SKIP_TURN(battler) SkipTurn(__LINE__, battler)
|
||||
#define SEND_OUT(battler, partyIndex) SendOut(__LINE__, battler, partyIndex)
|
||||
|
||||
#define USE_ITEM(battler, ...) UseItem(__LINE__, battler, (struct ItemContext) { APPEND_TRUE(__VA_ARGS__) })
|
||||
#define WITH_RNG(tag, value) rng: ((struct TurnRNG) { tag, value })
|
||||
|
||||
struct MoveContext
|
||||
@ -791,13 +798,23 @@ struct MoveContext
|
||||
bool8 explicitRNG;
|
||||
};
|
||||
|
||||
struct ItemContext
|
||||
{
|
||||
u16 itemId;
|
||||
u16 explicitItemId:1;
|
||||
u16 partyIndex;
|
||||
u16 explicitPartyIndex:1;
|
||||
u16 move;
|
||||
u16 explicitMove:1;
|
||||
};
|
||||
|
||||
void OpenTurn(u32 sourceLine);
|
||||
void CloseTurn(u32 sourceLine);
|
||||
void Move(u32 sourceLine, struct BattlePokemon *, struct MoveContext);
|
||||
void ForcedMove(u32 sourceLine, struct BattlePokemon *);
|
||||
void Switch(u32 sourceLine, struct BattlePokemon *, u32 partyIndex);
|
||||
void SkipTurn(u32 sourceLine, struct BattlePokemon *);
|
||||
|
||||
void UseItem(u32 sourceLine, struct BattlePokemon *, struct ItemContext);
|
||||
void SendOut(u32 sourceLine, struct BattlePokemon *, u32 partyIndex);
|
||||
|
||||
/* Scene */
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "battle_anim.h"
|
||||
#include "battle_controllers.h"
|
||||
#include "characters.h"
|
||||
#include "item_menu.h"
|
||||
#include "main.h"
|
||||
#include "malloc.h"
|
||||
#include "random.h"
|
||||
@ -1251,6 +1252,9 @@ void BattleTest_CheckBattleRecordActionType(u32 battlerId, u32 recordIndex, u32
|
||||
case B_ACTION_SWITCH:
|
||||
actualMacro = "SWITCH";
|
||||
break;
|
||||
case B_ACTION_USE_ITEM:
|
||||
actualMacro = "USE_ITEM";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RECORDED_PARTY_INDEX:
|
||||
@ -1508,6 +1512,40 @@ void SendOut(u32 sourceLine, struct BattlePokemon *battler, u32 partyIndex)
|
||||
DATA.currentMonIndexes[battlerId] = partyIndex;
|
||||
}
|
||||
|
||||
void UseItem(u32 sourceLine, struct BattlePokemon *battler, struct ItemContext ctx)
|
||||
{
|
||||
s32 i;
|
||||
s32 battlerId = battler - gBattleMons;
|
||||
bool32 requirePartyIndex = ItemId_GetType(ctx.itemId) == ITEM_USE_PARTY_MENU || ItemId_GetType(ctx.itemId) == ITEM_USE_PARTY_MENU_MOVES;
|
||||
// Check general bad use.
|
||||
INVALID_IF(DATA.turnState == TURN_CLOSED, "USE_ITEM outside TURN");
|
||||
INVALID_IF(DATA.actionBattlers & (1 << battlerId), "Multiple battler actions");
|
||||
INVALID_IF(ctx.itemId >= ITEMS_COUNT, "Illegal item: %d", ctx.itemId);
|
||||
// Check party menu items.
|
||||
INVALID_IF(requirePartyIndex && !ctx.explicitPartyIndex, "%S requires explicit party index", ItemId_GetName(ctx.itemId));
|
||||
INVALID_IF(requirePartyIndex && ctx.partyIndex >= ((battlerId & BIT_SIDE) == B_SIDE_PLAYER ? DATA.playerPartySize : DATA.opponentPartySize), \
|
||||
"USE_ITEM to invalid party index");
|
||||
// Check move slot items.
|
||||
if (ItemId_GetType(ctx.itemId) == ITEM_USE_PARTY_MENU_MOVES)
|
||||
{
|
||||
INVALID_IF(!ctx.explicitMove, "%S requires an explicit move", ItemId_GetName(ctx.itemId));
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (GetMonData(CurrentMon(battlerId), MON_DATA_MOVE1 + i, NULL) == ctx.move)
|
||||
break;
|
||||
}
|
||||
INVALID_IF(i == MAX_MON_MOVES, "USE_ITEM on invalid move: %d", ctx.move);
|
||||
}
|
||||
PushBattlerAction(sourceLine, battlerId, RECORDED_ACTION_TYPE, B_ACTION_USE_ITEM);
|
||||
PushBattlerAction(sourceLine, battlerId, RECORDED_ITEM_ID, (ctx.itemId >> 8) & 0xFF);
|
||||
PushBattlerAction(sourceLine, battlerId, RECORDED_ITEM_ID, ctx.itemId & 0xFF);
|
||||
if (ctx.explicitPartyIndex)
|
||||
gBattleStruct->itemPartyIndex[battlerId] = ctx.partyIndex;
|
||||
if (ctx.explicitMove)
|
||||
gBattleStruct->itemPartyIndex[battlerId] = i;
|
||||
DATA.actionBattlers |= 1 << battlerId;
|
||||
}
|
||||
|
||||
static const char *const sQueueGroupTypeMacros[] =
|
||||
{
|
||||
[QUEUE_GROUP_NONE] = NULL,
|
||||
|
Loading…
Reference in New Issue
Block a user