2011/02/06
今更だけど文字盤のスクリプト晒し
ずっと昔に作ったプリムに文字を表示できるスクリプトを
ろくに修正もせずにそのまま展開してみる。
ごり押しコードだらけでかなり汚いけど
よかったらどうぞ。
記事を書いてから気づいたけど
このままじゃ使えないので
後でHowToの記事を書くことにする
(来月からがんばる)
*使い方
プリズムに入れて使う
パスカット
B:0.167
E:0.833
integer linknum = 0;// 下のスクリプトへのリンクナンバー;
integer num = 0; // 使わないよ
string str = ""; // 表示した文字(4文字まで表示)
id = NULL_KEY; // 使わないよ
llMessageLinked(linknum, num, str, id);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
key texture;
integer dec;
list fasenum = [3,6,5,1];
list fasescl = [2,1,1,2];
list fasepos = [0.016,0,0,-0.016];
// 2Byte文字用テクスチャUUID配列
list Texture2Byte = ["c96fda26-86fa-e64e-b86f-041c904dd9f1","ae73807e-7d8d-f15c-4abb-fd613cef707f"];
// 3Byte文字用テクスチャUUID配列
list Texture3Byte = ["","","","",
"","","","",
"81e306ae-4845-c246-48c8-fd9743471006","caf5fb2b-6c46-f8d2-14e5-b2f7522190c1","","",
"c94ba00b-88c5-7834-e717-dedbba800213","","","",
"","","","5ea3c586-1af9-d3c6-ed6b-591e07b13c60",
"c1c446e7-b362-bcbd-4190-fa8b38ef9b3a","acefd0f1-44a6-1311-9cd6-a35dbbf5c261","c719e75d-2cb8-74b8-cb0e-e0de0089244d","3c7b449d-91ae-c60a-4ed3-6df1944a1290",
"f91ae719-24ea-b558-2c0b-1c052a53c05e","93e375b9-6f47-8c80-09e1-7203ff97a748","362dd4da-e33c-0891-2b84-fb9fff65fdc6","9bd48f7a-1ec3-44c1-fb34-7f81bf5c6702",
"8c7a98f2-6399-c6da-b048-86afa8081e06","a9c12e7d-339e-4e9b-a424-b8865347e9bf","4b0a4060-cf23-f84c-9fad-c211d0a4e135","71a6bbeb-3b8b-9918-4081-a35350cb816b",
"9ec1ff5b-4c9f-c287-a88e-5fddb1373a31","82c1f5e0-f63e-b159-dba3-3e2af9ff3f71","144f6a43-479f-61d8-0620-4221140ce530","2d6dbc34-a9cd-1914-3f99-d039e536c15f",
"b2aeab51-3a5a-f6c9-23e5-56e2bbcc090c","a3fc6e50-9b01-8868-1016-ad0a08635bc6","c1c43d99-0606-3c09-c440-975803a9295a","7a1eee1c-6091-4998-0946-9eac3ff18278",
"","","","",
"","","","",
"","","","",
"","","","",
"","","","",
"a6b77d55-fecb-2d1e-0232-3b76ec335bd3","","0039ac1f-a050-6b4d-a0ea-5b5caae1f9a8","466d8eff-6370-56df-ae43-992164445c03"];
// エスケープ文字を10進数integerに変換
integer Esc2Dec(string Esc){
string hex = "";
integer Loop;
integer SLength = llStringLength(Esc);
for(Loop=0;Loop<SLength/3;Loop++){
hex += llGetSubString(Esc,3*Loop+1,3*Loop+2);
}
return (integer)("0x"+hex);
}
default
{
link_message(integer sender_num, integer num, string message, key id)
{
integer word4Loop;
for(word4Loop = 0 ; word4Loop < 4 ; word4Loop ++){
//文字を取得
string Char = llGetSubString(message,word4Loop,word4Loop);
//文字をEscape
string EscapeWord = llEscapeURL(Char);
//Escape文字の長さを取得
integer EscLength = llStringLength(EscapeWord);
dec = Esc2Dec(EscapeWord);
integer offx = 0;
integer offy = 0;
if(EscLength<=3){
if(EscLength == 1){
string alphabet = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
integer AlphabetIndex = llSubStringIndex(alphabet, Char);
if(AlphabetIndex <= 0){
dec = 0;
}else if(37 <= AlphabetIndex){
dec = AlphabetIndex + 60;//28
}else if(11 <= AlphabetIndex){
dec = AlphabetIndex + 54;//67 56
}else{
dec = AlphabetIndex + 47;
}
}
// 1Byte文字用テクスチャUUID
texture = "e1677552-04f7-821b-4eb2-b762101fed53";
offx = dec & 31;
offy = (dec & 96)>>5;
}else if(EscLength==6){
integer BitIndex = (dec & 4096)>>12;
texture = llList2Key(Texture2Byte,BitIndex);
offx = 31&dec;
offy = (3840&dec>>7)|(32&dec >>5);
}else if(EscLength==9){
integer BitIndex = ((dec & 12288)>>12) | ((dec & 983040)>>14);
texture = llList2Key(Texture3Byte,BitIndex);
offx = 31&dec;
offy = ((3840&dec)>>7)|((32&dec) >>5);
}
// 1列に配置される文字数からテクスチャの繰り返し値を割り出す
float repeatx = (float)1 / 32;
// 1行に配置される文字(略
float repeaty = (float)1 / 32;
// 先頭文字へテクスチャをずらす
float DefOffX = -1 * (0.5 - repeatx/2);
float DefOffY = 0.5 - repeaty/2;
float xscale = repeatx * llList2Float(fasescl,word4Loop);
llSetPrimitiveParams(
[PRIM_TEXTURE,llList2Integer(fasenum,word4Loop),texture,<xscale ,repeaty,0>
,<DefOffX + repeatx * offx + llList2Float(fasepos,word4Loop) , DefOffY - repeaty * offy,0>,0]);
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2010/10/21
2010/10/20
2009/12/17
黒板っぽい何か
最近どうもセカンドライフでの制作意欲が出ないので
過去に俺が作ったスクリプトを晒してみる
プリムの上へ複数人同時にお絵かきが出来るスクリプト
とても汚いです
方向ベクトル⇒オイラー角の計算とかかなり強引
// ******** プリムとスクリプトの構成 ********
・板(プリム)
├ メインスクリプト
├ 子スクリプト
└ 線(プリム)
└ 線のスクリプト
・線消し
└ 線消しスクリプト
// ******** 板:メインスクリプト ********
integer giLinkNum;
integer giLinkNumMax = 20;
list glName;
list glVector;
integer MAX_PRIM = 5000;
integer ERASE_CHANNEL = 2131000;
integer gRezCount;
// ** 2点間にプリムを使って線を引く
// vector _vFrom Move
// vector _vTo To
rezline( vector _vFrom,vector _vTo)
{
vector vLineLength = _vTo - _vFrom;
vector vRezPos = _vFrom +(vLineLength/2);
// ** From - To から回転値を求める
vector vRezRotation = <llAtan2(vLineLength.z,vLineLength.y) ,0 ,0 >;
vRezRotation.z = llAtan2(
llSqrt(llPow(vLineLength.z,2)+llPow(vLineLength.y,2)),
vLineLength.x
);
if(vRezRotation.x < 0) vRezRotation.x += 2*PI;
if(MAX_PRIM > gRezCount) // 現在のRezしたプリムのカウントが許容範囲を下回っていた場合
{
// ** 線を引く子スクリプトにメッセージを送る
// 1: 送り先
// 2: 引く線の長さ+メッセージリンク受信判断
// 3: 線をRezする位置
// 4: 回転
llMessageLinked(
LINK_THIS, // 1:
llFloor(llVecMag(vLineLength)*100+1)*giLinkNumMax + (giLinkNum = ++giLinkNum % giLinkNumMax), // 2:
(string)vRezPos, // 3:
(key)((string)llEuler2Rot(vRezRotation)) // 4:
);
}
// ** Rezしたプリムのカウントを増やす
++gRezCount;
}
// ** プリムのカウントを更新
reloadPrimCount()
{
llSetText("現在のプリム: "+(string)gRezCount+"/"+(string)MAX_PRIM,<1,1,1>,1);
}
// ** エラーメッセージ
error(key _kTarget)
{
llInstantMessage(_kTarget, "RC 1.21.0以上のセカンドライフクライアントで使用してください。");
}
default
{
state_entry()
{
reloadPrimCount();
llListen(ERASE_CHANNEL, "", NULL_KEY, "");
}
on_rez(integer n){llResetScript();}
listen(integer _channel, string _name, key _key, string _message){llSleep(10.0);reloadPrimCount();}
touch_start(integer _iDispatchAgentCount)
{
reloadPrimCount();
integer i;
for(i = 0 ; i < _iDispatchAgentCount ; i++)
{
if(llDetectedTouchPos(i) != ZERO_VECTOR)
{
if(llListFindList(glName, [llDetectedKey(i)]) == -1)
{
if(MAX_PRIM > gRezCount)
{
glName += llDetectedKey(i);
glVector += llDetectedTouchPos(i);
}
else
{
llWhisper(0, "プリム数が限界なので一回消してね!");
}
}
}
else // クライアントがllDetectedTouchPos関数をサポートしていない
{
error(llDetectedKey(i));
}
}
}
touch(integer _iDispatchAgentCount)
{
integer i;
for(i = 0 ; i < _iDispatchAgentCount ; i++) // 複数のキャラクターが同時にタッチした場合の処理
{
integer iFoundIndex = llListFindList(glName,[llDetectedKey(i)]);
vector vTouchPos = llDetectedTouchPos(i);
if(iFoundIndex >= 0)
{
rezline(llList2Vector(glVector, iFoundIndex),vTouchPos);
glVector = llListReplaceList(glVector, [vTouchPos], iFoundIndex, iFoundIndex);
}
else if( vTouchPos == ZERO_VECTOR) // クライアントがllDetectedTouchPos関数をサポートしていない
{
error(llDetectedKey(i));
}
else
{
if(MAX_PRIM > gRezCount){
glName += llDetectedKey(i);
glVector += vTouchPos;
}
}
}
}
touch_end(integer _iDispatchAgentCount)
{
reloadPrimCount();
integer i;
for(i = 0 ; i < _iDispatchAgentCount ; i++)
{
integer iFoundIndex = llListFindList(glName,[llDetectedKey(i)]);
if(iFoundIndex >= 0)
{
rezline(llList2Vector(glVector,iFoundIndex),llDetectedTouchPos(i));
glName = llDeleteSubList(glName, iFoundIndex,iFoundIndex);
glVector = llDeleteSubList(glVector, iFoundIndex,iFoundIndex);
}
}
}
}
// ******** 板:子スクリプト ********
// ** SIMの処理能力と相談しながらスクリプト自体を増やして
// ** 増やした数だけPIPE_COUNTを書き換えてね。
string PRIM_NAME = "※線になるプリム";
integer PIPE_COUNT = 10;
default
{
link_message(integer _iSender, integer _iNum, string _sStr, key _iId)
{
if(_iNum % PIPE_COUNT == 0)
llRezObject("RezBox2", (vector)_sStr, ZERO_VECTOR, (rotation)((string)_iId), _iNum/20);
}
}
// ******** 線:線のスクリプト ********
default
{
on_rez(integer n)
{
llSetScale(<(float)n/100,0.01,0.01>);
integer zn = (integer)llFrand(200);
llListen(2131000 + n,"",NULL_KEY,"");
}
listen(integer a,string b,key c,string d)
{
llDie();
}
}
// ******** 線消し:線消しスクリプト ********
default
{
state_entry()
{
llSetText("消し",<1,1,1>,1);
}
touch_start(integer total_number)
{
llWhisper(0,llDetectedName(0)+"が全消ししたよ");
integer i;
for(i = 0 ; i < 200 ; ){
if(llGetRegionTimeDilation() < 1){
//llOwnerSay((string)llGetRegionTimeDilation());
}else{
llSleep(0.003);
llWhisper(2131000 + i, "Touched.");
i++;
}
}
}
}
過去に俺が作ったスクリプトを晒してみる
プリムの上へ複数人同時にお絵かきが出来るスクリプト
とても汚いです
方向ベクトル⇒オイラー角の計算とかかなり強引
// ******** プリムとスクリプトの構成 ********
・板(プリム)
├ メインスクリプト
├ 子スクリプト
└ 線(プリム)
└ 線のスクリプト
・線消し
└ 線消しスクリプト
// ******** 板:メインスクリプト ********
integer giLinkNum;
integer giLinkNumMax = 20;
list glName;
list glVector;
integer MAX_PRIM = 5000;
integer ERASE_CHANNEL = 2131000;
integer gRezCount;
// ** 2点間にプリムを使って線を引く
// vector _vFrom Move
// vector _vTo To
rezline( vector _vFrom,vector _vTo)
{
vector vLineLength = _vTo - _vFrom;
vector vRezPos = _vFrom +(vLineLength/2);
// ** From - To から回転値を求める
vector vRezRotation = <llAtan2(vLineLength.z,vLineLength.y) ,0 ,0 >;
vRezRotation.z = llAtan2(
llSqrt(llPow(vLineLength.z,2)+llPow(vLineLength.y,2)),
vLineLength.x
);
if(vRezRotation.x < 0) vRezRotation.x += 2*PI;
if(MAX_PRIM > gRezCount) // 現在のRezしたプリムのカウントが許容範囲を下回っていた場合
{
// ** 線を引く子スクリプトにメッセージを送る
// 1: 送り先
// 2: 引く線の長さ+メッセージリンク受信判断
// 3: 線をRezする位置
// 4: 回転
llMessageLinked(
LINK_THIS, // 1:
llFloor(llVecMag(vLineLength)*100+1)*giLinkNumMax + (giLinkNum = ++giLinkNum % giLinkNumMax), // 2:
(string)vRezPos, // 3:
(key)((string)llEuler2Rot(vRezRotation)) // 4:
);
}
// ** Rezしたプリムのカウントを増やす
++gRezCount;
}
// ** プリムのカウントを更新
reloadPrimCount()
{
llSetText("現在のプリム: "+(string)gRezCount+"/"+(string)MAX_PRIM,<1,1,1>,1);
}
// ** エラーメッセージ
error(key _kTarget)
{
llInstantMessage(_kTarget, "RC 1.21.0以上のセカンドライフクライアントで使用してください。");
}
default
{
state_entry()
{
reloadPrimCount();
llListen(ERASE_CHANNEL, "", NULL_KEY, "");
}
on_rez(integer n){llResetScript();}
listen(integer _channel, string _name, key _key, string _message){llSleep(10.0);reloadPrimCount();}
touch_start(integer _iDispatchAgentCount)
{
reloadPrimCount();
integer i;
for(i = 0 ; i < _iDispatchAgentCount ; i++)
{
if(llDetectedTouchPos(i) != ZERO_VECTOR)
{
if(llListFindList(glName, [llDetectedKey(i)]) == -1)
{
if(MAX_PRIM > gRezCount)
{
glName += llDetectedKey(i);
glVector += llDetectedTouchPos(i);
}
else
{
llWhisper(0, "プリム数が限界なので一回消してね!");
}
}
}
else // クライアントがllDetectedTouchPos関数をサポートしていない
{
error(llDetectedKey(i));
}
}
}
touch(integer _iDispatchAgentCount)
{
integer i;
for(i = 0 ; i < _iDispatchAgentCount ; i++) // 複数のキャラクターが同時にタッチした場合の処理
{
integer iFoundIndex = llListFindList(glName,[llDetectedKey(i)]);
vector vTouchPos = llDetectedTouchPos(i);
if(iFoundIndex >= 0)
{
rezline(llList2Vector(glVector, iFoundIndex),vTouchPos);
glVector = llListReplaceList(glVector, [vTouchPos], iFoundIndex, iFoundIndex);
}
else if( vTouchPos == ZERO_VECTOR) // クライアントがllDetectedTouchPos関数をサポートしていない
{
error(llDetectedKey(i));
}
else
{
if(MAX_PRIM > gRezCount){
glName += llDetectedKey(i);
glVector += vTouchPos;
}
}
}
}
touch_end(integer _iDispatchAgentCount)
{
reloadPrimCount();
integer i;
for(i = 0 ; i < _iDispatchAgentCount ; i++)
{
integer iFoundIndex = llListFindList(glName,[llDetectedKey(i)]);
if(iFoundIndex >= 0)
{
rezline(llList2Vector(glVector,iFoundIndex),llDetectedTouchPos(i));
glName = llDeleteSubList(glName, iFoundIndex,iFoundIndex);
glVector = llDeleteSubList(glVector, iFoundIndex,iFoundIndex);
}
}
}
}
// ******** 板:子スクリプト ********
// ** SIMの処理能力と相談しながらスクリプト自体を増やして
// ** 増やした数だけPIPE_COUNTを書き換えてね。
string PRIM_NAME = "※線になるプリム";
integer PIPE_COUNT = 10;
default
{
link_message(integer _iSender, integer _iNum, string _sStr, key _iId)
{
if(_iNum % PIPE_COUNT == 0)
llRezObject("RezBox2", (vector)_sStr, ZERO_VECTOR, (rotation)((string)_iId), _iNum/20);
}
}
// ******** 線:線のスクリプト ********
default
{
on_rez(integer n)
{
llSetScale(<(float)n/100,0.01,0.01>);
integer zn = (integer)llFrand(200);
llListen(2131000 + n,"",NULL_KEY,"");
}
listen(integer a,string b,key c,string d)
{
llDie();
}
}
// ******** 線消し:線消しスクリプト ********
default
{
state_entry()
{
llSetText("消し",<1,1,1>,1);
}
touch_start(integer total_number)
{
llWhisper(0,llDetectedName(0)+"が全消ししたよ");
integer i;
for(i = 0 ; i < 200 ; ){
if(llGetRegionTimeDilation() < 1){
//llOwnerSay((string)llGetRegionTimeDilation());
}else{
llSleep(0.003);
llWhisper(2131000 + i, "Touched.");
i++;
}
}
}
}




