0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LSL アナログ時計スクリプト

Posted at

時間の針、分の針、秒の針のプリム名をそれぞれ
"_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();
    }*/
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?