時間の針、分の針、秒の針のプリム名をそれぞれ
"_hour" "_min" "_sec" として以下のスクリプトを実行するとSLから時間をとってきてアナログ時刻表示します
(回転中心軸を合わせるなどはしてある前提)
タッチしてSL時間との差分を設定できますので、日本時間のアナログ表示も可能です。
(Date機能はありません。24時管理はしていません。)
/*
Clock Script
Written by Esforco
Please set child object name this one.
hour objectname = "_hour"
min objectname = "_min"
sec objectname = "_sec"
*/
integer rot_dir = -1; // or -1
rotation rootRot;
rotation hourRot;
rotation minRot;
rotation secRot;
list prim_list = [];
integer hour_hand_link_num;
integer min_hand_link_num;
integer sec_hand_link_num;
integer pst_hour = 0;
integer pst_min = 0;
integer pst_sec = 0;
float hourRot_FloatVal = 0.0;
float minRot_FloatVal = 0.0;
float secRot_FloatVal = 0.0;
float pre_hourRot_FloatVal;
float pre_minRot_FloatVal;
float pre_secRot_FloatVal;
key avatarKey = NULL_KEY;
integer dlg_channel = 0;
integer handle_dlg = -1;
float DIALOG_TIME_OUT = 30.0;
float time_dlg_rate = DIALOG_TIME_OUT;
string language = "English";
list mode_list = ["[Hour]", "[Min]"];
integer mode_index = 0;
string button_blank_char = "-";
integer offset_hour = 0; // ユーザー調整時間 (時)
integer offset_min = 0; // ユーザー調整時間 (分)
integer offset_hour_temp = 0; // 時刻調整中の調整時間 (時)
integer offset_min_temp = 0; // 時刻調整中のユーザー調整時間 (分)
// Prim List 作成
createIndex()
{
prim_list = [];
integer i;
prim_list = [""]; // ルート ( 1 : 起算 )
prim_list += [llGetObjectName()];
for(i = 2; i <= llGetNumberOfPrims() ; i++)
{
string prim_name = llGetLinkName(i);
prim_list += [prim_name];
}
}
// Prim Nmae から インデックス を返す
integer getIndex(string prim_name)
{
return llListFindList(prim_list, [prim_name]);
}
integer genCh()
{
integer gen;
string str = llGetSubString((string)llGetKey(),0,3);
gen = -1-(integer)("0x"+str);
return gen;
}
// 時針を指定角度移動
set_rot_hour_hand(float rot_val)
{
float rot = rot_val - pre_hourRot_FloatVal;
if(rot >= 360)
{
rot -= 360;
}
hourRot = llList2Rot(llGetLinkPrimitiveParams(hour_hand_link_num,[PRIM_ROT_LOCAL]),0);
vector targetEluer= DEG_TO_RAD*<0.0,0.0,rot * rot_dir>;
rotation targetQ = llEuler2Rot(targetEluer);
rootRot = targetQ * hourRot;
llSetLinkPrimitiveParams(hour_hand_link_num,[PRIM_ROT_LOCAL,rootRot]);
llMessageLinked(LINK_SET,10,"","");
pre_hourRot_FloatVal = rot_val;
}
// 分針を指定角度移動
set_rot_min_hand(float rot_val)
{
float rot = rot_val - pre_minRot_FloatVal;
if(rot >= 360)
{
rot -= 360;
}
//llSay(0, "min rot : " + (string)rot);
minRot = llList2Rot(llGetLinkPrimitiveParams(min_hand_link_num,[PRIM_ROT_LOCAL]),0);
vector targetEluer= DEG_TO_RAD*<0.0,0.0,rot * rot_dir>;
rotation targetQ = llEuler2Rot(targetEluer);
rootRot = targetQ * minRot;
llSetLinkPrimitiveParams(min_hand_link_num,[PRIM_ROT_LOCAL,rootRot]);
llMessageLinked(LINK_SET,11,"","");
pre_minRot_FloatVal = rot_val;
}
// 秒針を指定角度移動
set_rot_sec_hand(float rot_val)
{
float rot = rot_val - pre_secRot_FloatVal;
if(rot >= 360)
{
rot -= 360;
}
//llSay(0, "min rot : " + (string)rot);
secRot = llList2Rot(llGetLinkPrimitiveParams(sec_hand_link_num,[PRIM_ROT_LOCAL]),0);
vector targetEluer= DEG_TO_RAD*<0.0,0.0,rot * rot_dir>;
rotation targetQ = llEuler2Rot(targetEluer);
rootRot = targetQ * secRot;
llSetLinkPrimitiveParams(sec_hand_link_num,[PRIM_ROT_LOCAL,rootRot]);
llMessageLinked(LINK_SET,12,"","");
pre_secRot_FloatVal = rot_val;
}
// 指定時間に時計の針を動かす
set_time(integer in_hour, integer in_min, integer in_sec)
{
integer hour = in_hour + offset_hour + offset_hour_temp;
integer min = in_min + offset_min + offset_min_temp;
integer sec = in_sec;
// 24 時制 を 12 時間に置き換え
if(min >= 60)
{
min -= 60;
hour += 1;
}
if(hour >= 12)
{
hour -= 12;
}
if(min < 0)
{
min += 60;
hour -= 1;
}
if(hour < 0)
{
hour += 12;
}
// Hour の角度計算
float rot_by_1_hour = 30.0;// 360 ÷ 12;
float rot_by_1_min_for_hour = 0.5;//rot_by_1_hour ÷ 60;
hourRot_FloatVal = (float)hour * rot_by_1_hour + (float)min * rot_by_1_min_for_hour;
// Min の角度計算
float rot_by_1_min = 6.0; // 360 ÷ 60
minRot_FloatVal = (float)min * rot_by_1_min;
// Sec の角度計算
float rot_by_1_sec = 6.0; // 360 ÷ 60
secRot_FloatVal = (float)sec * rot_by_1_sec;
// 時計の針を動かす
set_rot_sec_hand(secRot_FloatVal);
set_rot_min_hand(minRot_FloatVal);
set_rot_hour_hand(hourRot_FloatVal);
}
// 初期化
init()
{
llSetLinkPrimitiveParams(hour_hand_link_num,[PRIM_ROT_LOCAL,rootRot]);
llSetLinkPrimitiveParams(min_hand_link_num,[PRIM_ROT_LOCAL,rootRot]);
llSetLinkPrimitiveParams(sec_hand_link_num,[PRIM_ROT_LOCAL,rootRot]);
}
// SL 時間の取得
get_PST_time()
{
string utc_time = llGetTimestamp();
list tokens = llParseString2List (utc_time, ["T"], []);
list times = llParseString2List (llList2String(tokens,1), [":"], []);
pst_hour = (integer)llList2Integer(times,0) - 8; // UTC 時間から 8 時間遅らせる
pst_min = (integer)llList2Integer(times,1);
pst_sec = (integer)llList2Integer(times,2);
if(pst_hour < 0) pst_hour+=12;
// PST Time をチャットに表示
//llOwnerSay((string)now_hour + ":"+(string)now_min + ":"+(string)now_sec);
}
do_clock()
{
//init();
// 現在時刻の取得
get_PST_time();
// 時刻表示
set_time(pst_hour, pst_min, pst_sec);
}
// 時刻合わせ設定ダイアログを開く
setting_clock_dlg(key av, string mode)
{
string message;
if(language == "English")
{
message = "\n\n\Time adjustment Setting\n";
}
else
{
message = "\n\n\時刻合わせ 設定\n";
}
integer hour = pst_hour + offset_hour + offset_hour_temp;
integer min = pst_min + offset_min + offset_min_temp;
// 24 時制 を 12 時間に置き換え
if(min >= 60)
{
min -= 60;
hour += 1;
}
if(hour >= 12)
{
hour -= 12;
}
if(min < 0)
{
min += 60;
hour -= 1;
}
if(hour < 0)
{
hour += 12;
}
string hour_str = (string)hour;
string min_str = (string)min;
if(llStringLength(hour_str) == 1)
{
hour_str = "0" + hour_str;
}
if(llStringLength(min_str) == 1)
{
min_str = "0" + min_str;
}
message += "\n"+ hour_str + " : " + min_str;
list buttons = [
"OK", button_blank_char, "Cancel",
"-1","-5","-10",
"+1","+5","+10",
mode, button_blank_char, "Reset"];
llDialog(av,message, buttons, dlg_channel);
buttons = []; // 解放的な
time_dlg_rate = DIALOG_TIME_OUT;
}
// 時刻合わせ中の Offset 時間を適正値にする
check_offset_temp_time()
{
if(offset_min_temp >= 60)
{
offset_min_temp -= 60;
}
if(offset_hour_temp >= 12)
{
offset_hour_temp -= 12;
}
if(offset_min_temp < 0)
{
offset_min_temp += 60;
}
if(offset_hour_temp < 0)
{
offset_hour_temp += 12;
}
}
// Offset 時間を適正値にする
check_offset_time()
{
if(offset_min >= 60)
{
offset_min -= 60;
offset_hour += 1;
}
if(offset_hour >= 12)
{
offset_hour -= 12;
}
if(offset_min < 0)
{
offset_min += 60;
offset_hour -= 1;
}
if(offset_hour < 0)
{
offset_hour += 12;
}
}
default
{
state_entry()
{
createIndex();
hour_hand_link_num = getIndex("_hour");
min_hand_link_num = getIndex("_min");
sec_hand_link_num = getIndex("_sec");
rootRot = ZERO_ROTATION;
dlg_channel = genCh();
init();
// 現在時刻の取得
get_PST_time();
// 時刻表示
set_time(pst_hour, pst_min, pst_sec);
llSetTimerEvent(1.0);
}
timer()
{
do_clock();
time_dlg_rate -= 1.0;
if(time_dlg_rate <= 0.0 && handle_dlg != -1)
{
llListenRemove(handle_dlg);
avatarKey = NULL_KEY;
handle_dlg = -1;
//llOwnerSay("Timer handle_dlg : " + (string)handle_dlg);
}
}
touch_start(integer total_number)
{
// オーナーであれば
if(llDetectedKey(0) == llGetOwner())
{
avatarKey = llDetectedKey(0);
if(handle_dlg == -1)
{
// 時刻合わせダイアログの表示
handle_dlg = llListen(dlg_channel,"",avatarKey,"");
//llOwnerSay("handle_dlg : " + (string)handle_dlg);
setting_clock_dlg(avatarKey, llList2String(mode_list, mode_index));
}
}
}
listen(integer channel, string name, key id, string message)
{
if(llGetOwnerKey(id) != llGetOwner()) return;
if(channel == dlg_channel)
{
if(message == "OK")
{
offset_hour += offset_hour_temp;
offset_min += offset_min_temp;
check_offset_time();
offset_hour_temp = 0;
offset_min_temp = 0;
llListenRemove(handle_dlg);
avatarKey = NULL_KEY;
handle_dlg = -1;
}
else if(message == "Cancel")
{
offset_hour_temp = 0;
offset_min_temp = 0;
llListenRemove(handle_dlg);
avatarKey = NULL_KEY;
handle_dlg = -1;
}
else if(message == "Reset")
{
llResetScript();
/*
offset_hour_temp = 0;
offset_min_temp = 0;
offset_hour = 0;
offset_min = 0;
do_clock();
// 時刻合わせダイアログを開く
setting_clock_dlg(avatarKey, llList2String(mode_list, mode_index));
*/
}
else if(message == button_blank_char)
{
llListenRemove(handle_dlg);
avatarKey = NULL_KEY;
handle_dlg = -1;
}
else if(message == "+1")
{
if("[Hour]" == llList2String(mode_list, mode_index))
{
offset_hour_temp += 1;
}
else if("[Min]" == llList2String(mode_list, mode_index))
{
offset_min_temp += 1;
}
check_offset_temp_time();
do_clock();
// 時刻合わせダイアログを開く
setting_clock_dlg(avatarKey, llList2String(mode_list, mode_index));
}
else if(message == "+5")
{
if("[Hour]" == llList2String(mode_list, mode_index))
{
offset_hour_temp += 5;
}
else if("[Min]" == llList2String(mode_list, mode_index))
{
offset_min_temp += 5;
}
check_offset_temp_time();
do_clock();
// 時刻合わせダイアログを開く
setting_clock_dlg(avatarKey, llList2String(mode_list, mode_index));
}
else if(message == "+10")
{
if("[Hour]" == llList2String(mode_list, mode_index))
{
offset_hour_temp += 10;
}
else if("[Min]" == llList2String(mode_list, mode_index))
{
offset_min_temp += 10;
}
check_offset_temp_time();
do_clock();
// 時刻合わせダイアログを開く
setting_clock_dlg(avatarKey, llList2String(mode_list, mode_index));
}
else if(message == "-1")
{
if("[Hour]" == llList2String(mode_list, mode_index))
{
offset_hour_temp -= 1;
}
else if("[Min]" == llList2String(mode_list, mode_index))
{
offset_min_temp -= 1;
}
check_offset_temp_time();
do_clock();
// 時刻合わせダイアログを開く
setting_clock_dlg(avatarKey, llList2String(mode_list, mode_index));
}
else if(message == "-5")
{
if("[Hour]" == llList2String(mode_list, mode_index))
{
offset_hour_temp -= 5;
}
else if("[Min]" == llList2String(mode_list, mode_index))
{
offset_min_temp -= 5;
}
check_offset_temp_time();
do_clock();
// 時刻合わせダイアログを開く
setting_clock_dlg(avatarKey, llList2String(mode_list, mode_index));
}
else if(message == "-10")
{
if("[Hour]" == llList2String(mode_list, mode_index))
{
offset_hour_temp -= 10;
}
else if("[Min]" == llList2String(mode_list, mode_index))
{
offset_min_temp -= 10;
}
check_offset_temp_time();
do_clock();
// 時刻合わせダイアログを開く
setting_clock_dlg(avatarKey, llList2String(mode_list, mode_index));
}
else
{
// Hour Min モードボタン押下なら
if(message == llList2String(mode_list, mode_index))
{
mode_index++;
if(mode_index > llGetListLength(mode_list)-1)
{
mode_index = 0;
}
// 時刻合わせダイアログを開く
setting_clock_dlg(avatarKey, llList2String(mode_list, mode_index));
}
}
}
}
/*
link_message(integer snd_num,integer num,string str,key id)
{
if(num==100)
{
llSetLinkPrimitiveParamsFast(2, [PRIM_TEXT,(string)rootRot+"\n"+str,<1.0,1.0,1.0>,1.0]);
}
}*/
changed(integer change)
{
if(change & CHANGED_OWNER)
{
llResetScript();
}
}
/*
on_rez(integer val)
{
llResetScript();
}*/
}