Athena NPC Script

某日看见此文件,觉得比较有用,保存在空间里,顺便纪念下曾经假期在家的日子。
此文件为AthenaNPCScript的说明,正如汉化者所说,此文件确实是明灯,让你解决很多Athena的脚本问题。
——————–

汉化:lkm
重新整理:KINBA

希望本文能成为所有脚本写手在黑暗里的明灯
本文部分比较难理解的地方我都加了说明,虽然不详细,但是一看就懂
如果还是看不懂,可以找点使用该命令的脚本看看
本人不保证翻译的一定正确,如有错误的地方请指出

-----------------------------------
AthenaNPCScript
?目录
0.开始
1.NPC的定义
2.脚本说明和基本规则
3.命令,函数,定数Label等等
4.错误信息
5.其他
0.开始
本文中的函数及格式等表述参考包含于最新的snapshot中的npc_sample.txt。
考虑到查看本文所用的编辑器问题,tab文字表记为,任意值表记为。
坐标系参考下图。
↑Y的増加
( 0,200)–(200,200)
| |
| |
| |
| |
| |
( 0, 0)–(200, 0)→X的増加
1.NPC的定义
可放在athena目录之下任何地方(最好是athena/script下),文件格式为txt。
先记述NPC的功能作用(某些场合NPC一词并不恰当)。

*传送点:进行MAP间的移动。
,,warp,,,,
gatname 指定放置传送点的地图文件名。不要忘记加.gat。
x 指定放置传送点的横坐标。
y 指定放置传送点的纵坐标。
displayname 传送点识别名。可重名。DEBUG用。
dx 传送点的x轴有效范围。
dy 传送点的y轴有效范围。实际可能为方形范围而非圆形。
dx,dy的例子(● x,y):
0,0 1,0 2,2
* ***** *******
*●* **●** *******
* ***** *******
***●***
*******
*******
*******
*碰到●的话就移动。
destination_gatname 目标地图。.gat可有可无。
destination_x 目标地图的横坐标。
destination_y 目标地图的纵坐标。
注意事項:
如果在相同位置放置1个以上的传送点,则只显示最后记述的那个。
如果目标地图的坐标点为移动禁止、则会随机传送MAP的某个位置。
*怪物:管理怪物刷新。
,,,,monster,,,[,]
gatname 指定出现的地图文件名。
x 指定出现的横坐标。0为随机。
y 指定出现的纵坐标。0为随机。
xs 指定出现的X轴方向的范围。
ys 指定出现的Y轴方向的范围。
xs,ys的例子(●为x,y):
0,0 2,1
● *****
**●**
*****
*和●点为怪物出现的位置。
displayname 怪物的表示名字。
npcid 指定出现怪物的ID,参考mob_db.txt的设定。。
number 出现于地图中及范围内的最大数量。
spawn_delay1 刷新后等多少毫秒再次刷新。
spawn_delay2 死亡后等多少毫秒再次刷新。
event 指定事件。可省略。
注意事項:
依据spawn_delay1或spawn_delay2来刷新的结果为标准,优先选择二者中慢的那个。

*商店:贩卖物品。
,,,shop,: gatname 指定放置的地图文件名。
x 指定放置的横坐标。
y 指定放置的纵坐标。
direction 指定方向。
详细direction:
701
6 2
543
displayname 放置的商店所显示的名字。
npcid 指定放置的商店所显示的NPC的ID。
item_id 指定商店配备出售的物品的ID。参考item_db。
price item_id所指定的物品的价格。
如果指定为负数,则取item_db.txt中设定的价格。
:,可以用(,)来分割以指定多个物品。
*脚本:制作NPC。
,,,script,,,{<script>// ,,,“部分改为”-“的话,可用于制作存在 于map服务器中,但实际上并不使用的NPC。可用来作为后述的复制脚本的复制源。 *复制脚本:复制现存的NPC(的脚本)。 ,,,duplicate(), source以外的参数和一般的脚本相同。 source处指定为复制源的NPC的识别符。 如果复制源的NPC已经被放置于地图上,则必须为同一地图。 如果并没有被放置于地图上,则可复制到任何地图。 如script\npc\quest里的npc_event_ice.txt *用户定义型函数脚本:制作由脚本调用的用户定义型函数。 functionscript{ <script> … } 制作可由callfunc命令调用的函数。 函数调用的参数可由getarg函数取得。 函数最后必须加return命令。 *地图标识:管理地图规则。 mapflag gatname 指定设定规则的地图的文件名。 const 指定规则的内容。 const介绍。 nosave,, 重新登录时移动到,。 如果为”nosave SavePoint”的话则移动到保存点。 nomemodummy 禁止记忆。 noteleportdummy 禁止使用指定了SavePoint或者Random的warp段,传送之阵和瞬间移动。 noportaldummy battle.conf的noportal_flag为1时有效,禁止传送之阵。 noreturndummy 禁止warp命令SavePoint的回城,禁止蝴蝶翅膀的使用。 nobranchdummy 禁止使用枯树枝和箱子。 nopenaltydummy 禁止任何处罚。 nozenypenaltydummy 死亡时不掉钱。 notradedummy 禁止玩家间交易。 norevivedummy 死亡时强制传送到记录点。 noskilldummy 禁止所有技能的使用。 nodropdummy 怪物死都不掉落道具。 noabradummy 禁止使用 随机技能 技能。 noicewalldummy 禁止使用冰墙。 snowdummy 下雪。 fogdummy 雾。 sakuradummy 樱花。 leavesdummy 落叶。 raindummy MAP内全变为水区。 base_exp_rate, 基本经验得到率改为。 job_exp_rate, 职业经验得到率改为。 monster_noteleportdummy 怪物无法使用传送。 pvpdummy PVP可能MAP。 pvp_nopenaltydummy PVP不处罚。 pvp_nopartydummy PVP不可攻击同队人员。 pvp_noguilddummy PVP不可攻击同工会人员。 pvp_nightmaredroprandom,equip, PVP恶梦模式。的部位装备会掉落。 pvp_nocalcrankdummy PVP里不计算数组次序。 gvgdummy 工会战。 gvg_nopartydummy 工会战不可攻击同队人员。 pkdummy 可PK的MAP。 pk_nopartydummy PK模式里无法攻击同队伍的人。 pk_noguilddummy PK模式里无法攻击同工会的人。 pk_nightmaredroprandom,equip, PK恶梦模式。的部位装备会掉落。 pk_nocalcrankdummy PK里不计算数组次序。 turbodummy 变为 竞速场地。 2.脚本说明和基本规则 *数字 可使用带符号的整数和16进制整数。 带符号的整数使用半角数字123456等。 16进制数需使用0x12等0x开头的格式。 *字符串 “(双引号)内的所有的文字被认为为字符串。 “(双引号)想使用双引号需在双引号前加加\。 需要使用\记号时使用\\。 可表示的字符串可用^000000等来改变颜色。 也可变量 + “字符串”进行字符串连接。 *单项计算符 以下为数值专用的单项计算符。 – 符号取反(2的补数) ~ 位元逻辑否(1的补数) ! 逻辑否 *2项计算符 以下的2项计算符在数值和在字符串中意义不同。 + 加法或结合 数字的场合为加法。 其余将被认为为字符串进行结合。(如一行写不下可用+来做上下文的连接(VB里用的最多)。) 以下的2项演算符为数值专用。 – 减法 * 乘法 / 除法 % 取余 & 位元逻辑与 | 位元逻辑或 ^ 位元排他逻辑非 && 逻辑与 || 逻辑或 >> 按位右移动 如a=10 a>>1后,a为5,相当于除2 << 按位左移动 如a=10 a<<1后,a为20,相当于乘2 (位元是把变量或常量看作二进制数来做各种逻辑运算,具体请参考C++的教程) 下面2项演算符用于数值和数值间,或字符串和字符串间的比较。 下列关系式成立返回1、不成立返回0。 == 等于 != 不等于 > 大于 >= 大于等于(以上) < 小于(不满) <= 小于等于(以下) *3项演算符 根据条件是否成立选择一个进行处理。 ? : 为真时,进行处的处理,返回处的值, 为真时,进行处的处理,返回处的值,。 *变量 可使用半角英文字母及数字。 变量的可视范围及生存周期由前缀符指定。 请注意小写的l将被作为前缀处理。 (小写的l方式今后将被放弃请不要使用) 前缀 可视范围 生存时间 (无) 人物 永远 @ 人物 短时间 l 同上 同上(不推荐) $ 地图服务器 永远 $@ 地图服务器 短时间 # 帐号 永远 ## 帐号(全服) 永远 ‘ 脚本 短时间(参考下面) ‘@ 脚本 短时间(参考下面) 就是说,一般的短时间的变量用@, 需要保存的变量不需要前缀符, 全体人物共用的变量是$、需要同一帐号共用的变数使用#或##。 同帐号的是 # 或 ## 。 ‘系列的前缀符的变量的可视范围为脚本内。 和别的变量相比,有使用时可以不必关心是否和别的脚本的变量名重复, 而且也和特定玩家是否关联无关等优点。 ‘ 变量是依赖于脚本的变量,即使脚本执行结束其值也被保存(服务器 重启则消失)。虽然使用callfunc命令的话,被调用函数将使用与调用函 数无关的别的变量,但配合getarg()函数使用的话,被调用函数可操纵调用 函数方的值。 function script func1 { set ‘var1, ‘var1 + 1; // func1::’var1 加1 set getarg(0), getarg(0) + 1; // func2::’var1 加1 } function script func2 { callfunc “func1”, ‘var1; } ‘@变量为函数固有变量,每次实行callfunc,callsub时将取得新的内存空间, return返回时则恢复为原来值。由于其类似于C语言的局部变量,随意可以用 于NPC用的临时变量,或递归处理等。这个变量被调用方也可用getarg()函数 来操作调用方变量。 function script func3 { set , rand(5); if( == 0 ) { return ; } else { // 与别的变量不同,因为callfunc的目标变量不同, // 所以不会发生mes的结果全为0的现象。 callfunc “func3”; } mes ; return; } 另外,变量的型别由后缀符指定。 不过,字符串型只可用于人物临时变量,脚本依存变量, 和永久/临时的MAP服务器变量。 (后缀符@,$,$@) 后缀符 型别 (无) 整数 $ 字符串 <例> @hoge$ 字符串型临时人物变量 hoge 数値型永久人物变量 $hoge 数値型永久全人物共用变量 不要多用非临时变量。 不需要保存的东西尽量使用领事变量。 请多多考虑是否需要保存。 特别是永久的人物/帐号变量有个数限制。 知道某个变量使用完毕并不再使用的时候, 将值设为0即可删除。 *数组变量 变量名后 用[ ]括起的话则为数组变量。 变量名与”[” 之间不能有空格。 多次元排列也可以使用,能使用的次元没有限制 <例> hoge[10] fuga[ @temp ] foo[5][@i][3] 数组的元素编号可在0~127范围内指定、编号为0的元素与同名的变量 同值。比如说,hoge[0]与hoge为同一变量。 同样、fuga[0][1] 和 fuga[1] 是相同的变数。 (但是、foo[1][0][2] 和 foo[1][2] 是别的变数) 数组变量可用于人物的临时变量,临时/永久的地图服务器变量, 和脚本依存变量。 变量的型别可以为数字或字符串。 *标签 可使用半角英数和下划线(_)。 为了区别于变量和命令,推荐在先头加上L_。 比如说 L_hoge: 。 用于指定if语句和menu语句的跳往何处。 *定数 athena提供了db/const.txt内的定数。 只能在脚本内使用。 *内嵌变量 可用来取得交谈的玩家的状态。 记载于db/const.txt。 并且,绝大部分无法带入值。 *表达式 命令的参数为数值时,可利用。 虽然不需要空格,不过加上的话方便查看。 比较演算符及逻辑运算符当值为真时数值为1,当值为伪时返回0。 *事件 没有固定格式的脚本。 可用于制作时间相关的脚本。 在记述事件名的地方,指定为事件名::标签的话,则从事件指定的 标签开始执行脚本。 *命令句法 参数请使用半角空格分割。 最先的函数/命令不需要(),但其外需要。不需要参数的函数以 mes checkfalcon记述的话,会去读取checkfalcon变量的值(基本上是0), 而不会调用函数。 另外,在文的先头写入函数,可以按意愿舍弃值,也可以用带()呼叫没有返回值的 (用户定义)函数。(参照:npc_test_seller.txt) 3.命令,函数及定数 *基本语法 类似C语言的语法。如果不清楚的话,请看c语言的解说。 if – else if – else 语法 if( ) [ [else if() ]* else ] 如果为真、则执行部分并结束if文。 如果后边存在 “else if()” 的话,则从上至下顺次判断, 为真就执行并结束if句法。 最后如果有”else” 的话,当上面就返回假后实行、结束if句法。 然后、 能用 { , } 来组合多条语句。 例; // @input 为0 跳到HOGE。 if(@input == 0) goto HOGE; // @input 为0 跳到HOGE,否则跳到FUGA。 if(@input == 0) goto HOGE; else goto FUGA; if(@input == 0) mes “zero”; else if(@input == 1) mes “one”; else if(@input == 2) { mes “two”; } else { mes “??unknown”; mes “请输入0,1,2中的任何一个值。”; } 在没有中括号的复数个if文后接上else文的话,则else文与最后一个 没有else文对应的if文相对应。例如: if(@temp <= 1) if(@temp <= 0) mes "<= 0"; else mes "1"; else mes ">= 2″; 和、 if(@temp <= 1) { if(@temp <= 0) mes "<= 0"; else mes "1"; } else mes ">= 2″; 为相同的处理方法。 for语法 for(; ; ) 执行运行后、只要为真,则执行后, 再执行。 (译注:C语言中的for循环语句,为初始化语句开始时执行一次, 此后并不再执行,为条件判断语句,为真则执行后执行 ,并再次判断,如此循环,直到为伪则结束整个for文。) for(set @i,0;@i < 5;set @i,@i+1) mes @i; //设置@i为0,如果@i小于5则显示@i然后@i加1 for(set @i,0;@i < 5;set @i,@i+1) { mes @i; next; // 依次输出显示@i if(@i > 3){close;} //原来的说明里没有这行,现在我加上大家就看的清楚了,当你看到屏幕显示 } //4的时候脚本退出,而如果把if(@i > 3){close;}加在mes @i;上的话就只显示到3,为什么?自己思考一下啊。。 while语法 while( ) 判断为真时循环执行。 set @temp,5; while(@temp > 0) { mes @temp; set @temp,@temp-1; } switch语法 switch() { [case : ….] [ default: …] } 移动到与为相同值的的”case “处。当所有case都不 一致时,如果有default文则移动到dedault文,没有则结束。 另外,由于为fall through,所以并不会自动跳出switch,需要跳出的话 请使用 break; 命令。 (译注:所谓fall through,则为当某个case文匹配的话,如果没有break文, 则包括匹配上的case文及其后面的case文都将被执行,是C语言的一个特性, 也是容易出BUG的地方。) switch(@temp) { default: mes(“unknown FALLTHRU”); // 因为没有”break”所以继续 case 0: mes(“零”); break; case 1: mes(“壹”); break; case 2: mes(“贰 FALLTHRU”); // 因为没有”break”所以继续 case 3: mes(“叁”); break; case 4: mes(“肆”); break; case 5: mes(“伍”); break; } do – while 语法 do while(); 等同于” while() ;”, 最初实行。 然后、当为真期间循环执行 。 break 命令 结束最内部的 for , while , switch , do – while文。 continue 命令 移动到最内部的 for , while , do – while的下一个循环位置。 function 语法 声明和定义位于同一个脚本内的函数。 function hoge; // 函数声明 function hoge { // 函数定义 mes getarg(0); } hoge “fuga”; // 调用函数 如果调用未声明的函数则会出错。 *命令文 mes命令 mes ; string 字符串 将记述于内的字符串显示到消息窗口中。 next命令 next; 在消息窗口上显示next按钮,并等待。 close命令 close; 在消息窗口上显示close按钮,中止脚本。 close2命令 close2; 在消息窗口上显示close按钮后等待,要中止脚本时请使用end命令。 可执行按下close按钮后的处理。 menu命令 menu ,[,,…]; stringN 字符串 labelN 标签 显示菜单。如果选择了记述于内的字符串则从开始 执行脚本。 并且,被选择的标签号将被代入到@menu变量。 (也会被代入l15中,但今后并不保证能够使用,请不要使用l15) goto命令 goto