summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRangi <remy.oukaour+rangi42@gmail.com>2020-03-15 01:46:55 -0400
committerRangi <remy.oukaour+rangi42@gmail.com>2020-03-15 01:46:55 -0400
commitac6bc67e43ce7f3be49cb2bfb101a56906bfbd1b (patch)
tree44be8f6c685dd5b721480af0e864e6f7f5e907a2
parentcc92a108567feabaf84d3450f68d08b817cd8a1f (diff)
Use unique colors for each thrown Poké Ball
-rw-r--r--Tutorials.md1
-rw-r--r--Use-unique-colors-for-each-thrown-Poké-Ball.md188
-rw-r--r--screenshots/unique-ball-colors-list.pngbin0 -> 1029 bytes
-rw-r--r--screenshots/unique-ball-colors.pngbin0 -> 3569 bytes
4 files changed, 189 insertions, 0 deletions
diff --git a/Tutorials.md b/Tutorials.md
index dbe4e50..8fb29e7 100644
--- a/Tutorials.md
+++ b/Tutorials.md
@@ -114,6 +114,7 @@ Tutorials may use diff syntax to show edits:
- [Puddles that splash when you walk](Puddles-that-splash-when-you-walk)
- [Use G/S SGB palettes for maps](Use-GS-SGB-palettes-for-maps)
- [Gain experience from catching Pokémon](Gain-experience-from-catching-Pokémon)
+- [Use unique colors for each thrown Poké Ball](Use-unique-colors-for-each-thrown-Poké-Ball)
- [Smashing rocks has a chance to contain items](Smashing-rocks-has-a-chance-to-contain-items)
diff --git a/Use-unique-colors-for-each-thrown-Poké-Ball.md b/Use-unique-colors-for-each-thrown-Poké-Ball.md
new file mode 100644
index 0000000..a2453a9
--- /dev/null
+++ b/Use-unique-colors-for-each-thrown-Poké-Ball.md
@@ -0,0 +1,188 @@
+Gen 2 showed colored Poké Balls in battle, but the colors were picked from a limited set of six. Gen 3 started showing each Poké Ball with its unique graphics and colors.
+
+This tutorial will add unique colors for each type of Ball, although they'll all still use the same graphic.
+
+
+## Contents
+
+1. [Define unique colors for each Ball](#1-define-unique-colors-for-each-ball)
+2. [Make every Ball use `PAL_BATTLE_OB_RED`](#2-make-every-ball-use-pal_battle_ob_red)
+3. [Load the unique colors into the palette](#3-load-the-unique-colors-into-the-palette)
+
+
+## 1. Define unique colors for each Ball
+
+Edit [data/battle_anims/ball_colors.asm](../blob/master/data/battle_anims/ball_colors.asm):
+
+```diff
+ ; colors of balls thrown in battle
+
+ BallColors:
+- db MASTER_BALL, PAL_BATTLE_OB_GREEN
+- db ULTRA_BALL, PAL_BATTLE_OB_YELLOW
+- db GREAT_BALL, PAL_BATTLE_OB_BLUE
+- db POKE_BALL, PAL_BATTLE_OB_RED
+- db HEAVY_BALL, PAL_BATTLE_OB_GRAY
+- db LEVEL_BALL, PAL_BATTLE_OB_BROWN
+- db LURE_BALL, PAL_BATTLE_OB_BLUE
+- db FAST_BALL, PAL_BATTLE_OB_BLUE
+- db FRIEND_BALL, PAL_BATTLE_OB_YELLOW
+- db MOON_BALL, PAL_BATTLE_OB_GRAY
+- db LOVE_BALL, PAL_BATTLE_OB_RED
+- db -1, PAL_BATTLE_OB_GRAY
++ db MASTER_BALL
++ RGB 31,31,31, 20,08,23
++ db ULTRA_BALL
++ RGB 31,31,31, 10,10,12
++ db GREAT_BALL
++ RGB 31,31,31, 09,13,30
++ db POKE_BALL
++ RGB 31,31,31, 30,08,05
++ db HEAVY_BALL
++ RGB 31,31,31, 06,10,12
++ db LEVEL_BALL
++ RGB 31,31,31, 30,24,00
++ db LURE_BALL
++ RGB 31,31,31, 04,14,30
++ db FAST_BALL
++ RGB 31,31,31, 31,16,04
++ db FRIEND_BALL
++ RGB 31,31,31, 04,17,04
++ db MOON_BALL
++ RGB 31,31,31, 07,19,25
++ db LOVE_BALL
++ RGB 31,31,31, 30,11,22
++ db PARK_BALL
++ RGB 31,31,31, 18,18,05
++ db -1 ; end
++ RGB 31,31,31, 16,16,16
+```
+
+Each Ball used to use one of the palettes meant for move animations (since throwing a Ball is technically an animation): gray, yellow, red, green, blue, or brown. Here we've replaced each `PAL_BATTLE_OB_*` color index with a pair of RGB colors: the first for the bottom half of the Ball, the second for the top half.
+
+Here's how they'll look:
+
+![Screenshot](screenshots/unique-ball-colors-list.png)
+
+We just changed the `BallColors` table to assign each Ball a pair of actual RGB colors, instead of a palette index. So putting back the palette index will be the next step.
+
+
+## 2. Make every Ball use `PAL_BATTLE_OB_RED`
+
+Edit [engine/battle_anims/functions.asm](../blob/master/engine/battle_anims/functions.asm):
+
+```diff
+ GetBallAnimPal:
+- ld hl, BallColors
+- ldh a, [rSVBK]
+- push af
+- ld a, BANK(wCurItem)
+- ldh [rSVBK], a
+- ld a, [wCurItem]
+- ld e, a
+- pop af
+- ldh [rSVBK], a
+-.IsInArray:
+- ld a, [hli]
+- cp -1
+- jr z, .load
+- cp e
+- jr z, .load
+- inc hl
+- jr .IsInArray
+-
+-.load
+- ld a, [hl]
+ ld hl, BATTLEANIMSTRUCT_PALETTE
+ add hl, bc
+- ld [hl], a
++ ld [hl], PAL_BATTLE_OB_RED
+ ret
+-
+-INCLUDE "data/battle_anims/ball_colors.asm"
+```
+
+Since we know every Ball will use the same palette index, the next step is to replace that palette's colors with the correct Ball-specific ones at the right time.
+
+
+## 3. Load the unique colors into the palette
+
+Edit [engine/battle_anims/helpers.asm](../blob/master/engine/battle_anims/helpers.asm):
+
+```diff
+ LoadBattleAnimGFX:
+ push hl
++ cp ANIM_GFX_POKE_BALL
++ call z, .LoadBallPalette
+ ld l, a
+ ld h, 0
+ add hl, hl
+ add hl, hl
+ ld de, AnimObjGFX
+ add hl, de
+ ld c, [hl]
+ inc hl
+ ld b, [hl]
+ inc hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ pop de
+ push bc
+ call DecompressRequest2bpp
+ pop bc
+ ret
++
++.LoadBallPalette:
++ ; save the current WRAM bank
++ ld a, [rSVBK]
++ push af
++ ; switch to the WRAM bank of wCurItem so we can read it
++ ld a, BANK(wCurItem)
++ ld [rSVBK], a
++ ; store the current item in b
++ ld a, [wCurItem]
++ ld b, a
++ ; seek for the BallColors entry matching the current item
++ ld hl, BallColors
++.loop
++ ld a, [hli]
++ cp b ; did we find the current ball?
++ jr z, .done
++ cp -1 ; did we reach the end of the list?
++ jr z, .done
++rept PAL_COLOR_SIZE * 2
++ inc hl ; skip over the two RGB colors to the next entry
++endr
++ jr .loop
++.done
++ ; switch to the WRAM bank of wOBPals2 so we can write to it
++ ld a, BANK(wOBPals2)
++ ld [rSVBK], a
++ ; load the RGB colors into the middle two colors of PAL_BATTLE_OB_RED
++ ld de, wOBPals2 palette PAL_BATTLE_OB_RED color 1
++rept PAL_COLOR_SIZE * 2 - 1
++ ld a, [hli]
++ ld [de], a
++ inc de
++endr
++ ld a, [hl]
++ ld [de], a
++ ; apply the updated colors to the palette RAM
++ ld a, $1
++ ld [hCGBPalUpdate], a
++ ; restore the previous WRAM bank
++ pop af
++ ld [rSVBK], a
++ ; restore the graphics index to be loaded
++ ld a, ANIM_GFX_POKE_BALL
++ ret
++
++INCLUDE "data/battle_anims/ball_colors.asm"
+```
+
+`LoadBattleAnimGFX` is called with an `ANIM_GFX_*` constant in `a`; it loads the appropriate graphics for that constant in preparation for animating the move. If we inspect [data/moves/animations.asm](../blob/master/data/moves/animations.asm), we can see that `ANIM_GFX_POKE_BALL` is used for throwing Poké Balls, and only for throwing Poké Balls; so if we know it's being loaded, that's the right time to load our unique colors too.
+
+Now we can see the unique colors in action:
+
+![Screenshot](screenshots/unique-ball-colors.png)
diff --git a/screenshots/unique-ball-colors-list.png b/screenshots/unique-ball-colors-list.png
new file mode 100644
index 0000000..04b324c
--- /dev/null
+++ b/screenshots/unique-ball-colors-list.png
Binary files differ
diff --git a/screenshots/unique-ball-colors.png b/screenshots/unique-ball-colors.png
new file mode 100644
index 0000000..9079181
--- /dev/null
+++ b/screenshots/unique-ball-colors.png
Binary files differ