summaryrefslogtreecommitdiff
path: root/Prompt-for-reusing-Repels.md
blob: d851915545e00377335cd5a4c810be6ea7db6cc1 (plain)
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
Credit to ExpoSeed for this feature.

This tutorial will ask the player, upon a Repel running out, if they want to use another repel, and use the repel if they say yes.

## Contents
1. [Store last used Repel](#1-store-last-used-repel)
2. [Ask the player](#2-ask-the-player)

## 1. Store last used Repel

The tricky part of implementing this is that the game does not actually store which repel is used. It only changes `VAR_REPEL_STEP_COUNT`. In order to remedy this, we must store the repel used. 

We can use any of the unused vars to do this. This tutorial will use `VAR_UNUSED_0x404E`, but you can use whatever you like. Edit [include/constants/vars.h](../blob/master/include/constants/vars.h):
```diff
-#define VAR_UNUSED_0x404E                    0x404E // Unused Var
+#define VAR_REPEL_LAST_USED                  0x404E
```

Next, we need to write to the variable when a repel is used. Edit [src/item_use.c](../blob/master/src/item_use.c):
```diff
 static void Task_UseRepel(u8 taskId)
 {
     if (!IsSEPlaying())
     {
         VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(gSpecialVar_ItemId));
+        VarSet(VAR_REPEL_LAST_USED, gSpecialVar_ItemId);
         RemoveUsedItem();
         if (!InBattlePyramid())
             DisplayItemMessage(taskId, 1, gStringVar4, BagMenu_InitListsMenu);
         else
             DisplayItemMessageInBattlePyramid(taskId, gStringVar4, Task_CloseBattlePyramidBagMessage);
     }
 }
```
There is one last issue. We also need a value to write to `VAR_REPEL_STEP_COUNT`. From a script, we cannot get this from the item ID alone. While we could use another unused variable, there is a way to avoid having to do this. `callnative` in scripts lets you call any function from a script. So, we can define a new function and use it with `callnative`. `callnative` is not the only way to use C code in scripts. You can also define specials and save some (but not much space), but it is largely unneeded.

In [src/item.c](../blob/master/src/item.c), we will declare and define a new function (note: declare the function in include/item.h):
```c
void ItemId_GetHoldEffectParam_Script();
```
```c
void ItemId_GetHoldEffectParam_Script()
{
    VarSet(VAR_RESULT, ItemId_GetHoldEffectParam(VarGet(VAR_0x8004)));
}
```
Next, we will modify the script to ask the player if they want to use another repel.

## 2. Ask the player
Now, we have everything we need. Edit [data/scripts/repel.inc](../blob/master/data/scripts/repel.inc):
```diff
 EventScript_RepelWoreOff::
+	lockall
+	checkitem VAR_REPEL_LAST_USED, 1
+	compare VAR_RESULT, FALSE
+	goto_if_eq EventScript_RepelWoreOff_NoMoreRepels
+	msgbox Text_RepelWoreOff_UseAnother, MSGBOX_YESNO
+	compare VAR_RESULT, 0
+	goto_if_eq EventScript_RepelWoreOff_ChooseNo
+	copyvar VAR_0x8004, VAR_REPEL_LAST_USED
+	callnative ItemId_GetHoldEffectParam_Script
+	copyvar VAR_REPEL_STEP_COUNT, VAR_RESULT
+	bufferitemname 1, VAR_REPEL_LAST_USED
+	removeitem VAR_REPEL_LAST_USED, 1
+	playse SE_REPEL
+	msgbox gText_PlayerUsedVar2, MSGBOX_SIGN
+	goto EventScript_RepelWoreOff_End
+EventScript_RepelWoreOff_ChooseNo:
+	closemessage
+	goto EventScript_RepelWoreOff_End
+EventScript_RepelWoreOff_NoMoreRepels:
	msgbox Text_RepelWoreOff, MSGBOX_SIGN
+EventScript_RepelWoreOff_End:
+	releaseall
	end

 Text_RepelWoreOff:
	.string "REPEL's effect wore off…$"

+Text_RepelWoreOff_UseAnother:
+	.string "REPEL's effect wore off…\n"
+	.string "Use another?$"
```
Let's walk through this script. First, we check whether the player has another of the same repel in their bag. If they don't, we jump to the end. But if they do, we ask the player if they want to use another. If they say "No", then we close the message box and end the script. If they say "Yes", then we set the step count variable appropriately, deduct a repel from the bag, play the appropriate sound effect, and show a message saying the player used a repel. 

And that's it!

![](https://i.imgur.com/4AdZCbo.png)
![](https://i.imgur.com/t0OKP9X.png)

Alternatively, check out DizzyEgg's [repel](https://github.com/DizzyEggg/pokeemerald/tree/repel) branch for a version which uses a multichoice box instead.