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