summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Add-different-kinds-of-new-items.md131
-rw-r--r--Tutorials.md2
-rw-r--r--screenshots/eviolite.pngbin0 -> 3125 bytes
3 files changed, 128 insertions, 5 deletions
diff --git a/Add-different-kinds-of-new-items.md b/Add-different-kinds-of-new-items.md
index 6d52229..db7f5c9 100644
--- a/Add-different-kinds-of-new-items.md
+++ b/Add-different-kinds-of-new-items.md
@@ -12,7 +12,7 @@ This tutorial is for how to add different kinds of new items, including a healin
- [`PokeBallEffect`: Dusk Ball](#pokeballeffect-dusk-ball)
- [`EvoStoneEffect`: Mist Stone](#evostoneeffect-mist-stone)
- [`TownMapEffect`: Town Map](#townmapeffect-town-map)
- - [Held effect: TODO](#held-effect-todo)
+ - [Held effect: Eviolite](#held-effect-eviolite)
## 1. How item constants work
@@ -321,7 +321,7 @@ Then it's time to implement the specific Pokémon-catching effect. Edit [engine/
+
+.night_or_cave
+; b is the catch rate
-+; a == b / 2 + b + b + b == b × 3.5
++; a := b / 2 + b + b + b == b × 3.5
+ ld a, b
+ srl a
+rept 3
@@ -409,6 +409,129 @@ This code is based on how items with `ITEMMENU_PARTY` work, as written in `UseIt
![Screenshot](screenshots/town-map.png)
-### Held effect: TODO
+### Held effect: Eviolite
-TODO
+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_78` with `EVIOLITE`; give it a name, description, and attributes (`200, HELD_EVIOLITE, 0, CANT_SELECT, ITEM, ITEMMENU_NOUSE, ITEMMENU_NOUSE`); give it the `NoEffect` (it has a *held* effect, but no *used* effect); and remove `ITEM_78` from `TimeCapsule_CatchRateItems`.
+
+Note that `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_def 40
+ const HELD_40
+ const HELD_41
+ 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, like `HELD_40` and `HELD_41`, 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: ; 352b1
+ ...
+
+ ; 352dc
+
++UnevolvedEviolite:
++; get the defender's species
++ ld a, MON_SPECIES
++ call BattlePartyAttr
++ ld a, [hBattleTurn]
++ and a
++ ld a, [hl]
++ jr nz, .Unevolved
++ ld a, [wTempEnemyMonSpecies]
++
++.Unevolved:
++; 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 GetFarHalfword
++; a := the first byte of the species' EvosAttacks data
++ ld a, BANK(EvosAttacks)
++ 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, [hl]
++ cp 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
+
+ PlayerAttackDamage: ; 352e2
+ ; 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
+
+ ; 3534d
+
+ ...
+
+ EnemyAttackDamage: ; 353f6
+ ...
+
+ ld a, [wEnemyMonLevel]
+ ld e, a
+ call DittoMetalPowder
++ call UnevolvedEviolite
+
+ ld a, 1
+ and a
+ ret
+
+ ; 35461
+```
+
+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). `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.
+
+![Screenshot](screenshots/eviolite.png)
diff --git a/Tutorials.md b/Tutorials.md
index db24ed9..4d06e28 100644
--- a/Tutorials.md
+++ b/Tutorials.md
@@ -10,7 +10,7 @@ Tutorials may use diff syntax to show edits:
**How to add a new…**
- [Type (Fairy)](Add-a-new-Fairy-type)
-- [Item (including a healing item, Poké Ball, evolution stone, Town Map, etc)](Add-different-kinds-of-new-items)
+- [Item (including a healing item, held item, Poké Ball, evolution stone, Town Map, etc)](Add-different-kinds-of-new-items)
- [Music song](Add-a-new-music-song)
**Upgrades to existing features:**
diff --git a/screenshots/eviolite.png b/screenshots/eviolite.png
new file mode 100644
index 0000000..f92529f
--- /dev/null
+++ b/screenshots/eviolite.png
Binary files differ