v0.9[edit]

Note Card[edit]

ChatGPT_API_Key[edit]
sk-##########################################
ChatGPT_Model[edit]
gpt-4-turbo
ChatGPT_Charactor[edit]
貴方は美術館の説明員です.
美術の質問以外については答えてはいけません.
答えは日本語で答えます.
Appearance[edit]

Code[edit]

NSL ChatGPT for OpenSimulator[edit]
// NPC and NSL_ChatGPT Rezzer v1.1.3
//   support NSL_ChatCPT is v1.3.1
//

string  fname = "プロ生";
string  lname = "ちゃん";
string  appear_name = "ProNama_Red_Appearance";

//
// Listen
integer DEFAULT_CHANNEL = 683;
integer listen_hdl = 0;

// NPC List
integer list_stride = 3;
list npc_list = []; // [user_key, npc_key, channel] の繰り返し


// 指定したユーザがリストにあるかどうかをチェックする.
//   ユーザが存在する場合は,npc_list中の位置を返す.
//   ユーザが存在しない場合は -1 を返す
integer check_user_list(key _user_key)
{
   integer _indx = 0;
   integer _len = llGetListLength(npc_list);
   
   for(_indx=0; _indx<_len; _indx+=list_stride) {
       if (_user_key == (key)npc_list[_indx]) {
           return _indx;
       }
   } 
   return -1;
}


// 指定したNPCがリストにあるかどうかをチェックする.
//   NPCが存在する場合は,npc_list中の位置を返す.
//   NPCが存在しない場合は -1 を返す
integer check_npc_list(key _npc_key)
{
   integer _indx = 0;
   integer _len = llGetListLength(npc_list);
   
   for(_indx=0; _indx<_len; _indx+=list_stride) {
       if (_npc_key == (key)npc_list[_indx + 1]) {
           return _indx;
       }
   } 
   return -1;
}


// 指定したチャンネル番号がリストにあるかどうかをチェックする.
//   チャンネル番号が存在する場合は,npc_list中の位置を返す.
//   チャンネル番号が存在しない場合は -1 を返す
integer check_channel_list(integer _channel)
{
   integer _indx = 0;
   integer _len = llGetListLength(npc_list);
   
   for(_indx=0; _indx<_len; _indx+=list_stride) {
       if (_channel == (integer)npc_list[_indx + 2]) {
           return _indx;
       }
   } 
   return -1;
}


integer  get_valid_channel()
{
   integer _channel = DEFAULT_CHANNEL + 1;
   
   integer _indx = check_channel_list(_channel);
   while (_indx != -1) {
       _channel++;
       _indx = check_channel_list(_channel);
   }   
   return _channel;
}


// NPC の作成と NSL ChatGPT の Rez
key create_npc(key _user_key, vector _user_pos)
{
   vector _obj_pos = llGetPos();
   vector _move_to = _user_pos - llVecNorm(_user_pos - _obj_pos)*1.5; // 1.5m 手前
   float  _dist = llVecDist(_obj_pos, _move_to);
   //llRegionSayTo(_user_key, 0, "DIST = " + _dist);

   key _npc_key = NULL_KEY;
   if (_dist < 10.0) {
       // NPC 作成
       _npc_key = osNpcCreate(fname, lname, _obj_pos, appear_name, OS_NPC_SENSE_AS_AGENT);
       osNpcMoveTo(_npc_key, _move_to);
       
       // NSL_ChatGPT の Rez
       integer _channel = get_valid_channel();
       llRezObject("NSL_ChatGPT", _move_to, <0.0, 0.0, 0.0>, <0.0, 0.0, 0.0, 1.0>, _channel);
       //
       npc_list = npc_list + [_user_key, _npc_key, _channel];
   }
   else {
       llRegionSayTo(_user_key, 0, "オブジェクトから離れすぎています.10m 以内に近づいてください.");
   }
   //llOwnerSay("NPC Key = " + _npc_key + ", Channel = " + _channel);
   
   return _npc_key;
}


delete_all_npc()
{
   integer _len = llGetListLength(npc_list);
   integer _indx = 0;
   for (_indx=0; _indx<_len; _indx += list_stride) {
       key _npc_key = (key)npc_list[_indx + 1];
       osNpcRemove(_npc_key);
   }
   npc_list = [];
}


init_script()
{
   if (listen_hdl!=0) llListenRemove(listen_hdl);
   listen_hdl = llListen(DEFAULT_CHANNEL, "", NULL_KEY, "");

   delete_all_npc();
}


////////////////////////////////////////////////////////////////////////////////////////////

default
{
   state_entry()
   {
       //llSay(0, "Script running");
       init_script();
   }
   
   
   touch_start(integer _number)
   {
       key    _user_key  = llDetectedKey(0);
       string _user_name = llDetectedName(0);
       vector _user_pos  = llDetectedPos(0);
       
       integer _indx = check_user_list(_user_key);
       
       // NPC と ChatGPT を起動
       if (_indx==-1) {
           key _npc_key = create_npc(_user_key, _user_pos);
           llSleep(1.0);
           integer _num = check_npc_list(_npc_key);
           if (_num>=0) {
               integer _channel = (integer)npc_list[_num + 2];
               string  _npc_name = fname + lname;
               string  _command = "start " + _user_key + " " + _npc_key + " " + _user_name;
               llRegionSay(_channel, _command);
               //llSay(0, "Send Data to " + _channel + ": " + _command);
           }
       }
       // 既にNPCを起動している場合は,ChatGPTとNPCを削除
       else if (_indx>=0) {
           key     _npc_key = (key)npc_list[_indx + 1];
           integer _channel = (integer)npc_list[_indx + 2];
           string  _command = "stop";
           llRegionSay(_channel, _command);
           //llSay(0, "Send Data to " + _channel + ": " + _command);
           llSleep(1.0);
           osNpcRemove(_npc_key);
           npc_list = llListReplaceList(npc_list, [], _indx, _indx + list_stride - 1);
       }
   }
   
   
   listen(integer _ch, string _name, key _id, string _msg) 
   {
       //llSay(0, "Recived Message: " + _msg);
       
       list _items = llParseString2List(_msg, ["=", ",", " ", "\n"], []);       
       string _cmd = llList2String(_items, 0);
       string _opr = llList2String(_items, 1);

       if  (_cmd == "" || _cmd == " ") {
           // NOP
       }
       else if (llToLower(_cmd)=="delete" || llToLower(_cmd)=="del") {
           if (_id == llGetOwner()) {
               if (llToLower(_opr) == "all") {
                   delete_all_npc();
               }
               else {
                   key _npc_key = (key)_opr;
                   osNpcRemove(_npc_key);
                   integer _indx = check_npc_list(_npc_key);
                   if (_indx>=0) npc_list = llListReplaceList(npc_list, [], _indx, _indx + list_stride - 1);
               }
           }
       }
   }
   

   //
   on_rez(integer _start_param) 
   {
       init_script();
       llResetScript();
   }
  
   
   changed(integer _change)
   {
       //地域が再起動された場合
       if (_change & CHANGED_REGION_START) {
           init_script();
           llResetScript();
       }
       else if (_change & CHANGED_INVENTORY) {
           init_script();
           llResetScript();
       }   
   }                
}
NPC and NSL_ChatGPT Rezzer[edit]
// NPC and NSL_ChatGPT Rezzer v1.1.3
//   support NSL_ChatCPT is v1.3.1
//

string  fname = "プロ生";
string  lname = "ちゃん";
string  appear_name = "ProNama_Red_Appearance";

//
// Listen
integer DEFAULT_CHANNEL = 683;
integer listen_hdl = 0;

// NPC List
integer list_stride = 3;
list npc_list = []; // [user_key, npc_key, channel] の繰り返し


// 指定したユーザがリストにあるかどうかをチェックする.
//   ユーザが存在する場合は,npc_list中の位置を返す.
//   ユーザが存在しない場合は -1 を返す
integer check_user_list(key _user_key)
{
   integer _indx = 0;
   integer _len = llGetListLength(npc_list);
   
   for(_indx=0; _indx<_len; _indx+=list_stride) {
       if (_user_key == (key)npc_list[_indx]) {
           return _indx;
       }
   } 
   return -1;
}


// 指定したNPCがリストにあるかどうかをチェックする.
//   NPCが存在する場合は,npc_list中の位置を返す.
//   NPCが存在しない場合は -1 を返す
integer check_npc_list(key _npc_key)
{
   integer _indx = 0;
   integer _len = llGetListLength(npc_list);
   
   for(_indx=0; _indx<_len; _indx+=list_stride) {
       if (_npc_key == (key)npc_list[_indx + 1]) {
           return _indx;
       }
   } 
   return -1;
}


// 指定したチャンネル番号がリストにあるかどうかをチェックする.
//   チャンネル番号が存在する場合は,npc_list中の位置を返す.
//   チャンネル番号が存在しない場合は -1 を返す
integer check_channel_list(integer _channel)
{
   integer _indx = 0;
   integer _len = llGetListLength(npc_list);
   
   for(_indx=0; _indx<_len; _indx+=list_stride) {
       if (_channel == (integer)npc_list[_indx + 2]) {
           return _indx;
       }
   } 
   return -1;
}


integer  get_valid_channel()
{
   integer _channel = DEFAULT_CHANNEL + 1;
   
   integer _indx = check_channel_list(_channel);
   while (_indx != -1) {
       _channel++;
       _indx = check_channel_list(_channel);
   }   
   return _channel;
}


// NPC の作成と NSL ChatGPT の Rez
key create_npc(key _user_key, vector _user_pos)
{
   vector _obj_pos = llGetPos();
   vector _move_to = _user_pos - llVecNorm(_user_pos - _obj_pos)*1.5; // 1.5m 手前
   float  _dist = llVecDist(_obj_pos, _move_to);
   //llRegionSayTo(_user_key, 0, "DIST = " + _dist);

   key _npc_key = NULL_KEY;
   if (_dist < 10.0) {
       // NPC 作成
       _npc_key = osNpcCreate(fname, lname, _obj_pos, appear_name, OS_NPC_SENSE_AS_AGENT);
       osNpcMoveTo(_npc_key, _move_to);
       
       // NSL_ChatGPT の Rez
       integer _channel = get_valid_channel();
       llRezObject("NSL_ChatGPT", _move_to, <0.0, 0.0, 0.0>, <0.0, 0.0, 0.0, 1.0>, _channel);
       //
       npc_list = npc_list + [_user_key, _npc_key, _channel];
   }
   else {
       llRegionSayTo(_user_key, 0, "オブジェクトから離れすぎています.10m 以内に近づいてください.");
   }
   //llOwnerSay("NPC Key = " + _npc_key + ", Channel = " + _channel);
   
   return _npc_key;
}


delete_all_npc()
{
   integer _len = llGetListLength(npc_list);
   integer _indx = 0;
   for (_indx=0; _indx<_len; _indx += list_stride) {
       key _npc_key = (key)npc_list[_indx + 1];
       osNpcRemove(_npc_key);
   }
   npc_list = [];
}


init_script()
{
   if (listen_hdl!=0) llListenRemove(listen_hdl);
   listen_hdl = llListen(DEFAULT_CHANNEL, "", NULL_KEY, "");

   delete_all_npc();
}


////////////////////////////////////////////////////////////////////////////////////////////

default
{
   state_entry()
   {
       //llSay(0, "Script running");
       init_script();
   }
   
   
   touch_start(integer _number)
   {
       key    _user_key  = llDetectedKey(0);
       string _user_name = llDetectedName(0);
       vector _user_pos  = llDetectedPos(0);
       
       integer _indx = check_user_list(_user_key);
       
       // NPC と ChatGPT を起動
       if (_indx==-1) {
           key _npc_key = create_npc(_user_key, _user_pos);
           llSleep(1.0);
           integer _num = check_npc_list(_npc_key);
           if (_num>=0) {
               integer _channel = (integer)npc_list[_num + 2];
               string  _npc_name = fname + lname;
               string  _command = "start " + _user_key + " " + _npc_key + " " + _user_name;
               llRegionSay(_channel, _command);
               //llSay(0, "Send Data to " + _channel + ": " + _command);
           }
       }
       // 既にNPCを起動している場合は,ChatGPTとNPCを削除
       else if (_indx>=0) {
           key     _npc_key = (key)npc_list[_indx + 1];
           integer _channel = (integer)npc_list[_indx + 2];
           string  _command = "stop";
           llRegionSay(_channel, _command);
           //llSay(0, "Send Data to " + _channel + ": " + _command);
           llSleep(1.0);
           osNpcRemove(_npc_key);
           npc_list = llListReplaceList(npc_list, [], _indx, _indx + list_stride - 1);
       }
   }
   
   
   listen(integer _ch, string _name, key _id, string _msg) 
   {
       //llSay(0, "Recived Message: " + _msg);
       
       list _items = llParseString2List(_msg, ["=", ",", " ", "\n"], []);       
       string _cmd = llList2String(_items, 0);
       string _opr = llList2String(_items, 1);

       if  (_cmd == "" || _cmd == " ") {
           // NOP
       }
       else if (llToLower(_cmd)=="delete" || llToLower(_cmd)=="del") {
           if (_id == llGetOwner()) {
               if (llToLower(_opr) == "all") {
                   delete_all_npc();
               }
               else {
                   key _npc_key = (key)_opr;
                   osNpcRemove(_npc_key);
                   integer _indx = check_npc_list(_npc_key);
                   if (_indx>=0) npc_list = llListReplaceList(npc_list, [], _indx, _indx + list_stride - 1);
               }
           }
       }
   }
   

   //
   on_rez(integer _start_param) 
   {
       init_script();
       llResetScript();
   }
  
   
   changed(integer _change)
   {
       //地域が再起動された場合
       if (_change & CHANGED_REGION_START) {
           init_script();
           llResetScript();
       }
       else if (_change & CHANGED_INVENTORY) {
           init_script();
           llResetScript();
       }   
   }                
}

トップ   新規 ページ一覧 検索 最終更新   ヘルプ   最終更新のRSS