--.--.-- *--*
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

はじめてのAurigaスクリプト 応用編(6)

2011.12.16 *Fri*
アタッチとデタッチについて

Athena系のスクリプトの特徴として
アタッチという概念があります。

既存スクリプトの例を見ると、プロンテラ大聖堂の結婚NPCに
アタッチ&デタッチが使用されています。

npc_quest_marriage.txt(430行)

//もし嫁がログインしてるなら仕込まれたタイムアップフラグを堕ろす
if(attachrid(getcharid(3,'bride$))) {
set @defend,0;
detachrid;
}
if(attachrid(getcharid(3,'groom$))) { //再度アタッチ
//PTが解体されていようが嫁がすでにログアウト状態であろうが関係なし!性転換は考慮しない
announce "国王陛下: 汝、その富める時も、貧しき時も、病めるときも、健やかなる時も",9;
mes "[トリスタン3世]";
mes "新郎" +'groom$+ "よ。";
mes "汝、その富める時も、貧しき時も、";
mes "病めるときも、健やかなる時も、";
mes "" +'bride$+ "を愛し";
mes "敬い、慰め、助け、その命の限り";
mes "堅く節操を守ることを誓うか。";
next;


■アタッチとは?
通常のスクリプトでは、NPC会話や、アイテム使用時など、
そのユーザが直接関わったスクリプト内でのみ
キャラクタのパラメータ・ユーザ変数などへのアクセスが行えます。

NPC会話時やアイテムスクリプト実行時には、内部で自動的にそのキャラクタへ
アタッチが行われています。

OnTimerなどのイベント時には、特定キャラクタへのアタッチが行われていませんので
全体アナウンスなどの、キャラクタとの対話以外の命令しか実行できません。
アクセスしようとするとmapserverの画面に「fatal error ! player not attached!」などと表示されます。

しかし、結婚NPCの場合のように、話しかけたキャラとは別のキャラの
パラメータや変数を扱ったりすることが必要となることがあります。

その場合、アタッチという手続きが必要になります。

■アタッチの利点
アタッチができるとなにができるかというと
・パーティIDからパーティメンバーへのアクセス
・IDや名前が判ればログイン中かどうか判別できる
・他、ワープさせる、アイテムを渡す、キャラ永続変数の変更・・・などなど

■アタッチの方法

if(attachrid(getcharid(3,<キャラクター名>))){
~~~アタッチしたキャラへの処理~~~
detachrid; //必ずデタッチする。しないとアタッチされたキャラが固まることがあります!
} else {
~~~ログアウトしている場合の処理~~~
}


■注意点
Aurigaでは、アタッチしたキャラクタへの変数やパラメータを参照・書換は行えますが
mes や menu や input などのユーザ入力待ちの命令は使用できません。
メッセージ表示は行えても、next、closeなどで、NPCスクリプトが再開できずに固まってしまいます。

script_ref.txt にもこう書いてあります。
この命令でPCをアタッチした場合、mes,menu,nextなどの
ウィンドウ(やボタン)が出る命令を実行してはいけません。
相手が他のNPCと会話中の場合、これらの命令は正しく動作しません。
情報取得命令などだけで済ませるべきです。


※結婚NPCの場合は、最初に話しかけたNPCなので、キャラクタにたまたま
NPCセッションが残っており、かなり奇跡的に動くスクリプトだったりします。

※eAthenaではこの問題は解決されています。C_EOL でのスタックの扱いの違いだけっぽい。

■アタッチを使用した例

パーティ用の討伐クエストの一部です。
「案内人」というNPCで参加パーティメンバーのチェック、クールタイムのチェックを行い、
資格があるキャラをクエストマップへ転送します。
転送する際、入室者のキャラ名を配列変数「'INOUT$」へ登録しています。

これは、そのクエストマップの入退出の監視を行うイベント型NPCです。
OnPC系のイベントでも行えますが、PTを抜けたときに退場させたいのでこのような処理になっています。


prontera.gat,0,0,0 script mission_chk_inout -1,{
OnInit:
OnTimer1000:
//NPC「案内人」の配列変数「'INOUT$[n]」の配列の長さ取得
set '@len,getarraysize(getvariableofnpc('INOUT$,"案内人"))-1;

//配列に登録されているキャラを順番に処理する
for(set '@i,'@len; '@i>=0; set '@i,'@i-1){
set '@chr$, getvariableofnpc('INOUT$['@i],"案内人"); //キャラ名取得
set '@dummy,getmapxy('@mapname$,'@dummy,'@dummy,0,'@chr$); //該当キャラがいるマップ名取得

if('@dummy==0 && '@mapname$=="bat_a01.gat") { //クエストマップにいるかどうか
if(attachrid(getcharid(3,'@chr$))){
set QUEST_CURSE_TIME,gettimetick(2)+300; //クールタイムの更新
if(getcharid(1)==0) { //PTID==0ならパーティを抜けているので退場させる
deletearray getvariableofnpc('INOUT$['@i],"案内人"),1;
warp "SavePoint",0,0;
}
detachrid;
}else{
//ログアウトしているのでリストから削除
deletearray getvariableofnpc('INOUT$['@i],"案内人"),1;
}
} else {
//該当マップに居ないのでリストから削除
deletearray getvariableofnpc('INOUT$['@i],"案内人"),1;
}
}
initnpctimer;
}


■sleepとアタッチ
sleepという命令があります。一定時間ウェイトを行う命令です。
会話型NPCの場合、sleep命令が呼ばれるとその後、nextやcloseが反応しなくなります。

これはアタッチが外れたのではなく、キャラ側にNPCIDが残っていないので、ユーザー入力系のスクリプトの再開ができない(アタッチのときと同じ現象)ようです。

スリープ後に会話を再開したい場合、素直にsleep2を使いましょう。
関連記事

COMMENT

Comment Form


秘密にする
 


TRACKBACK

TrackBack List



プロフィール

Author:みのり

すごく面倒臭がりで大雑把です。
なので、すぐ楽をしようとして
ツールを作り始めます。
ツールを作る時間と手作業で費やす時間
はたしてどちらが短いのか……


-構築環境-

Auriga0945 MySQL 5.5
with 2011-12-20bRagexeRE

3CeAM rev525
with 2010-07-30aRagexeRE



カテゴリ

未分類 (9)
RagexeRE (9)
eAthena (1)
Auriga (5)
ツール:eAthena用 (4)
ツール:Auriga用 (6)
ツール:その他 (14)
はじめてのAurigaスクリプト (8)
はじめてのAurigaスクリプト基本編 (21)
はじめてのAurigaスクリプト応用編 (7)
Aurigaスクリプト (3)
本鯖 (7)
Aurigaスクリプト:冒険者アカデミー (6)
ドラクエ10 (2)
新生FF14 (3)
EVE Online (2)



最新記事



最新コメント



月別アーカイブ



検索フォーム



リンク

このブログをリンクに追加する



ブロとも申請フォーム

この人とブロともになる



QRコード

QR



12
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
Copyright © Rocco di Forte All Rights Reserved.
テンプレート配布者: サリイ  ・・・  素材: HELIUM  ・・・ 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。