How to add a Pocket Move Reminder and Pocket Move Deleter - pret/pokecrystal GitHub Wiki

Starting in Pokemon: Legends Arceus, the player can freely change a Pokemon's moves from the move menu. While this tutorial does not provide the means to implement such a system in Crystal, it will show you how to implement the Move Reminder as an item in your bag. This takes a lot of inspiration from both the Pocket PC guide and the Move Reminder (Variant 2) guide.

This tutorial also will show you how make a Pocket version of the Move Deleter.

Contents

Premise

I noticed that the Move Reminder is a special command, much like the command to open the PC. The Pocket PC proved that you can have items that open menus in the overworld. Ergo, I thought to myself, "What if you could implement both so that you had a Move Reminder wherever you went?" So that's what I did!

Note that you can also use this to make a Pocket Move Deleter, though the tutorial for that is much simpler, as the code for the Move Deleter already exists inside of the game.

Implementing the Pocket Reminder

With that preamble out of the way, here is how to implement the Pocket Reminder.

Step 1: Implement the Move Reminder.

Follow the Move Reminder (Variant 2) tutorial, though you don't need to implement a new NPC if you don't want to. If you do implement an actual Move Reminder NPC, though, this tutorial shouldn't cause any issues, as proven by the regular PC still working when the Pocket PC is implemented.

I would also recommend not adding a cost to the Move Reminder if you are implementing the Pocket Reminder, as Legends Arceus and beyond do not have a cost attached to changing out moves.

Step 2: Add the Pocket Reminder Item.

Much like any other item, add the item PCKT_REMIND with the appropriate name and description and the attributes (item_attribute 0, HELD_NONE, 0, CANT_TOSS, KEY_ITEM, ITEMMENU_CLOSE, ITEMMENU_NOUSE). Then, make it have the PocketReminderEffect and define it in engine/items/item_effects.asm as:

-	dw NoEffect            ; ITEM_XX (whichever item you decide to replace)
+	dw PocketReminderEffect; PCKT_REMIND
+PocketReminderEffect:
+	farcall PocketReminderFunction
+	ret

Also make sure that whenever you add an item, that you remove it from catch_rate_items.asm.

Step 3: Add the Pocket Reminder Effect.

Next, in engine/events/overworld.asm, add:

+PocketReminderFunction:
+	call .LoadPocketReminder
+	and $7f
+	ld [wFieldMoveSucceeded], a
+	ret
+	
+.LoadPocketReminder:
+	ld a, [wPlayerState]
+	ld hl, Script_LoadPocketReminder
+	ld de, Script_LoadPocketReminder_Register
+	call .CheckIfRegistered
+	call QueueScript
+	ld a, TRUE
+	ret
+	
+.CheckIfRegistered:
+	ld a, [wUsingItemWithSelect]
+	and a
+	ret z
+	ld h, d
+	ld l, e
+	ret
+
+Script_LoadPocketReminder:
+	reloadmappart
+	special UpdateTimePals
+Script_LoadPocketReminder_Register:
+	opentext
+	special MoveReminder
+	closetext
+	reloadmappart
+	end

Note that this is similar to how it's done in the Pocket PC tutorial, but instead of calling PokemonCenterPC, we call the MoveReminder command we implemented in Step 1 instead, allowing the player to "talk" to the Move Reminder wherever they are! This code simply checks if we are using the Pocket Reminder from the Bag or the Select Menu. If we are using it from the Select Menu, we stay in the overworld and open the Move Reminder menu, but if we are using it from the Bag, we must go into the overworld first before opening the menu (which is what the reloadmappart command does). Then in any case, we must reloadmappart again once we are done to return to the overworld properly.

Step 4: Give it to the Player.

And you should be done, at least with the "backend" part of this tutorial. Now all that's left is to add a proper method of receiving the item. For my purposes, I added it to when Elm's Aide gives you Pokeballs. Wherever you end up adding it, make sure that you add it after the player receives their starter, since it wouldn't make much sense to remind Pokemon of moves when you don't have Pokemon in the first place. Open up maps/ElmsLab.asm, if you decide to add it when the player gets Pokeballs:

First, add the new call to both events:

AideScript_WalkBalls1:
	applymovement ELMSLAB_ELMS_AIDE, AideWalksRight1
	turnobject PLAYER, DOWN
	scall AideScript_GiveYouBalls
+	scall AideScript_GivePocketReminder
	applymovement ELMSLAB_ELMS_AIDE, AideWalksLeft1
	end

AideScript_WalkBalls2:
	applymovement ELMSLAB_ELMS_AIDE, AideWalksRight2
	turnobject PLAYER, DOWN
	scall AideScript_GiveYouBalls
+	scall AideScript_GivePocketReminder
	applymovement ELMSLAB_ELMS_AIDE, AideWalksLeft2
	end

Then, add it after the Aide gives you the Pokeballs and make sure that you move the end scene to our new script:

AideScript_GiveYouBalls:
	opentext
	writetext AideText_GiveYouBalls
	promptbutton
	getitemname STRING_BUFFER_4, POKE_BALL
	scall AideScript_ReceiveTheBalls
	giveitem POKE_BALL, 5
	writetext AideText_ExplainBalls
	promptbutton
	itemnotify
	closetext
-       setscene SCENE_ELMSLAB_NOTHING
	end

+AideScript_GivePocketReminder:
+	opentext
+	writetext AideText_GetPocketReminderText
+	promptbutton
+	giveitem PCKT_REMIND
+	writetext AideText_PocketReminderInfoText
+	waitbutton
+	closetext
+	setscene SCENE_ELMSLAB_NOTHING
+	end

And finally, add some appropriate text:

+AideText_GetPocketReminderText:
+	text "One last thing!"
+	line "I have this."
+
+	para "It's a Pocket"
+	line "Reminder!"
+	done
+	
+AideText_PocketReminderInfoText:
+	text "Use this to manage"
+	line "your party's"
+	line "moves!"
+	done

Bonus Tutorial: Pocket Move Deleter

I said this tutorial would be much simpler, so I might as well add this here. Add a new item, PCKT_DELETE with an appropriate name and description, and the attributes (item_attribute 0, HELD_NONE, 0, CANT_TOSS, KEY_ITEM, ITEMMENU_CLOSE, ITEMMENU_NOUSE). Make the following changes to engine/items/item_effects.asm:

-	dw NoEffect            ; ITEM_XX (whichever item you decide to replace)
+	dw PocketDeleterEffect; PCKT_DELETE
PocketReminderEffect:
	farcall PocketReminderFunction
	ret

+PocketDeleterEffect:
+	farcall PocketDeleterFunction
+	ret
PocketReminderFunction:
	call .LoadPocketReminder
	and $7f
	ld [wFieldMoveSucceeded], a
	ret
	
.LoadPocketReminder:
	ld a, [wPlayerState]
	ld hl, Script_LoadPocketReminder
	ld de, Script_LoadPocketReminder_Register
	call .CheckIfRegistered
	call QueueScript
	ld a, TRUE
	ret
	
.CheckIfRegistered:
	ld a, [wUsingItemWithSelect]
	and a
	ret z
	ld h, d
	ld l, e
	ret

Script_LoadPocketReminder:
	reloadmappart
	special UpdateTimePals
Script_LoadPocketReminder_Register:
	opentext
	special MoveReminder
	closetext
	reloadmappart
	end

Next, in engine/events/overworld.asm, add:

+PocketDeleterFunction:
+	call .LoadPocketDeleter
+	and $7f
+	ld [wFieldMoveSucceeded], a
+	ret
+	
+.LoadPocketDeleter:
+	ld a, [wPlayerState]
+	ld hl, Script_LoadPocketDeleter
+	ld de, Script_LoadPocketDeleter_Register
+	call .CheckIfRegistered
+	call QueueScript
+	ld a, TRUE
+	ret
+	
+.CheckIfRegistered:
+	ld a, [wUsingItemWithSelect]
+	and a
+	ret z
+	ld h, d
+	ld l, e
+	ret
+
+Script_LoadPocketDeleter:
+	reloadmappart
+	special UpdateTimePals
+Script_LoadPocketDeleter_Register:
+	opentext
+	special MoveDeletion
+	closetext
+	reloadmappart
+	end

Again, like before, we use the same code as the Pocket PC and Pocket Reminder, but instead we call the special command MoveDeletion, which is the same command the Move Deleter NPC calls in game. It'll open up the same menu as the Move Deleter NPC and allow you to delete a move, even HMs! This code simply checks if we are using the Pocket Deleter from the Bag or the Select Menu. If we are using it from the Select Menu, we stay in the overworld and open the Move Deleter menu, but if we are using it from the Bag, we must go into the overworld first before opening the menu (which is what the reloadmappart command does). Then in any case, we must reloadmappart again once we are done to return to the overworld properly.

Add the Pocket Deleter to the World

Once again, you are faced with the decision on where to put an item like this. Again, I'd recommend giving it to the player right after you receive the Pocket Reminder, just to keep it consistent. Open up maps/ElmsLab.asm again:

First, add the new call to both events:

AideScript_WalkBalls1:
	applymovement ELMSLAB_ELMS_AIDE, AideWalksRight1
	turnobject PLAYER, DOWN
	scall AideScript_GiveYouBalls
	scall AideScript_GivePocketReminder
+	scall AideScript_GivePocketDeleter
	applymovement ELMSLAB_ELMS_AIDE, AideWalksLeft1
	end

AideScript_WalkBalls2:
	applymovement ELMSLAB_ELMS_AIDE, AideWalksRight2
	turnobject PLAYER, DOWN
	scall AideScript_GiveYouBalls
	scall AideScript_GivePocketReminder
+	scall AideScript_GivePocketDeleter
	applymovement ELMSLAB_ELMS_AIDE, AideWalksLeft2
	end

Then, add it after the Aide gives you the Pocket Reminder and make sure that you move the end scene to our new script:

AideScript_GivePocketReminder:
	opentext
	writetext AideText_GetPocketReminderText
	promptbutton
	giveitem PCKT_REMIND
	writetext AideText_PocketReminderInfoText
	waitbutton
	closetext
-	setscene SCENE_ELMSLAB_NOTHING
	end

+AideScript_GivePocketDeleter:
+	opentext
+	writetext AideText_GetPocketDeleterText
+	promptbutton
+	giveitem PCKT_DELETE
+	writetext AideText_PocketDeleterInfoText
+	waitbutton
+	closetext
+	setscene SCENE_ELMSLAB_NOTHING
+	end

And finally, add some appropriate text:

+AideText_GetPocketDeleterText:
+	text "I also have this"
+	line "as well."
+
+	para "It's a Pocket"
+	line "Deleter!"
+	done
+	
+AideText_PocketDeleterInfoText:
+	text "Use this to delete"
+	line "your party's"
+	line "moves!"
+	done

And that's it!