2008年07月25日
NPC・ペットの会話・対応するLSL
NPCやペットで周囲の会話に反応・対応するためのLSLです。
オーナーがたっちすれば 動作をON-OFFできます。
会話の応対するための 言葉は ノートカードで作成して 読み込むタイプです、
【聞き取りの判定のキーワード:文字短すぎない程度】 こんにちは
【返事をするキーワード:応答メッセージ:コメント文字1行以内】 こんにちは^^ビーム ~(ノ=^‥^)‥‥…━━━━━☆
【聞き取りの判定のキーワード:文字短すぎない程度】 おはよう
【返事をするキーワード:応答メッセージ:コメント文字1行以内】 おはようです^^b
データは必要な実際の言葉を、改行して 順番にひたすら並べてあるだけでokです
//NPC 会話対応
//会話を常時LISTEN 聞き取りをするための基本、
//読み込みデータと 一致するものが 含まれているかチェックすだけの作業です
//100個のキーワードで実施して、5000程フリーメモリが残っていましたので、200ワードくらいが限界です
//キーワードが短い、ひらがなだけであるものは いろいろな言葉に重複してしまうので 注意してください
//文字列の中に 含まれているか? という判定なので 会話のはじめでなくても 判定ができます
//逆に 希望・想定していない文字に反応しないように キーワードは意味のある長さの文字であるようでないといけません
//たとえばひらがな2文字の ”よろ”に登録すると ”よろしく” だけでなく ”よろい” ”よろけた” ”よろこび” に判定できちゃいます
<参考LSL>
オーナーがたっちすれば 動作をON-OFFできます。
会話の応対するための 言葉は ノートカードで作成して 読み込むタイプです、
【聞き取りの判定のキーワード:文字短すぎない程度】 こんにちは
【返事をするキーワード:応答メッセージ:コメント文字1行以内】 こんにちは^^ビーム ~(ノ=^‥^)‥‥…━━━━━☆
【聞き取りの判定のキーワード:文字短すぎない程度】 おはよう
【返事をするキーワード:応答メッセージ:コメント文字1行以内】 おはようです^^b
データは必要な実際の言葉を、改行して 順番にひたすら並べてあるだけでokです
//NPC 会話対応
//会話を常時LISTEN 聞き取りをするための基本、
//読み込みデータと 一致するものが 含まれているかチェックすだけの作業です
//100個のキーワードで実施して、5000程フリーメモリが残っていましたので、200ワードくらいが限界です
//キーワードが短い、ひらがなだけであるものは いろいろな言葉に重複してしまうので 注意してください
//文字列の中に 含まれているか? という判定なので 会話のはじめでなくても 判定ができます
//逆に 希望・想定していない文字に反応しないように キーワードは意味のある長さの文字であるようでないといけません
//たとえばひらがな2文字の ”よろ”に登録すると ”よろしく” だけでなく ”よろい” ”よろけた” ”よろこび” に判定できちゃいます
<参考LSL>
list DATA=[];//聞き取りの判定 キーワード
list SAY_DATA=[];//返事をする キーワード または文章として 1行で準備する
string notecard_name = "list Note";//読み込むノートカードの名前
integer MAX_count;//聞き取りの判定 キーワードの数
integer say_flag_last;//発信したフレーズ
float say_time_last;//発信した時間
float repeat_time=10.0;//同じフレーズを発信しない制限時間
integer read_line;
key query_id;
integer L_ON;//LISTENコントロール
integer flag;//動作ON-OFF
//異なるフレーズであれば 反応する
//同じフレーズであれば、 繰り返して連続しない 少しだけの間制限する
say_data(integer i ){
//llSleep(1.0); //反応を遅くしておく^^
if (say_flag_last!=i){
say_flag_last=i;
llSay(0,llList2String(SAY_DATA,i));
say_time_last=llGetTimeOfDay();
}else if(llGetTimeOfDay()-say_time_last >repeat_time){
llSay(0,llList2String(SAY_DATA,i));
say_time_last=llGetTimeOfDay();
}
}
//ノートカードの読み込み開始
load_start(){
llOwnerSay(" Now Loading..");
read_line = 0;
if (llGetInventoryType(notecard_name) == INVENTORY_NOTECARD) {
query_id = llGetNotecardLine(notecard_name, read_line); // request first line
}else{
llOwnerSay("Not found notecard '" + notecard_name );
}
}
// ノートカード読込をして準備します
default{
state_entry(){
load_start();
}
dataserver(key queryid, string data) {
if (queryid == query_id) {
if (data != EOF) {
// ここで読み取ったデータの準備・リストへ記憶します
if (read_line%2 ==0) DATA+=(list)data;
else SAY_DATA+=(list)data;
read_line ++;
query_id = llGetNotecardLine(notecard_name, read_line);
}else{
llOwnerSay("Loading complete. メモリFREE : "+ (string)llGetFreeMemory());
state main; // メイン処理を行うステートへ
}
}
}
}
//会話をLISTEN 聞き取りをします、
//読み込みデータと 一致するものが 含まれているかチェックするものです
state main{
state_entry(){
say_flag_last=-1;
say_time_last=llGetTimeOfDay();
MAX_count=llGetListLength(DATA);
flag=1;
L_ON=llListen(0,"",NULL_KEY,"");
}
//聞き取りした会話をすべてチェック作業をします
listen(integer channel, string name, key id, string msg)
{
integer i;
string TEMP;
integer NUMBER;
if (llGetAgentInfo(id)>0 ) { //アバターである==アバタは動作しているとき、ZEROではない時
for (i = 0; i < MAX_count; ++i){
TEMP=llList2String(DATA,i);
NUMBER=llSubStringIndex(msg, TEMP);
if (NUMBER>=0){
//一致するものが 含まれているものを発見した場合だけ キーワード番号=say_flag
say_data(i);
return;
}
}
}
}
touch_start(integer total_number)
{
if (llDetectedKey(0)==llGetOwner()){
flag++;
if (flag==1){
llListenControl(L_ON,TRUE);
llOwnerSay("会話:起動しました");
}else{
flag=0;
llListenControl(L_ON,FALSE);
llOwnerSay("会話:一時停止しました");
}
}
}
on_rez(integer param){llResetScript(); }
}
Posted by しんいち at 10:25│Comments(0)
│NPC会話・対応