晓月圆舞曲的flag的额外用途
本文所述的一些改动用dsvania编辑器可以方便的完成,所以基本上改动是在这个编辑器里进行的,你也可以对照rom map用16进制编辑器修改,不过这样很麻烦。
flag就是一些标记,以美版晓月为例,这是他们的地址和用途。(从dsvania编辑器文档翻译而来)
0200033C - Event flags.事件的标记,记录发生过的事情,已发生过就不再发生。
02000344 - Bitfield of miscellaneous flags.杂项,是特殊物体相关的,如可被攻击破坏墙是否已经破裂,可被道具破坏的墙是否已经破裂,机关门,铁球是否达到过足够的摆幅,按钮是否按过之类的。
02000360-02000373 - Bitfield of pickup flags.可拾取物品,记录地图上已经捡过的东西,所以地图上捡过就不会再次生成了。但如果物品的设置的var A是0,则不会设置flag。
02000378,4 - Bitfield of what warp rooms you've unlocked.记录了你开过的传送的点,与查看地图界面上是否有黄色标记的房间无关。此外,一旦进入任何一个传送点,荒城回廊的传送点就会自动开启。
0200037C,2 - Bitfield of which area names you've seen.记录你见过的区域名,就是进新区域会弹出的那行地名。下次进入就不会显示名字了。
0200037E,2 - Boss death flags. boss死亡标记,记录已经打败的boss,这样已打败的boss就不会再出现了。
00 0001 Graham 格拉罕
01 0002 Death 死神
02 0004 Julius 尤利乌斯
03 0008 (Unused) 未使用
04 0010 Headhunter 收集者
05 0020 Legion 死人军团
06 0040 Balore 巴洛尔
07 0080 Chaos 混沌(混沌击败时会设置这个flag,但是读档后又会变回没打过混沌的状态,这样读档后就能再打混沌了。)
08 0100 (Unused) 未使用
09 0200 (Unused) 未使用
0A 0400 Manticore 曼提科亚(蝎尾狮)
0B 0800 Creaking Skull 大骷髅
0C 1000 Big Golem 巨人
0D 2000 (Unused) 未使用,经测试似乎是食人虫
0E 4000 (Unused) 未使用
0F 8000 Great Armor 大装甲(此怪物的flag可以自己设置,是放置怪物时的var A,dsv编辑器内可改)
大骷髅和大装甲的换皮怪大骸骨、终极卫兵、影子骑士作为boss和他们的本体flag是一样的。大骸骨是0B,大装甲flag是自己设置。
上面就是所谓的flag了,可以看出这是用来记录各种事项的。所以如果有东西共用flag就能相互影响。比如原版的按钮和机关门,按钮按下,改变了flag,机关门检测到flag已经设置为1,就打开了。而两个物品共用flag,就会在拾取一个物品以后设置flag,之后两个物品都不会再生成了。
而设置flag是把这位标记从0变成1,但是具体是哪一位?这需要看地址。这里用gba模拟器VisualBoyAdvance自带的内存查看器看看这些值。先看记录拾取物品的区域。

捡起这把武器。看看内存的变化。从02000360开始是捡到的物品的标记。

我们可以看见第三个数字变成了02,这里是小端模式,16进制,低位地址更低。那么为什么是02?换成2进制就明确了。00 00 02,换成二进制看。从左到右,00 00 02四组数在不同的地址,右边的地址更大,所以位数更高。实际上是02 00 00,而每组数都是两位16进制数8位2进制数,即一个地址存一个字节。
十六进制 00 00 02 ...
二进制 0000 0000 0000 0000 0000 0010 ...
位数 7654 3210 7654 3210 7654 3210 ...
7,6,5,4 3,2,1,0 15,14,13,12,11,10,9,8 23,22,21,20,19,18,17,16 ...
这就一目了然了,17对应的位置被设置成了1.所以那里看起来就是02了。所以flag就是以文章开头的地址为最低位的一个很长的数的每一位。但这个地址是有范围的,所以这个数的位数是有范围的,编辑超出位数的flag就是编辑不属于自己类型的flag了。我们可以很容易地让一个能自由编辑flag位置的东西设置或者检测的flag因为足够大而改动别的区。这就是重点了。
能自由控制设置flag的位置的,有按钮,铁球,可破坏墙,可拾取物品等。能修改要检测的flag的位置的,有可被道具破坏墙,机关墙,商店物品池(仅限bossflag)等。bossflag等则是不可修改的。

以打完boss地板碎裂为例。需要boss和可被机关破坏墙。拿食人虫当被打的对象,因为它不需要站在地板上。效果如下:

bossflag的地址是0200037E。地板是杂项,起始地址是02000344。两者起始地址不同,所以flag值不同。食人虫varA设为1,让他作为boss登场。地板形状要合适,varA取000B。食人虫bossflag是0D,即 20 00,小端模式下是00 20,是击败后在第13位上设置flag。
问题在于,地板检测的的flag,即地板的var B要如何设置?
每个地址下有一个字节,8位二进制数,就是8个flag。(0200037E-02000344)*8=1D0,这就是bossflag的地址和miscellaneous flags的地址之间的这些数据的位数对应的flag的偏移值,bossflag的第0位对于miscellaneous flags来说就是1D0。而bossflag值是相对bossflag的第0位,格拉罕的死亡标记在miscellaneous flags的值中是0x01D0,死神是0x01D1,而食人虫是0x01DD。所以地板值varB设为1DD,就能检测到食人虫的bossflag,在食人虫被击败时自动碎掉了。

我比较懒所以不写太多,微机原理也学的不算好,有些概念讲的不清楚,但也不再多说了,原理大致如此。flag是四位有符号16进制数,所以负数flag能影响到地址在前面的flag。计算方法也给出来了,剩下的自行摸索吧。日版和美版可能存在地址上的差异,没有查看过日版(或者汉化rom),所以无法下定论。