Decomp ApplyItemEffect; replace its stale extern with the new header

ApplyItemEffect (0x0231B68C, 1310 instructions in US, 1312 in EU) is the
thrown/eaten item dispatcher: an item-catcher preamble, the sticky-item
block, and then one switch (item->id) over a 183-entry jump table with 85
distinct case bodies, a shared tail that walks
APPLES_AND_BERRIES_ITEM_IDS, and EnemyEvolution. It is the last of ten
functions in asm/overlay_29_0231B33C.s and the next object in main.lsf is
src/overlay_29_0231CBC8.o, so extract_function.py merges rather than
splits and main.lsf is unchanged.

src/dungeon_projectile_throw.c declared ApplyItemEffect itself, with a
live call site. That extern is removed and the file now includes the new
header instead. It is a landed, already-matching object and parameters 1-3
are exactly where a wrong spelling would surface, so its rebuild in all
three regions is a check on the signature rather than tidying.

case ITEM_NOTHING is written explicitly above default even though the jump
table sends id 0 there. The dispatch is cmp r0,#0 / addge pc,pc,r0,lsl #2
with no rebase, and a survey of all 786 such dispatches in asm/ shows
MWCC's table spans the minimum to maximum LABELLED case: 104 of the 105
rebased tables have a real case at index 0, rebases occur for offsets as
small as 3, yet 40 tables have 3-7 leading default entries un-rebased and
82 have trailing default entries, which padding cannot explain. Leading
and trailing default entries are therefore explicit case labels sharing
default's body.

The category-5/10 test that skips the switch is an if/else whose else arm
is the entire switch; both arms fall into the shared tail. Case emission
order is source order and is not ascending (8 before 7, 77 before 74, 136
before 113, 182 before 104, default last).

The 41 callees that are still asm are declared extern in the .c with
prototypes read off their own asm, as the sibling files do, and so are the
28 rodata data symbols - const, with ov10_022C4864 as s32 where the other
25 scalars are s16, which is what makes its load a 32-bit ldr. Two
prototypes deliberately differ from pmdsky-debug: ApplyKeyEffect takes one
parameter, not two, and CalcDamageFixedNoCategory's fifth parameter points
at a one-byte object, not a struct damage_data.

Region handling: seven message ids are file-scope defines at US - 0x2C1
under JAPAN, and one EU-only call to ov29_022FB920 sits inside an
ifdef EUROPE with its prototype. The JP fork of the
exclusive_item_effect_flags offset needs nothing - the header already
models the 4-byte JP struct monster shrink.

Authored by Claude (Opus 5) under human direction. Confirmed by matching
builds of all three regions: build/pmdsky.us/pmdsky.us.nds: OK,
build/pmdsky.eu/pmdsky.eu.nds: OK, build/pmdsky.jp/pmdsky.jp.nds: OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
cecilarmitais
2026-09-06 17:16:55 -07:00
parent d387d4e273
commit d814f8d017
5 changed files with 614 additions and 1608 deletions

View File

@@ -1,117 +1,25 @@
#pragma once
.public AbilityIsActiveVeneer
.public AddHeldItemToBag
.public AnimationDelayOrSomething
.public APPLES_AND_BERRIES_ITEM_IDS
.public ApplyBlastSeedEffect
.public ApplyCalciumEffect
.public ApplyCheriBerryEffect
.public ApplyDoughSeedEffect
.public ApplyGinsengEffect
.public ApplyGonePebbleEffect
.public ApplyGracideaEffect
.public ApplyGravelyrockEffect
.public ApplyGrimyFoodEffect
.public ApplyGummiBoostsDungeonMode
.public ApplyHungerSeedEffect
.public ApplyIronEffect
.public ApplyKeyEffect
.public ApplyMixElixirEffect
.public ApplyPechaBerryEffect
.public ApplyProteinEffect
.public ApplyRawstBerryEffect
.public ApplyViaSeedEffect
.public ApplyVileSeedEffect
.public ApplyViolentSeedEffect
.public ApplyZincEffect
.public BoostIQ
.public BoostSpeedOneStage
.public CACNEA_SPIKE_POWER
.public CalcDamageFixedNoCategory
.public CALCIUM_STAT_BOOST
.public CalcStatusDuration
.public CheckVariousConditions__0230156C
.public CORSOLA_TWIG_POWER
.public DealDamageProjectile
.public DetermineMonsterShadow
.public DUNGEON_PTR
.public DetermineMonsterShadow
.public DungeonGetSpriteIndex
.public EndNegativeStatusConditionWrapper
.public EnemyEvolution
.public EntityIsValid__0231CBC8
.public ExclusiveItemEffectFlagTest
.public FemaleToMaleForm
.public FreezeAnim
.public GEO_PEBBLE_DAMAGE
.public GetActiveTeamMember
.public GetIdleAnimationId
.public GetItemCategoryVeneer
.public GOLD_FANG_POWER
.public GOLD_THORN_POWER
.public GRAVELEROCK_DAMAGE
.public GUMMI_STAT_BOOST
.public InitMove
.public IqSkillIsEnabled
.public IRON_STAT_BOOST
.public IRON_THORN_POWER
.public IsBagFull
.public IsShaymin
.public IsSkyExclusiveDungeon
.public LevelUpItemEffect
.public LIFE_SEED_HP_BOOST
.public LogMessageByIdWithPopupCheckUserTarget
.public ORAN_BERRY_FULL_HP_BOOST
.public ORAN_BERRY_HP_RESTORATION
.public OREN_BERRY_DAMAGE
.public ov10_022C44EC
.public ov10_022C4558
.public ov10_022C4574
.public SetMonsterTypeAndAbility
.public SwapMonsterWanFileIndex
.public UnfreezeAnim
.public ov10_022C457C
.public ov10_022C4864
.public ov29_022E3590
.public ov29_022E5A00
.public ov29_022E5AE4
.public ov29_022E60E4
.public ov29_022E81F8
.public ov29_022E9FD0
.public ov29_022EA370
.public ov29_022F9EA0
.public ov29_022FB920
.public ov29_022FB9BC
.public ov29_02304830
.public ov29_0230F9A4
.public PlaySeByIdIfNotSilence
.public PrepareItemForPrinting__02345728
.public PROTEIN_STAT_BOOST
.public RARE_FOSSIL_DAMAGE
.public RestoreAllMovePP
.public SetMonsterTypeAndAbility
.public SILVER_SPIKE_POWER
.public SITRUS_BERRY_FULL_HP_BOOST
.public SITRUS_BERRY_HP_RESTORATION
.public SLEEP_TURN_RANGE
.public SpawnDroppedItemWrapper
.public STICK_POWER
.public sub_020017EC
.public sub_0201CF80
.public SubstitutePlaceholderStringTags
.public SwapMonsterWanFileIndex
.public TryDecreaseLevel
.public TryIncreaseBelly
.public TryIncreaseHp
.public TryInflictBlinkerStatus
.public TryInflictConfusedStatus
.public TryInflictCrossEyedStatus
.public TryInflictDropeyeStatus
.public TryInflictEyedropStatus
.public TryInflictInvisibleStatus
.public TryInflictPetrifiedStatus
.public TryInflictSleeplessStatus
.public TryInflictSleepStatus
.public TryInflictSlipStatus
.public TryWarp
.public UnfreezeAnim
.public UpdateShopkeeperModeAfterAttack
.public WaitUntilAlertBoxPauseIsOver
.public WONDER_GUMMI_STAT_BOOST
.public ZINC_STAT_BOOST

File diff suppressed because it is too large Load Diff

View File

@@ -6,4 +6,6 @@
// Checks if an entity pointer points to a valid entity (not entity type 0, which represents no entity).
bool8 EntityIsValid__0231CBC8(struct entity *entity);
void ApplyItemEffect(char param_1, u8 param_2, u8 param_3, struct entity *attacker, struct entity *defender, struct item *item);
#endif //PMDSKY_OVERLAY_29_0231CBC8_H

View File

@@ -1,4 +1,5 @@
#include "dungeon_projectile_throw.h"
#include "overlay_29_0231CBC8.h"
#include "dg_object.h"
#include "dungeon.h"
#include "dungeon_items.h"
@@ -35,7 +36,6 @@ extern void SubstitutePlaceholderStringTags(s32 string_id, struct entity *entity
extern void ChangeMonsterAnimationToHurt(struct entity *monster, u32 direction);
extern void LogMessageByIdWithPopupCheckUserTarget(struct entity *user, struct entity *target, u32 message_id);
extern bool8 TryEndPetrifiedOrSleepStatus(struct entity *user, struct entity *target);
extern void ApplyItemEffect(char param_1, u8 param_2, u8 param_3, struct entity *attacker, struct entity *defender, struct item *thrown_item);
extern void SpawnDroppedItem(struct entity *entity, struct entity *item_entity, struct item *item, bool8 param_4, struct position *dir_xy, u32 param_6);
bool8 ItemIsActive__02347B50(struct entity *entity, enum item_id item_id)

View File

@@ -1,5 +1,612 @@
#include "overlay_29_0231CBC8.h"
#include "dungeon_util_static.h"
#include "dungeon_capabilities_1.h"
#include "dungeon_pokemon_attributes_1.h"
#include "exclusive_item.h"
#include "item_util.h"
#include "main_0200EDC0.h"
#include "move_orb_effects.h"
#include "moves_1.h"
#include "overlay_29_022EAC7C.h"
#include "overlay_29_02344AF8.h"
#include "overlay_29_0234BA54.h"
#ifdef JAPAN
#define MESSAGE_BE6 0x925
#define MESSAGE_BE7 0x926
#define MESSAGE_BE8 0x927
#define MESSAGE_BE9 0x928
#define MESSAGE_C67 0x9A6
#define MESSAGE_C75 0x9B4
#define MESSAGE_C76 0x9B5
#else
#define MESSAGE_BE6 0xBE6
#define MESSAGE_BE7 0xBE7
#define MESSAGE_BE8 0xBE8
#define MESSAGE_BE9 0xBE9
#define MESSAGE_C67 0xC67
#define MESSAGE_C75 0xC75
#define MESSAGE_C76 0xC76
#endif
#ifdef EUROPE
extern void ov29_022FB920(bool8 a);
#endif
extern void LogMessageByIdWithPopupCheckUserTarget(struct entity *user, struct entity *target, u32 message_id);
extern void SubstitutePlaceholderStringTags(s32 string_id, struct entity *entity, u32 param_3);
extern void TryIncreaseHp(struct entity *user, struct entity *target, s32 hp, s32 a, bool8 b);
extern void EndNegativeStatusConditionWrapper(struct entity *user, struct entity *target, bool8 displayMessage, bool8 fromMove);
extern bool8 SpawnDroppedItemWrapper(struct entity *entity, struct position *pos, struct item *item, u32 a);
extern void TryWarp(struct entity *user, struct entity *target, s32 a, s32 b);
extern void BoostIQ(struct entity *entity, s16 iq, bool8 a);
extern void UpdateShopkeeperModeAfterAttack(struct entity *attacker, struct entity *defender);
extern void TryInflictConfusedStatus(struct entity *user, struct entity *target, bool8 a, bool8 b);
extern void TryInflictInvisibleStatus(struct entity *user, struct entity *target);
extern void TryInflictPetrifiedStatus(struct entity *user, struct entity *target);
extern void TryInflictSleeplessStatus(struct entity *user, struct entity *target);
extern s32 CalcStatusDuration(struct entity *entity, const s16 *turn_range, bool8 iq_skill_effects);
extern void CalcDamageFixedNoCategory(struct entity *attacker, struct entity *defender, s16 fixed_damage, s32 a, bool8 *flag, s32 b, s32 damage_source, s32 c, s32 d, s32 e);
extern void DealDamageProjectile(struct entity *attacker, struct entity *defender, struct move *move, s16 power, s32 a, s32 b);
extern void ApplyGummiBoostsDungeonMode(struct entity *user, struct entity *target, s32 type, s16 boost);
extern void TryIncreaseBelly(struct entity *user, struct entity *target, s32 a, s32 b, s32 c);
extern void LevelUpItemEffect(struct entity *user, struct entity *target, s32 a, s32 b, s32 c);
extern void RestoreAllMovePP(struct entity *user, struct entity *target, s32 a, s32 b);
extern void TryInflictSleepStatus(struct entity *user, struct entity *target, s32 turns, bool8 a);
extern void TryInflictBlinkerStatus(struct entity *user, struct entity *target, bool8 a, bool8 b);
extern void TryInflictCrossEyedStatus(struct entity *user, struct entity *target, bool8 a);
extern void TryDecreaseLevel(struct entity *user, struct entity *target, s32 a);
extern void ApplyProteinEffect(struct entity *user, struct entity *target, s16 boost);
extern void ApplyCalciumEffect(struct entity *user, struct entity *target, s16 boost);
extern void ApplyIronEffect(struct entity *user, struct entity *target, s16 boost);
extern void ApplyZincEffect(struct entity *user, struct entity *target, s16 boost);
extern void ApplyBlastSeedEffect(struct entity *user, struct entity *target, char a);
extern void ApplyCheriBerryEffect(struct entity *user, struct entity *target);
extern void ApplyPechaBerryEffect(struct entity *user, struct entity *target);
extern void ApplyRawstBerryEffect(struct entity *user, struct entity *target);
extern void ApplyHungerSeedEffect(struct entity *user, struct entity *target);
extern void ApplyGinsengEffect(struct entity *user, struct entity *target);
extern void ApplyVileSeedEffect(struct entity *user, struct entity *target);
extern void ApplyViolentSeedEffect(struct entity *user, struct entity *target);
extern void ApplyGrimyFoodEffect(struct entity *user, struct entity *target);
extern void ApplyMixElixirEffect(struct entity *user, struct entity *target);
extern void ApplyDoughSeedEffect(struct entity *user, struct entity *target);
extern void ApplyViaSeedEffect(struct entity *user, struct entity *target);
extern void ApplyGravelyrockEffect(struct entity *user, struct entity *target);
extern void ApplyGonePebbleEffect(struct entity *user, struct entity *target);
extern void ApplyGracideaEffect(struct entity *user, struct entity *target);
extern void TryInflictDropeyeStatus(struct entity *user, struct entity *target);
extern void TryInflictEyedropStatus(struct entity *user, struct entity *target);
extern bool8 TryInflictSlipStatus(struct entity *user, struct entity *target);
extern void ov29_022E5A00(struct entity *entity, struct item *item);
extern void ov29_022E5AE4(struct entity *entity, struct item *item);
extern void ov29_0230F9A4(struct entity *entity, struct item *item);
extern bool8 ov29_022FB9BC(struct entity *entity);
extern void ov29_022F9EA0(struct entity *entity);
extern void EnemyEvolution(struct entity *entity);
extern bool8 AddHeldItemToBag(struct monster *monster);
extern void ApplyKeyEffect(struct entity *entity);
extern const s16 STICK_POWER;
extern const s16 IRON_THORN_POWER;
extern const s16 SILVER_SPIKE_POWER;
extern const s16 GOLD_FANG_POWER;
extern const s16 CACNEA_SPIKE_POWER;
extern const s16 CORSOLA_TWIG_POWER;
extern const s16 GOLD_THORN_POWER;
extern const s16 GEO_PEBBLE_DAMAGE;
extern const s16 GRAVELEROCK_DAMAGE;
extern const s16 RARE_FOSSIL_DAMAGE;
extern const s16 OREN_BERRY_DAMAGE;
extern const s16 ORAN_BERRY_HP_RESTORATION;
extern const s16 ORAN_BERRY_FULL_HP_BOOST;
extern const s16 SITRUS_BERRY_HP_RESTORATION;
extern const s16 SITRUS_BERRY_FULL_HP_BOOST;
extern const s16 LIFE_SEED_HP_BOOST;
extern const s16 PROTEIN_STAT_BOOST;
extern const s16 CALCIUM_STAT_BOOST;
extern const s16 IRON_STAT_BOOST;
extern const s16 ZINC_STAT_BOOST;
extern const s16 GUMMI_STAT_BOOST;
extern const s16 WONDER_GUMMI_STAT_BOOST;
extern const s16 ov10_022C44EC;
extern const s16 ov10_022C4558;
extern const s16 ov10_022C4574;
extern const s32 ov10_022C4864;
extern const s16 SLEEP_TURN_RANGE[];
extern const s16 APPLES_AND_BERRIES_ITEM_IDS[];
void ApplyItemEffect(char param_1, u8 param_2, u8 param_3,
struct entity *attacker, struct entity *defender,
struct item *item)
{
if (param_1 != 0 && param_2 == 0) {
struct monster *monster = GetEntInfo(defender);
bool8 flag = FALSE;
if (ov29_022FB9BC(defender)) {
SpawnDroppedItemWrapper(attacker, &defender->pos, item, 0);
return;
}
if (monster->is_not_team_member) {
if (GetItemCategoryVeneer(item->id) != CATEGORY_THROWN_LINE &&
GetItemCategoryVeneer(item->id) != CATEGORY_BERRIES_SEEDS_VITAMINS &&
GetItemCategoryVeneer(item->id) != CATEGORY_THROWN_ARC) {
flag = TRUE;
}
if (GetItemCategoryVeneer(item->id) == CATEGORY_HELD_ITEMS &&
item->id >= ITEM_A_STONE && item->id <= ITEM_QUESTION_STONE) {
flag = FALSE;
}
} else if (GetItemCategoryVeneer(item->id) != CATEGORY_BERRIES_SEEDS_VITAMINS) {
flag = IqSkillIsEnabled(defender, IQ_ITEM_CATCHER);
}
if (CheckVariousConditions__0230156C(defender)) {
flag = FALSE;
}
if (flag) {
if (!ItemExists(monster->held_item.flags)) {
if (monster->is_not_team_member || !IsBagFull()) {
if (monster->shopkeeper == SHOPKEEPER_MODE_SHOPKEEPER) {
SpawnDroppedItemWrapper(attacker, &defender->pos, item, 0);
return;
}
PlaySeByIdIfNotSilence(0x1317);
PrepareItemForPrinting__02345728(0, item);
SubstitutePlaceholderStringTags(0, defender, 0);
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_BE6);
monster->held_item = *item;
if (!monster->is_not_team_member) {
AddHeldItemToBag(monster);
}
ov29_022F9EA0(defender);
return;
}
}
}
}
if (param_1) {
ov29_022E5A00(defender, item);
UpdateShopkeeperModeAfterAttack(attacker, defender);
}
if (ItemSticky(item->flags)) {
PrepareItemForPrinting__02345728(0, item);
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_BE7);
if (param_1) {
bool8 b;
CalcDamageFixedNoCategory(attacker, defender, ov10_022C4574, 1, &b, 0,
DAMAGE_SOURCE_THROWN_ITEM, 0, 0, 0);
EnemyEvolution(attacker);
return;
}
}
if (!param_1) {
ov29_022E5AE4(defender, item);
}
ov29_0230F9A4(attacker, item);
if (GetItemCategoryVeneer(item->id) == CATEGORY_BERRIES_SEEDS_VITAMINS) {
TryIncreaseBelly(attacker, defender, 5, 0, 0);
}
if (GetItemCategoryVeneer(item->id) == CATEGORY_TMS_HMS ||
GetItemCategoryVeneer(item->id) == CATEGORY_LINK_BOX) {
if (param_1) {
bool8 b;
CalcDamageFixedNoCategory(attacker, defender, ov10_022C4558, 1, &b, 0,
DAMAGE_SOURCE_THROWN_ITEM, 0, 0, 0);
} else {
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_BE8);
}
} else {
switch (item->id) {
case ITEM_STICK: {
struct move move;
InitMove(&move, MOVE_PROJECTILE);
DealDamageProjectile(attacker, defender, &move, STICK_POWER, 0x100, ITEM_STICK);
break;
}
case ITEM_IRON_THORN: {
struct move move;
InitMove(&move, MOVE_PROJECTILE);
DealDamageProjectile(attacker, defender, &move, IRON_THORN_POWER, 0x100, ITEM_IRON_THORN);
break;
}
case ITEM_SILVER_SPIKE: {
struct move move;
InitMove(&move, MOVE_PROJECTILE);
DealDamageProjectile(attacker, defender, &move, SILVER_SPIKE_POWER, 0x100, ITEM_SILVER_SPIKE);
break;
}
case ITEM_GOLD_FANG: {
struct move move;
InitMove(&move, MOVE_PROJECTILE);
DealDamageProjectile(attacker, defender, &move, GOLD_FANG_POWER, 0x100, ITEM_GOLD_FANG);
break;
}
case ITEM_CACNEA_SPIKE: {
struct move move;
InitMove(&move, MOVE_PROJECTILE);
DealDamageProjectile(attacker, defender, &move, CACNEA_SPIKE_POWER, 0x100, ITEM_CACNEA_SPIKE);
break;
}
case ITEM_CORSOLA_TWIG: {
struct move move;
InitMove(&move, MOVE_PROJECTILE);
DealDamageProjectile(attacker, defender, &move, CORSOLA_TWIG_POWER, 0x100, ITEM_CORSOLA_TWIG);
break;
}
case ITEM_GEO_PEBBLE:
CalcDamageFixedNoCategory(attacker, defender, GEO_PEBBLE_DAMAGE, 1, NULL, 0, DAMAGE_SOURCE_THROWN_ROCK, 0, 0, 0);
break;
case ITEM_GRAVELEROCK:
CalcDamageFixedNoCategory(attacker, defender, GRAVELEROCK_DAMAGE, 1, NULL, 0, DAMAGE_SOURCE_THROWN_ROCK, 0, 0, 0);
break;
case ITEM_GOLD_THORN: {
struct move move;
InitMove(&move, MOVE_PROJECTILE);
DealDamageProjectile(attacker, defender, &move, GOLD_THORN_POWER, 0x100, ITEM_GOLD_THORN);
break;
}
case ITEM_RARE_FOSSIL:
CalcDamageFixedNoCategory(attacker, defender, RARE_FOSSIL_DAMAGE, 1, NULL, 0, DAMAGE_SOURCE_THROWN_ROCK, 0, 0, 0);
break;
case ITEM_HEAL_SEED:
EndNegativeStatusConditionWrapper(attacker, defender, TRUE, param_3);
break;
case ITEM_ORAN_BERRY:
TryIncreaseHp(attacker, defender, ORAN_BERRY_HP_RESTORATION, ORAN_BERRY_FULL_HP_BOOST, TRUE);
break;
case ITEM_SITRUS_BERRY:
TryIncreaseHp(attacker, defender, SITRUS_BERRY_HP_RESTORATION, SITRUS_BERRY_FULL_HP_BOOST, TRUE);
break;
case ITEM_LIFE_SEED:
TryIncreaseHp(attacker, defender, 0, LIFE_SEED_HP_BOOST, TRUE);
break;
case ITEM_BLINKER_SEED:
TryInflictBlinkerStatus(attacker, defender, FALSE, FALSE);
break;
case ITEM_X_EYE_SEED:
TryInflictCrossEyedStatus(attacker, defender, FALSE);
break;
case ITEM_QUICK_SEED:
BoostSpeedOneStage(attacker, defender, 0, TRUE);
break;
case ITEM_EYEDROP_SEED:
TryInflictEyedropStatus(attacker, defender);
break;
case ITEM_TOTTER_SEED:
TryInflictConfusedStatus(attacker, defender, TRUE, FALSE);
break;
case ITEM_CHERI_BERRY:
ApplyCheriBerryEffect(attacker, defender);
break;
case ITEM_PECHA_BERRY:
ApplyPechaBerryEffect(attacker, defender);
break;
case ITEM_WARP_SEED:
TryWarp(attacker, defender, 0, 0);
break;
case ITEM_SLEEP_SEED:
TryInflictSleepStatus(attacker, defender, CalcStatusDuration(defender, SLEEP_TURN_RANGE, TRUE), TRUE);
break;
case ITEM_CHESTO_BERRY:
TryInflictSleeplessStatus(attacker, defender);
break;
case ITEM_JOY_SEED:
LevelUpItemEffect(attacker, defender, 1, 1, 1);
break;
case ITEM_DOOM_SEED:
TryDecreaseLevel(attacker, defender, 1);
break;
case ITEM_STUN_SEED:
TryInflictPetrifiedStatus(attacker, defender);
break;
case ITEM_PLAIN_SEED:
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_BE9);
break;
case ITEM_RAWST_BERRY:
ApplyRawstBerryEffect(attacker, defender);
break;
case ITEM_HUNGER_SEED:
ApplyHungerSeedEffect(attacker, defender);
break;
case ITEM_GINSENG:
ApplyGinsengEffect(attacker, defender);
break;
case ITEM_BLAST_SEED:
ApplyBlastSeedEffect(attacker, defender, param_1);
break;
case ITEM_MAX_ELIXIR:
RestoreAllMovePP(attacker, defender, 999, 0);
break;
case ITEM_PROTEIN:
ApplyProteinEffect(attacker, defender, PROTEIN_STAT_BOOST);
break;
case ITEM_CALCIUM:
ApplyCalciumEffect(attacker, defender, CALCIUM_STAT_BOOST);
break;
case ITEM_IRON:
ApplyIronEffect(attacker, defender, IRON_STAT_BOOST);
break;
case ITEM_ZINC:
ApplyZincEffect(attacker, defender, ZINC_STAT_BOOST);
break;
case ITEM_GABITE_SCALE:
EndNegativeStatusConditionWrapper(attacker, defender, TRUE, FALSE);
break;
case ITEM_GOLDEN_SEED:
LevelUpItemEffect(attacker, defender, 5, 1, 1);
break;
case ITEM_VILE_SEED:
ApplyVileSeedEffect(attacker, defender);
break;
case ITEM_PURE_SEED:
TryWarp(attacker, defender, 4, 0);
break;
case ITEM_VIOLENT_SEED:
ApplyViolentSeedEffect(attacker, defender);
break;
case ITEM_VANISH_SEED:
TryInflictInvisibleStatus(attacker, defender);
break;
case ITEM_NECTAR:
BoostIQ(defender, 10, FALSE);
break;
case ITEM_APPLE:
TryIncreaseBelly(attacker, defender, 50, 5, 1);
break;
case ITEM_BIG_APPLE:
TryIncreaseBelly(attacker, defender, 100, 10, 1);
break;
case ITEM_HUGE_APPLE:
TryIncreaseBelly(attacker, defender, 999, 10, 1);
break;
case ITEM_GRIMY_FOOD:
ApplyGrimyFoodEffect(attacker, defender);
break;
case ITEM_WHITE_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_NORMAL, GUMMI_STAT_BOOST);
break;
case ITEM_RED_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_FIRE, GUMMI_STAT_BOOST);
break;
case ITEM_BLUE_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_WATER, GUMMI_STAT_BOOST);
break;
case ITEM_GRASS_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_GRASS, GUMMI_STAT_BOOST);
break;
case ITEM_YELLOW_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_ELECTRIC, GUMMI_STAT_BOOST);
break;
case ITEM_CLEAR_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_ICE, GUMMI_STAT_BOOST);
break;
case ITEM_ORANGE_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_FIGHTING, GUMMI_STAT_BOOST);
break;
case ITEM_PINK_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_POISON, GUMMI_STAT_BOOST);
break;
case ITEM_BROWN_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_GROUND, GUMMI_STAT_BOOST);
break;
case ITEM_SKY_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_FLYING, GUMMI_STAT_BOOST);
break;
case ITEM_GOLD_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_PSYCHIC, GUMMI_STAT_BOOST);
break;
case ITEM_GREEN_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_BUG, GUMMI_STAT_BOOST);
break;
case ITEM_GRAY_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_ROCK, GUMMI_STAT_BOOST);
break;
case ITEM_PURPLE_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_GHOST, GUMMI_STAT_BOOST);
break;
case ITEM_ROYAL_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_DRAGON, GUMMI_STAT_BOOST);
break;
case ITEM_BLACK_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_DARK, GUMMI_STAT_BOOST);
break;
case ITEM_SILVER_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, TYPE_STEEL, GUMMI_STAT_BOOST);
break;
case ITEM_WONDER_GUMMI:
ApplyGummiBoostsDungeonMode(attacker, defender, 0xFF, WONDER_GUMMI_STAT_BOOST);
break;
case ITEM_UNNAMED_0x71:
TryIncreaseBelly(attacker, defender, 50, 5, 1);
break;
case ITEM_UNNAMED_0x72:
TryIncreaseBelly(attacker, defender, 10, 0, 1);
break;
case ITEM_GOLDEN_APPLE:
TryIncreaseBelly(attacker, defender, 999, 50, 1);
break;
case ITEM_KEY:
if (param_1) {
bool8 flag;
CalcDamageFixedNoCategory(attacker, defender, ov10_022C4558, 1, &flag, 0,
DAMAGE_SOURCE_THROWN_ITEM, 0, 0, 0);
}
else {
ApplyKeyEffect(attacker);
}
break;
case ITEM_DROPEYE_SEED:
TryInflictDropeyeStatus(attacker, defender);
break;
case ITEM_SLIP_SEED:
if (!TryInflictSlipStatus(attacker, defender)) {
SubstitutePlaceholderStringTags(0, defender, 0);
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_C75);
}
break;
case ITEM_VIA_SEED:
ApplyViaSeedEffect(attacker, defender);
break;
case ITEM_MIX_ELIXIR:
ApplyMixElixirEffect(attacker, defender);
break;
case ITEM_OREN_BERRY:
CalcDamageFixedNoCategory(attacker, defender, OREN_BERRY_DAMAGE, 1, NULL, 0,
DAMAGE_SOURCE_OREN_BERRY, 0, 0, 0);
break;
case ITEM_DOUGH_SEED:
ApplyDoughSeedEffect(attacker, defender);
break;
case ITEM_GRAVELYROCK:
ApplyGravelyrockEffect(attacker, defender);
break;
case ITEM_GONE_PEBBLE:
ApplyGonePebbleEffect(attacker, defender);
break;
case ITEM_WANDER_GUMMI:
TryInflictBlinkerStatus(attacker, defender, 0, 0);
break;
case ITEM_PRIZE_TICKET:
if (param_1) {
bool8 flag;
CalcDamageFixedNoCategory(attacker, defender, ov10_022C4558, 1, &flag, 0,
DAMAGE_SOURCE_THROWN_ITEM, 0, 0, 0);
} else {
SubstitutePlaceholderStringTags(0, defender, 0);
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_C67);
}
break;
case ITEM_SILVER_TICKET:
if (param_1) {
bool8 flag;
CalcDamageFixedNoCategory(attacker, defender, ov10_022C4558, 1, &flag, 0,
DAMAGE_SOURCE_THROWN_ITEM, 0, 0, 0);
} else {
SubstitutePlaceholderStringTags(0, defender, 0);
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_C67);
}
break;
case ITEM_GOLD_TICKET:
if (param_1) {
bool8 flag;
CalcDamageFixedNoCategory(attacker, defender, ov10_022C4558, 1, &flag, 0,
DAMAGE_SOURCE_THROWN_ITEM, 0, 0, 0);
} else {
SubstitutePlaceholderStringTags(0, defender, 0);
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_C67);
}
break;
case ITEM_PRISM_TICKET:
if (param_1) {
bool8 flag;
CalcDamageFixedNoCategory(attacker, defender, ov10_022C4558, 1, &flag, 0,
DAMAGE_SOURCE_THROWN_ITEM, 0, 0, 0);
} else {
SubstitutePlaceholderStringTags(0, defender, 0);
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_C67);
}
break;
case ITEM_SKY_GIFT:
if (param_1) {
bool8 flag;
CalcDamageFixedNoCategory(attacker, defender, ov10_022C4558, 1, &flag, 0,
DAMAGE_SOURCE_THROWN_ITEM, 0, 0, 0);
} else {
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_C76);
}
break;
case ITEM_GRACIDEA:
ApplyGracideaEffect(attacker, defender);
break;
case ITEM_UNNAMED_0x16B:
break;
case ITEM_A_STONE:
case ITEM_B_STONE:
case ITEM_C_STONE:
case ITEM_D_STONE:
case ITEM_E_STONE:
case ITEM_F_STONE:
case ITEM_G_STONE:
case ITEM_H_STONE:
case ITEM_I_STONE:
case ITEM_J_STONE:
case ITEM_K_STONE:
case ITEM_L_STONE:
case ITEM_M_STONE:
case ITEM_N_STONE:
case ITEM_O_STONE:
case ITEM_P_STONE:
case ITEM_Q_STONE:
case ITEM_R_STONE:
case ITEM_S_STONE:
case ITEM_T_STONE:
case ITEM_U_STONE:
case ITEM_V_STONE:
case ITEM_W_STONE:
case ITEM_X_STONE:
case ITEM_Y_STONE:
case ITEM_Z_STONE:
case ITEM_EXCLAMATION_STONE:
case ITEM_QUESTION_STONE:
if (param_1) {
bool8 flag;
CalcDamageFixedNoCategory(attacker, defender, ov10_022C44EC, 1, &flag, 0,
DAMAGE_SOURCE_THROWN_ITEM, 0, 0, 0);
} else {
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_BE8);
}
break;
case ITEM_NOTHING:
default:
if (param_1) {
bool8 flag;
CalcDamageFixedNoCategory(attacker, defender, ov10_022C4558, 1, &flag, 0, DAMAGE_SOURCE_THROWN_ITEM, 0, 0, 0);
}
else {
LogMessageByIdWithPopupCheckUserTarget(attacker, defender, MESSAGE_BE8);
}
break;
}
}
if (EntityIsValid__0231CBC8(defender)) {
struct monster *info = GetEntInfo(defender);
s16 id = item->id;
bool8 active;
if (!info->is_not_team_member)
active = ExclusiveItemEffectFlagTest(info->exclusive_item_effect_flags, EXCLUSIVE_EFF_RECOVER_HP_FROM_APPLES_AND_BERRIES);
else
active = FALSE;
if (active) {
const s16 *p;
for (p = APPLES_AND_BERRIES_ITEM_IDS; *p != 0; p++) {
if (id == *p) {
WaitUntilAlertBoxPauseIsOver(10);
TryIncreaseHp(attacker, defender, ov10_022C4864, 0, TRUE);
break;
}
}
}
}
#ifdef EUROPE
ov29_022FB920(TRUE);
#endif
EnemyEvolution(attacker);
}
bool8 EntityIsValid__0231CBC8(struct entity *entity)
{