1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
|
This tutorial is for how to add different kinds of new items, including a healing item, Poké Ball, evolution stone, key item, and held item.
## Contents
1. [How item constants work](#1-how-item-constants-work)
2. [Essential item data: name, description, attributes, and effect](#2-essential-item-data-name-description-attributes-and-effect)
3. [Examples](#3-examples)
- [No effect: Big Nugget](#no-effect-big-nugget)
- [`RestoreHPEffect`: Sweet Heart](#restorehpeffect-sweet-heart)
- [`StatusHealingEffect`: Lava Cookie](#statushealingeffect-lava-cookie)
- [`PokeBallEffect`: Dusk Ball](#pokeballeffect-dusk-ball)
- [`EvoStoneEffect`: Mist Stone](#evostoneeffect-mist-stone)
- [`XItemEffect`: X Sp.Def](#xitemeffect-x-spdef)
- [`TownMapEffect`: Town Map](#townmapeffect-town-map)
- [Held effect: Eviolite](#held-effect-eviolite)
4. [Adding up to 254 items](#4-adding-up-to-254-items)
## 1. How item constants work
Item constants are defined in [constants/item_constants.asm](../blob/master/constants/item_constants.asm). But unlike some constants, they're not a simple sequence where you can append new items to the end.
- `NO_ITEM` is the first item ID, which is used to indicate a lack of item. Leave this alone.
- Item constants start out as an ordinary sequence, from `MASTER_BALL` to `ITEM_BE`, including 23 unused <code>ITEM_<i>XX</i></code> constants. Those are simplest to replace with any kind of item you want, except for TMs or HMs.
- After the ordinary items come the TMs, from `TM_DYNAMICPUNCH` to `TM_NIGHTMARE`. These are defined with an `add_tm` macro that simultaneously defines the next <code>TM_<i>MOVENAME</i></code> item constant *and* the next <code><i>MOVENAME</i>_TMNUM</code> constant (starting at 1 for the first `add_tm` use). The first time `add_tm` is used it defines `TM01` as the current item, and any items after that are assumed to also be TMs. Note that `ITEM_C3` and `ITEM_DC` are two unusable item IDs in-between the TMs—they can't become normal items, since they're greater than `TM01`, and some TM-related code manually skips over those two slots—so if you want to use them you'll have to [correct that design flaw](../blob/master/docs/design_flaws.md#item_c3-and-item_dc-break-up-the-continuous-sequence-of-tm-items).
- After the TMs come the HMs, from `HM_CUT` to `HM_WATERFALL`. These are defined with an `add_hm` macro that simultaneously defines the next <code>HM_<i>MOVENAME</i></code> item constant *and* the next <code><i>MOVENAME</i>_TMNUM</code> constant (continuing from the TMs, so for instance, `CUT_TMNUM` is 51). The first time `add_hm` is used it defines `HM01` as the current item, and any items after that are assumed to also be HMs, with all the differences that implies (they'll have an "H" in the Pack, using them will print "Booted up an HM", they can't be tossed, etc).
- There can't be useful items after the HMs, since by definition anything after `HM01` is treated as an HM itself. In fact, `ITEM_FA` is defined after the HMs, so you might need to move or delete it.
- `ITEM_FROM_MEM` is the last item ID, which is used in some scripts to give whatever item is in `wScriptVar` instead of a hard-coded item. (For instance, fruit trees rely on it so they don't need a separate script for each kind of Berry and Apricorn.)
(Note that after the `add_tm`s and `add_hm`s, there are also some `add_mt`s. This macro defines more <code><i>MOVENAME</i>\_TMNUM</code> constants, but not more <code>TM\_<i>MOVENAME</i></code> or <code>HM\_<i>MOVENAME</i></code> item constants, so the moves are recognized as teachable but don't have an associated item.)
It's important to understand that there's nothing special about the specific numeric values, except $00 for `NO_ITEM` and $FF for `ITEM_FROM_MEM`. `const_def` starts a new constant sequence at 0, and every `const`, `add_tm`, or `add_hm` after that defines the next constant in the sequence.
## 2. Essential item data: name, description, attributes, and effect
You may have already guessed this from the comment at the top of [constants/item_constants.asm](../blob/master/constants/item_constants.asm):
```asm
; item ids
; indexes for:
; - ItemNames (see data/items/names.asm)
; - ItemDescriptions (see data/items/descriptions.asm)
; - ItemAttributes (see data/items/attributes.asm)
; - ItemEffects (see engine/items/item_effects.asm)
```
Every kind of item has these pieces of data. `ItemNames`, `ItemDescriptions`, `ItemAttributes`, and `ItemEffects` are four tables with an entry for each item constant, one after another. It's important for them all to be in sync, so that the Nth constant correctly matches the Nth name, the Nth description, and so on.
**Names** are defined in [data/items/names.asm](../blob/master/data/items/names.asm). They're simply written as <code>li "<em>NAME</em>"</code>: an opening quote, the name and a closing quote. Names can be up to 12 characters long. The number of *printed* characters also matters, since screens like the Pack and the Mart menus are a fixed width. For example, when the name `"# DOLL"` gets printed as "POKé DOLL", that's 9 characters, not 6.
**Descriptions** are defined in [data/items/descriptions.asm](../blob/master/data/items/descriptions.asm). Unlike with names, each entry in the table of descriptions is a pointer to the actual description data. Descriptions have two lines, each with up to 18 characters. Again, what matters is the printed length, since they have to fit in a text box of that size.
**Attributes** are defined in [data/items/attributes.asm](../blob/master/data/items/attributes.asm). They use an `item_attribute` macro that defines many pieces of data at once:
- **price:** The price in Marts. Prices range from ¥0 to ¥65535 ($FFFF, the maximum value of a two-byte quantity). Items can be resold for half the price.
- **held effect:** The effect when held by a Pokémon. Usually `HELD_NONE`, except for items like Leftovers. The `HELD_*` constants are defined in [constants/item_data_constants.asm](../blob/master/constants/item_data_constants.asm). We'll see how to create a new held effect later, for [Eviolite](#held-effect-eviolite).
- **parameter:** A piece of extra data associated with the item. Usually 0, but some item effects use this parameter. For instance, BrightPowder's parameter of 20 is interpreted by `BattleCommand_CheckHit` as an extra 20/256 (~7.8%) chance to miss a move.
- **property:** Controls whether you can select and/or toss the item. `NO_LIMITS`, `CANT_SELECT`, `CANT_TOSS`, or `CANT_SELECT | CANT_TOSS`. Most items have `CANT_SELECT`, except for the usefully selectable ones like Bicycle or ItemFinder. `CANT_TOSS` is for key items and HMs.
- **pocket:** Which pocket it goes in. `ITEM`, `KEY_ITEM`, `BALL`, or `TM_HM`.
- **field menu:** What the item does when you try to use it in the field (i.e. outside of battle).
- `ITEMMENU_NOUSE` can't be used at all ("OAK: <i>PLAYER</i>! This isn't the time to use that!")
- `ITEMMENU_CURRENT` just uses it right away (like Repel or Coin Case)
- `ITEMMENU_PARTY` lets you choose a party Pokémon to use it on (like Potion or HP Up)
- `ITEMMENU_CLOSE` has a confirmation menu before using it (like Bicycle or Escape Rope)
- **battle menu:** What the item does when you try to use it during battle. Another `ITEMMENU_*` constant.
**Effects** are defined in [engine/items/item_effects.asm](../blob/master/engine/items/item_effects.asm). Like descriptions, there's a table of pointers to the effects themselves, and the pointers are what correspond directly with item constants. Effects are implemented in assembly code, and are virtually unlimited in what they can do. But many of them are flexible. Effects like `StatusHealingEffect`, `PokeBallEffect`, or `EvoStoneEffect` get reused for many different items, and the items' particular details come from their attributes or from extra data tables related to that kind of item. Next we'll see how to add new items that use some of these general-purpose effects.
## 3. Examples
### No effect: Big Nugget
To start with, we'll implement a new item that just has the essential data. A Big Nugget doesn't do anything, it just has a high price. So here's how to add one:
Edit [constants/item_constants.asm](../blob/master/constants/item_constants.asm):
```diff
const WATER_STONE ; 18
- const ITEM_19 ; 19
+ const BIG_NUGGET ; 19
const HP_UP ; 1a
```
Edit [data/items/names.asm](../blob/master/data/items/names.asm):
```diff
li "WATER STONE"
- li "TERU-SAMA"
+ li "BIG NUGGET"
li "HP UP"
```
Edit [data/items/descriptions.asm](../blob/master/data/items/descriptions.asm):
```diff
dw WaterStoneDesc
- dw TeruSama2Desc
+ dw BigNuggetDesc
dw HPUpDesc
...
-TeruSama2Desc:
- db "?@"
+BigNuggetDesc:
+ db "Made of pure gold."
+ next "Sell very high.@"
```
Edit [data/items/attributes.asm](../blob/master/data/items/attributes.asm):
```diff
-; ITEM_19
- item_attribute $9999, HELD_NONE, 0, NO_LIMITS, ITEM, ITEMMENU_NOUSE, ITEMMENU_NOUSE
+; BIG_NUGGET
+ item_attribute 20000, HELD_NONE, 0, CANT_SELECT, ITEM, ITEMMENU_NOUSE, ITEMMENU_NOUSE
```
Edit [engine/items/item_effects.asm](../blob/master/engine/items/item_effects.asm):
```diff
dw EvoStoneEffect ; WATER_STONE
- dw NoEffect ; ITEM_19
+ dw NoEffect ; BIG_NUGGET
dw VitaminEffect ; HP_UP
```
And last, edit [data/items/catch_rate_items.asm](../blob/master/data/items/catch_rate_items.asm):
```diff
TimeCapsule_CatchRateItems:
- db ITEM_19, LEFTOVERS
...
```
This is an easy-to-miss edit that's needed because of the Time Capsule. When a Pokémon is traded via Time Capsule from RBY to GSC, the byte in its data structure that represents its catch rate is interpreted as its held item. (A catch rate byte no longer exists in GSC, since that's part of base data.) For example, Jigglypuff's catch rate is 170, or $AA, so it holds a Polkadot Bow when traded to GSC because `POLKADOT_BOW` is $AA.
The `TimeCapsule_CatchRateItems` is used to convert catch rate values that don't correspond to valid items. So a Pokémon with a catch rate of $19, when traded from RBY to GSC, would hold Leftovers instead of `ITEM_19`. (And even without any trading, if a Pokémon's held item is `ITEM_19`, it will appear as "LEFTOVERS" in the status screen!) But since we're replacing `ITEM_19` with a valid item, we don't want this to happen any more.
Anyway, that's all you need to add a basic item:

### `RestoreHPEffect`: Sweet Heart
A Sweet Heart, from Gen 5, restores 20 HP, just like RageCandyBar. It can be used on the field or during battle, and enemy trainer AI should know how to use one too.
First, add the essential data. Replace `ITEM_2D` with `SWEET_HEART`; give it a name, description, and attributes (`100, HELD_NONE, 0, CANT_SELECT, ITEM, ITEMMENU_PARTY, ITEMMENU_PARTY`); give it the `RestoreHPEffect`; and remove `ITEM_2D` from `TimeCapsule_CatchRateItems`.
Then it's time to implement the specific HP healing amount for Sweet Heart. Notice how most healing items—Potion, Fresh Water, etc—have an `item_attribute` parameter value equal to how much they heal? Those aren't actually used anywhere. Instead, the healing amounts for items used by the player, by the enemy trainer, and (when possible) by the Pokémon holding it are all handled separately.
Edit [data/items/heal_hp.asm](../blob/master/data/items/heal_hp.asm):
```diff
HealingHPAmounts:
dbw FRESH_WATER, 50
...
dbw BERRY_JUICE, 20
+ dbw SWEET_HEART, 20
dbw -1, 0 ; end
```
`HealingHPAmounts` is used by `GetHealingItemAmount`, which is called by `ItemRestoreHP`, which is called by `RestoreHPEffect`, which is the effect we already assigned to Sweet Heart; so now it will successfully heal 20 HP when used by the player.
Now edit [engine/battle/ai/items.asm](../blob/master/engine/battle/ai/items.asm):
```diff
AI_Items:
dbw FULL_RESTORE, .FullRestore
...
dbw X_SPECIAL, .XSpecial
+ dbw SWEET_HEART, .SweetHeart
db -1 ; end
...
.Potion:
call .HealItem
jp c, .DontUse
ld b, 20
call EnemyUsedPotion
jp .Use
+
+.SweetHeart:
+ call .HealItem
+ jp c, .DontUse
+ ld b, 20
+ call EnemyUsedSweetHeart
+ jp .Use
...
EnemyUsedPotion:
ld a, POTION
ld b, 20
jr EnemyPotionContinue
+
+EnemyUsedSweetHeart:
+ ld a, SWEET_HEART
+ ld b, 20
+ jr EnemyPotionContinue
```
Now if a trainer has a Sweet Heart (as defined in [data/trainers/attributes.asm](../blob/master/data/trainers/attributes.asm)) they'll be able to use it. The `.HealItem` subroutine called by `.SweetHeart` determines whether the healing item will be used, with different random chances when the enemy has half or a quarter of their HP left; and the `EnemyPotionContinue` routine does the whole process of restoring HP, animating the HP bar, playing the sound effect, etc.

### `StatusHealingEffect`: Lava Cookie
A Lava Cookie, from Gen 3, heals any status condition, just like Full Heal. It can be used on the field or during battle, and enemy trainer AI should know how to use one too.
First, add the essential data. Replace `ITEM_32` with `LAVA_COOKIE`; give it a name, description, and attributes (`200, HELD_NONE, 0, CANT_SELECT, ITEM, ITEMMENU_PARTY, ITEMMENU_PARTY`); give it the `StatusHealingEffect`; and remove `ITEM_32` from `TimeCapsule_CatchRateItems`.
Then it's time to implement the specific status-healing effect. Edit [data/items/heal_status.asm](../blob/master/data/items/heal_status.asm):
```diff
StatusHealingActions:
; item, party menu action text, status
db ANTIDOTE, PARTYMENUTEXT_HEAL_PSN, 1 << PSN
...
db MIRACLEBERRY, PARTYMENUTEXT_HEAL_ALL, %11111111
+ db LAVA_COOKIE, PARTYMENUTEXT_HEAL_ALL, %11111111
db -1, 0, 0 ; end
```
`%11111111` is a bit mask for all status conditions, but that particular value is checked for by `HealStatus` to allow healing confusion as well. A different value, like `1 << PSN` or `(1 << BRN) | (1 << FRZ)`, could be used to heal only certain conditions.
`StatusHealingActions` is used by `GetItemHealingAction`, which is called by `UseStatusHealer`, which is called by `StatusHealingEffect`, which is the effect we already assigned to Lava Cookie; so now it will successfully heal all status conditions when used by the player.
Now edit [engine/battle/ai/items.asm](../blob/master/engine/battle/ai/items.asm):
```diff
AI_Items:
dbw FULL_RESTORE, .FullRestore
...
dbw X_SPECIAL, .XSpecial
+ dbw LAVA_COOKIE, .LavaCookie
db -1 ; end
.FullHeal:
call .Status
jp c, .DontUse
call EnemyUsedFullHeal
jp .Use
+
+.LavaCookie:
+ call .Status
+ jp c, .DontUse
+ call EnemyUsedLavaCookie
+ jp .Use
...
EnemyUsedFullHeal:
call AIUsedItemSound
call AI_HealStatus
ld a, FULL_HEAL
jp PrintText_UsedItemOn_AND_AIUpdateHUD
+
+EnemyUsedLavaCookie:
+ call AIUsedItemSound
+ call AI_HealStatus
+ ld a, LAVA_COOKIE
+ jp PrintText_UsedItemOn_AND_AIUpdateHUD
```
Now if a trainer has a Lava Cookie (as defined in [data/trainers/attributes.asm](../blob/master/data/trainers/attributes.asm)) they'll be able to use it. The `.Status` subroutine called by `.LavaCookie` determines whether the healing item will be used, with different random chances depending on the enemy AI and the battle situation; and the `EnemyUsedLavaCookie` routine does the whole process of healing status, playing the sound effect, etc.

### `PokeBallEffect`: Dusk Ball
A Dusk Ball, from Gen 4, has a 3.5× catch rate if used in caves or at night.
First, add the essential data. Replace `ITEM_5A` with `DUSK_BALL`; give it a name, description, and attributes (`1000, HELD_NONE, 0, CANT_SELECT, BALL, ITEMMENU_NOUSE, ITEMMENU_CLOSE`); give it the `PokeBallEffect`; and remove `ITEM_5A` from `TimeCapsule_CatchRateItems`.
A piece of data specific to Poké Balls is what color they are when thrown in battle. Edit [data/battle_anims/ball_colors.asm](../blob/master/data/battle_anims/ball_colors.asm):
```diff
BallColors:
db MASTER_BALL, PAL_BATTLE_OB_GREEN
...
db LOVE_BALL, PAL_BATTLE_OB_RED
+ db DUSK_BALL, PAL_BATTLE_OB_GREEN
db -1, PAL_BATTLE_OB_GRAY
```
Then it's time to implement the specific Pokémon-catching effect. Edit [engine/items/item_effects.asm](../blob/master/engine/items/item_effects.asm) again:
```diff
BallMultiplierFunctionTable:
; table of routines that increase or decrease the catch rate based on
; which ball is used in a certain situation.
dbw ULTRA_BALL, UltraBallMultiplier
...
dbw PARK_BALL, ParkBallMultiplier
+ dbw DUSK_BALL, DuskBallMultiplier
db -1 ; end
+DuskBallMultiplier:
+; is it night?
+ ld a, [wTimeOfDay]
+ cp NITE
+ jr z, .night_or_cave
+; or are we in a cave?
+ ld a, [wEnvironment]
+ cp CAVE
+ ret nz ; neither night nor cave
+
+.night_or_cave
+; b is the catch rate
+; a := b + b + b == b × 3
+ ld a, b
+ add a
+ jr c, .max
+
+ add b
+ jr c, .max
+
+ ld b, a
+ ret
+
+.max
+ ld b, $ff
+ ret
```
`DuskBallMultiplier`, like all the Ball multiplier routines, just has to modify `b` according to the relevant factors. If it's nighttime or we're in a cave, it multiplies `b` by 3; otherwise it doesn't modify `b`.

### `EvoStoneEffect`: Mist Stone
A Mist Stone is a rumored item from Gen 1 that evolves Pokémon into "PokéGods". A more realistic function would be to evolve Pokémon like Machoke or Haunter that otherwise require trading, which can be inconvenient.
First, add the essential data. Replace `ITEM_64` with `MIST_STONE`; give it a name, description, and attributes (`2100, HELD_NONE, 0, CANT_SELECT, ITEM, ITEMMENU_PARTY, ITEMMENU_NOUSE`); give it the `EvoStoneEffect`; and remove `ITEM_64` from `TimeCapsule_CatchRateItems`.
That's actually all you need to do for the item itself. Now as long as it's declared to evolve a Pokémon, it will do so correctly.
Edit [data/pokemon/evos_attacks.asm](../blob/master/data/pokemon/evos_attacks.asm):
```diff
KadabraEvosAttacks:
+ db EVOLVE_ITEM, MIST_STONE, ALAKAZAM
db EVOLVE_TRADE, -1, ALAKAZAM
db 0 ; no more evolutions
...
MachokeEvosAttacks:
+ db EVOLVE_ITEM, MIST_STONE, MACHAMP
db EVOLVE_TRADE, -1, MACHAMP
db 0 ; no more evolutions
...
GravelerEvosAttacks:
+ db EVOLVE_ITEM, MIST_STONE, GOLEM
db EVOLVE_TRADE, -1, GOLEM
db 0 ; no more evolutions
...
HaunterEvosAttacks:
+ db EVOLVE_ITEM, MIST_STONE, GENGAR
db EVOLVE_TRADE, -1, GENGAR
db 0 ; no more evolutions
...
```
(Note that if a Pokémon has too many evolution methods, they'll say "NOT ABLE" to evolve with an item even if they are. This is a known bug with `PlacePartyMonEvoStoneCompatibility` and has [a simple solution](../blob/master/docs/bugs_and_glitches.md#only-the-first-three-evolution-entries-can-have-stone-compatibility-reported-correctly).)

### `XItemEffect`: X Sp.Def
X Sp.Def, from Gen 4, boosts Special Defense by one stage in battle. It can only be used during battle, and enemy trainer AI should know how to use one too.
(In Gen 1, X Special boosted the single Special stat. Gen 2 split Special into Attack and Defense, but X Special only boosted Special Attack, and it took until Gen 4 to split the item as well into X Sp.Atk and X Sp.Def.)
First, add the essential data. Replace `ITEM_78` with `X_SP_DEF`; give it a name, description, and attributes (`350, HELD_NONE, 0, CANT_SELECT, ITEM, ITEMMENU_NOUSE, ITEMMENU_CLOSE`); give it the `XItemEffect`; and remove `ITEM_78` from `TimeCapsule_CatchRateItems`.
A piece of data specific to X items is which stat they boost. Edit [data/items/x_stats.asm](../blob/master/data/items/x_stats.asm):
```diff
XItemStats:
; item, stat
db X_ATTACK, ATTACK
db X_DEFEND, DEFENSE
db X_SPEED, SPEED
db X_SPECIAL, SP_ATTACK
+ db X_SP_DEF, SP_DEFENSE
```
`XItemStats` is used by `XItemEffect`, so now it will successfully boost Special Defense when used by the player.
Now edit [engine/battle/ai/items.asm](../blob/master/engine/battle/ai/items.asm):
```diff
AI_Items:
dbw FULL_RESTORE, .FullRestore
...
dbw X_SPECIAL, .XSpecial
+ dbw X_SP_DEF, .XSpDef
db -1 ; end
...
.XSpecial:
call .XItem
jp c, .DontUse
call EnemyUsedXSpecial
jp .Use
+
+.XSpDef:
+ call .XItem
+ jp c, .DontUse
+ call EnemyUsedXSpDef
+ jp .Use
...
+EnemyUsedXSpDef:
+ ld b, SP_DEFENSE
+ ld a, X_SP_DEF
+ jr EnemyUsedXItem
EnemyUsedXSpecial:
ld b, SP_ATTACK
ld a, X_SPECIAL
; Parameter
; a = ITEM_CONSTANT
; b = BATTLE_CONSTANT (ATTACK, DEFENSE, SPEED, SP_ATTACK, SP_DEFENSE, ACCURACY, EVASION)
EnemyUsedXItem:
...
```
Now if a trainer has an X Sp.Def (as defined in [data/trainers/attributes.asm](../blob/master/data/trainers/attributes.asm)) they'll be able to use it. The `.XItem` subroutine called by `.XSpDef` determines whether the healing item will be used, with different random chances depending on the enemy AI and the battle situation; and the `EnemyUsedXSpDef` routine does the whole process of boosting the stat, playing the sound effect, etc.

Note that I named it "X SPCL.DEF", not "X SP.DEF", because that's the naming convention for stats in Gen 2. I also renamed "X SPECIAL" to "X SPCL.ATK" so they match.
### `TownMapEffect`: Town Map
The Town Map was present in Gen 1 but replaced in Gen 2 by the Pokégear's Map Card; however, it still exists in the code. Its `TownMapEffect` implementation is buggy, but can be fixed.
First, add the essential data. The `TOWN_MAP` item constant already exists, but it needs a proper name, description, and attributes (`0, HELD_NONE, 0, CANT_SELECT | CANT_TOSS, KEY_ITEM, ITEMMENU_CURRENT, ITEMMENU_NOUSE`).
Now fix the effect. Edit [engine/items/item_effects.asm](../blob/master/engine/items/item_effects.asm):
```diff
TownMapEffect:
- farcall PokegearMap
+ call FadeToMenu
+ farcall _TownMap
+ call Call_ExitMenu
+ xor a
+ ldh [hBGMapMode], a
+ farcall Pack_InitGFX
+ farcall WaitBGMap_DrawPackGFX
+ farcall Pack_InitColors
ret
```
This code is based on how items with `ITEMMENU_PARTY` work, as written in `UseItem.Party` in [engine/items/pack.asm](../blob/master/engine/items/pack.asm).

### Held effect: Eviolite
Eviolite, from Gen 5, boosts Defense and Special Defense by 50% if held by a Pokémon that is not fully evolved.
First, add the essential data. Replace `ITEM_87` with `EVIOLITE`; give it a name, description, and attributes (`200, HELD_EVIOLITE, 0, CANT_SELECT, ITEM, ITEMMENU_NOUSE, ITEMMENU_NOUSE`); give it `NoEffect` (it has a *held* effect, but no *used* effect); and remove `ITEM_87` from `TimeCapsule_CatchRateItems`.
`HELD_EVIOLITE` has not been defined yet, so we'll do that next. Edit [constants/item_data_constants.asm](../blob/master/constants/item_data_constants.asm):
```diff
const_next 40
const_skip
const_skip
const HELD_METAL_POWDER
+ const HELD_EVIOLITE
```
Two things to note about these `HELD_*` constants. One, they're not a continuous sequence; Game Freak usually grouped related ones together, starting from round numbers like 40. This was probably just to make it easier to deal with the raw numeric values, using the less powerful development tools of the late 90s. Two, there's no data associated with these constants. They're just unique values that the battle engine can check for in any arbitrary circumstances. If one of them is unused you can always replace it with something useful.
In other words, adding an effect for `HELD_EVIOLITE` won't involve updating any data tables; we'll just have to write some all-new assembly code. So if you want to design an original held item, you'll have to become familiar with how the battle engine works, and figure out which parts need updating to accomodate your item.
Eviolite's effect is pretty similar to Metal Powder, which boosts Ditto's defenses. Searching through the battle engine code for references to `METAL_POWDER` finds that it's implemented as a `DittoMetalPowder` routine, which gets called in two places, one for the player and one for the enemy. (Note that it checks directly for whether the held item is `METAL_POWDER`, not whether the held item's effect is `HELD_METAL_POWDER`. Either check would be okay, though.)
Anyway, edit [engine/battle/effect_commands.asm](../blob/master/engine/battle/effect_commands.asm):
```diff
DittoMetalPowder:
...
+UnevolvedEviolite:
+; get the defender's species
+ ld a, MON_SPECIES
+ call BattlePartyAttr
+ ldh a, [hBattleTurn]
+ and a
+ ld a, [hl]
+ jr nz, .got_species
+ ld a, [wTempEnemyMonSpecies]
+
+.got_species
+; check if the defender has any evolutions
+; hl := EvosAttacksPointers + (species - 1) * 2
+ dec a
+ push hl
+ push bc
+ ld c, a
+ ld b, 0
+ ld hl, EvosAttacksPointers
+ add hl, bc
+ add hl, bc
+; hl := the species' entry from EvosAttacksPointers
+ ld a, BANK(EvosAttacksPointers)
+ call GetFarWord
+; a := the first byte of the species' *EvosAttacks data
+ ld a, BANK("Evolutions and Attacks")
+ call GetFarByte
+; if a == 0, there are no evolutions, so don't boost stats
+ and a
+ pop bc
+ pop hl
+ ret z
+
+; check if the defender's item is Eviolite
+ push bc
+ call GetOpponentItem
+ ld a, b
+ cp HELD_EVIOLITE
+ pop bc
+ ret nz
+
+; boost the relevant defense stat in bc by 50%
+ ld a, c
+ srl a
+ add c
+ ld c, a
+ ret nc
+
+ srl b
+ ld a, b
+ and a
+ jr nz, .done
+ inc b
+.done
+ scf
+ rr c
+ ret
BattleCommand_DamageStats:
...
PlayerAttackDamage:
; Return move power d, player level e, enemy defense c and player attack b.
...
ld a, [wBattleMonLevel]
ld e, a
call DittoMetalPowder
+ call UnevolvedEviolite
ld a, 1
and a
ret
...
EnemyAttackDamage:
...
ld a, [wEnemyMonLevel]
ld e, a
call DittoMetalPowder
+ call UnevolvedEviolite
ld a, 1
and a
ret
```
The implementation of `UnevolvedEviolite` is very similar to `DittoMetalPowder`, except the simple check for whether the species is `DITTO` has been replaced by a check for evolutions, similar to the check in `MoonBallMultiplier` in [engine/items/item_effects.asm](../blob/master/engine/items/item_effects.asm). (Also, instead of checking whether `[hl]` is `EVIOLITE`, we check whether `b` is `HELD_EVIOLITE`; either would be fine, since `GetOpponentItem` returns "the effect of the opponent's item in `bc`, and its id at `hl`", as explained in a comment.) `bc` gets repeatedly saved on the stack with `push` and `pop` because it contains the defense stat, and we don't want the various pre-boost checks to corrupt the original value.
In general, if you're implementing a custom held item effect, think about which items have similar effects, and which other code might already do something like what you want.

## 4. Adding up to 254 items
Like most IDs in pokecrystal, item IDs are one byte each, so they can go from 0 to 255. Item $00 is `NO_ITEM` and $FF (−1) is an end-of-list marker, which leaves 254 usable IDs.
We've been replacing unused items with useful ones, but in principle you can also add new items (as long as you're careful to arrange regular items before TMs, then HMs last). Only 251 item constants are defined, from `NO_ITEM` to `ITEM_FA`, but the tables of `ItemNames`, `ItemDescriptions`, and `ItemAttributes` already have 256 entries each (and `ItemEffects` has entries for every regular item; the TMs and HMs don't use effects). So just be careful to keep the constants and all those tables in sync. Remember that adding a new constant in the middle of a sequence will shift all the ones after it.
If `make` gives you the error "Expression must be 8-bit", you're probably using an ID constant greater than 255, which won't fit in one byte (eight bits). Double-check the constants and make sure they're all between $00 and $FF. It's easy to forget about the useless `ITEM_FA` at the very end, which can end up shifted beyond the 8-bit range if you add too many new items. Feel free to delete it, and remove its entry from `TimeCapsule_CatchRateItems` (the only place `ITEM_FA` is ever used).
|