- 积分
- 34677
- 威望
- 499
- 魅力
- 507
- 经验
- 20326
- 热心度
- 9
- 注册时间
- 2006-3-13
- 最后登录
- 2024-9-30
- 主题
- 134
- 回帖
- 4949
- 精华
- 35
- 阅读权限
- 150
TA的每日心情 | 郁闷 2015-6-6 16:12 |
---|
签到天数: 52 天 连续签到: 1 天 [LV.5]女巫
超级版主
- 积分
- 34677
|
楼主 |
发表于 2014-10-15 10:52:15
|
显示全部楼层
本帖最后由 贤知有您 于 2014-10-16 14:26 编辑
【讨论】ERM执行顺序和ERM变量的应用
首先,如果你还不知道如何把ERM语句引入到游戏中,还不晓得什么叫触发器什么是接收器,请先阅读《ERM帮助》中关于“ERM教程”的部分。
建议学习或测试ERM时可以采用“以地图事件形式把ERM脚本引入游戏”。因为载入地图时只要不WOG化,就只执行地图事件的脚本了,可以排除其他脚本的干扰。
触发器是由游戏过程产生的各种触发事件,也就是让后续代码执行的前提条件。实际上触发器也是一个函数形式(!?开头)。所以,一般来说,某段代码开始执行时,应该是先从某个触发器代码开始的。
假设访问智慧树物体触发(!?OB102;)触发器,那么程序开始执行脚本中所有关于!?OB102;的函数主体部分(触发器或函数代码段姑且统称为函数主体)。
脚本文件(*.ERM以及事件ERM)之间的执行顺序,大致以这样理解:
1.地图事件ERM先执行,且事件的初发日越早越先执行.
2.S文件夹的ERM执行,如果不同MOD有相同的ERM脚本,只有最优先MOD的该脚本执行.
3.S文件夹下ERM文件的执行顺序比较奇特,并不完全由脚本的文件名排序顺序决定.
首先,如果是按照官方约定的命名方式"数字+空格+wog+空格+其他字符串.erm",那么前缀数字越大,越先执行.比如官方的<78 wog - wogify.erm>比<1 wog - cheat menu.erm>要早执行.
其次,"数字+空格"的组合几乎要比其它组合要早执行.
最后,没有空格情况下,看一组比较顺序(从左到右的执行顺序)
,.erm -> 0.erm -> 000.erm -> 1.erm -> 999.erm -> ab.erm -> bc.erm -> 我.erm
貌似有点让人捉摸不透,但至少我们可以自行测试一下便有分晓.
言归正传,所有脚本中带有(!?OB102;)触发器都会执行,而且是按上述ERM的顺序执行.
假设某个!?OB102;触发器代码是这样写的.
!?OB102;
!!FU12345:P;
!!VRv1:S0;
触发器(函数)下调用了另外一个函数FU12345.
那么程序又开始按照ERM文件处理顺序执行所有关于FU12345的函数主体(!?FU12345;)
只有当所有!?FU12345;函数执行完毕后,再回到上面那个OB102触发器,执行后面那句!!VRv1:S0;
只要调用了函数,都会如此这般执行,执行完毕后再回到原来的位置下一句继续执行.
当所有的!?OB102;主体都执行完毕了,也就是所有脚本都执行完毕,游戏继续进行,等待下一个触发器的产生.
为什么要花这么多文字来说明ERM语句执行顺序呢?后面将说明重要性.如何正确使用ERM的变量.
ERM变量类型包括:
1. 4字节的带符号整型变量:v变量,y变量,y-变量,f-t快捷变量,以及存在于函数内部的参数变量x1-x16
2. 1字节的标志变量: 1-1000
3. 4字节的特殊变量:w变量
4. 4字节的浮点数单精度变量:e变量,e-变量
5. 512字节的文本变量:z变量,z-变量
其中函数过程使用变量最多的是 v,y,y-和快捷变量.下面主要以这几个变量做说明.
y变量和y-变量(下标都是从1-100)被称为临时变量.
在旧版本的WOG中,y变量不能跨触发器,甚至不能跨函数来保存.意思就是说,当跳转到另外一个函数后,y变量的值会被重置为0.
写过脚本的都知道y变量可以跨函数返回时来使用.
虽然这样,但并不是说y变量可以随意跨度来用.(不同函数时会被清零)
这里涉及到一个变量存储期的问题,y变量的存储器很短,因为它经常被使用而容易冲突.
跨函数前y变量的值,跨函数返回时仍可获得这个值.很绕口,看下面一段代码.
你能直接猜出弹框的结果吗?
ZVSE
!?PI;
!!VRy1:S100;
!!IF:M^A Y1=%Y1^;
!!FU123:P;
!!IF:M^B Y1=%Y1^;
!?FU123;
!!IF:M^C Y1=%Y1^;
!!VRy1:S999;
!?FU123;
!!IF:M^D Y1=%Y1^;
!!VRy1:S-999;
!!FU124:P;
!!IF:M^E Y1=%Y1^;
!?FU124;
!!IF:M^F Y1=%Y1^;
结果可能出乎你意料,分别弹框是:
A Y1=100
C Y1=0
D Y1=999
F Y1=0
E Y1=-999
B Y1=100
怎么,拿来测试了吧,是不是越来越晕.这正正说明,临时变量的不确定性.
函数嵌套函数时,y临时变量最好少用,关键的变量最好使用v变量来处理.
说了这么久,怎么不说y-变量呢,其实y-变量很好用,在不对它赋值之前,它的值不变(跟v变量一样).
不过,ERA的作者bersy在ERA帮助中提到,不建议使用y-变量,可能是ERA的支持度还不够吧.
但官方脚本很多也用y-变量的,暂时还没发现什么问题,可以放心使用,但它仍属于临时变量.
至于快捷变量f-t, 跟y变量差不多,但要注意一个奇怪问题是,应用快捷变量的数字运算最好不带空格.
比如 !!VRy2:Si +y1; 提示是一个错误语法.不带空格的话!!VRy2:Si+y1;就没问题.(主要是加减方面会出BUG)
要长期保存值,当然首选v变量了.
你会发现,v变量仍然分成2部分,临时v变量和非临时v变量.临时v变量是从官方脚本中约定出来的.
临时v变量的好处是,可以跨函数使用,只要你确定没有被其它占用改变之前就可以一直保留.
而编写erm时也是不能跨触发器来使用v临时变量的.在触发器产生之前,它可能已经不是那样子了.
比如:
!?BG0;[动作前]
!!BG:N?v2 E?v3 Q?v4;
!?BG1;[动作后]
!!IF:M^攻击堆栈%V2 被攻击堆栈%V3 攻击方%V4^;
这种使用是不可靠的.BG0在这段没更改v2-v4,但可能下一个BG0就会改掉v2-v4.
就算所有BG0不更改v2-v4,中间可能触发!?MF1;等,仍然有可能被覆盖.
正确的方法,最好使用未曾用过的v变量.
可以研究一下沧海一粟大师的怪物强化,因为经常在其它触发器使用到BG0动作前的数据,所以沧海一粟使用了一整套v变量来记录,以便调用.
当然,你可以想象得到,这套v变量记录BG0信息(叫变量准备吧)需要在最前端的脚本先执行,后面才行应用.这也是脚本执行顺序的重要性.
这里顺带提醒一个特殊问题.
WOG官方脚本定义了很多宏变量,比如
!?TM2&$day$=1/$once$=1; // only once at day 1
应用起来很方便,但需要注意的是,假设你新建了一个erm文件 (100 wog - 我的脚本.erm)
在这个脚本中应用宏变量就会出错了.
宏变量作为预定义的部分,有点类似替换文本.比如上面的$once$会被事先替换为v2391.
由于100 wog 比78 wog - wogify.erm先被扫描,故会认为未定义宏变量而出错.
最后综合一下使用y和v变量注意事项:
1.y变量只能在某段顺序执行的函数代码下应用较好.尽量避免跨函数使用.
2.v变量的临时变量也应该在能预知不被改变的代码段中应用,跨函数时也要避免冲突.
3.跨函数可以直接使用x1-x15来传递一些特定值.比调用变量要方便.
|
|