summaryrefslogtreecommitdiff
path: root/Trigger-Map-Scripts-By-Flag.md
blob: a82edafbf145538cb12c1b8bb65c6d423faf2ec2 (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
### Triggering Map Scripts With Flags

In vanilla emerald, mapscripts are conditionally triggered based on the value of a provided variable. This small change allows mapscripts to be triggered based on the value of a flag instead. This is useful if you have an event/cutscene that you need to activate only once. This also works just fine with poryscript.

To add this feature, you will modify the function `MapHeaderCheckScriptTable` in the file `src\script.c`.  Simply replace that entire function with the following:

```c
u8 *MapHeaderCheckScriptTable(u8 tag)
{
    u8 *ptr = MapHeaderGetScriptTable(tag);

    if (!ptr)
        return NULL;

    while (1)
    {
        u16 varIndex1;
        u16 varIndex2;
        bool8 isFlag;
        bool8 flagSet;

        // Read first var (or .2byte terminal value)
        varIndex1 = T1_READ_16(ptr);
        if (!varIndex1)
            return NULL; // Reached end of table
        ptr += 2;

        // Read second var
        varIndex2 = T1_READ_16(ptr);
        ptr += 2;

        isFlag = varIndex1 < VARS_START;
        flagSet = isFlag && FlagGet(varIndex1);

        // Run map script if vars are equal
        if (isFlag
         && ((VarGet(varIndex2) != 0 && flagSet)
          || (VarGet(varIndex2) == 0 && !flagSet))) {
            return T2_READ_PTR(ptr);
        }
        else if (VarGet(varIndex1) == VarGet(varIndex2)) {
            return T2_READ_PTR(ptr);
        }
        ptr += 4;
    }
}
```

To make use of this, write any mapscript as you normally would but substituting a flag in place of the var. If the value provided is zero, the mapscript will trigger when the flag is **not** set.  If the value is **not** zero, the mapscript will trigger if the flag **is** set.

For example, the following will trigger a script when the flag `FLAG_DO_A_THING` is set.

```
MyMap_MapScripts::
	map_script MAP_SCRIPT_ON_FRAME_TABLE, NeoBay_MapScripts_MAP_SCRIPT_ON_FRAME_TABLE
	.byte 0

MyMap_MapScripts_MAP_SCRIPT_ON_FRAME_TABLE:
	map_script_2 FLAG_DO_A_THING, 1, MyMap_EventScript_DoSomething
	.2byte 0
```

It's that easy!

## Caveats ##
Due to the values associated with them, this will NOT work for "Special" flags, i.e. those beginning at `SPECIAL_FLAGS_START`.  Those overlap with the VAR indices, and thus will be read as though they are VARs instead of flags.