[[Nasal スクリプト集]]

* 概要 [#pf776953]
daytime.nas はワープ状態 (a キーを押してN倍速で飛行する) に応じて時計を進める為のスクリプトです。オリジナルはコンコルド用のファイルです。daytime.nas はそこから必要な物を取り出して、特別な設定なしで、どの機体でも動作可能なように変更したものです。コンコルドで実行すると処理がかぶってしまうので、時計が更に倍すすんでしまいますので、注意してください。
daytime.nas はスピードアップ状態 (a/A キーを押して1〜n倍速で飛行する) に応じて時計を進める為のスクリプトです。オリジナルはコンコルド用のファイルです。daytime.nas はそこから必要な物を取り出して、特別な設定なしで、どの機体でも動作可能なように変更したものです。なお、コンコルドは既にこの機能がありますので、コンコルド以外の機体で有効になるようにしています。

* インストール方法 [#zd32fd28]
ソースを ~/.fgfs/Nasal/daytime.nas に保存してください。あとは FlightGear を起動するだけで反映されます。
下のソースをエディタにコピーして、 ~/.fgfs/Nasal/daytime.nas として保存してください (Windows の場合は  C:/Documents and Settings/<ユーザ名>/Applciation Data/flightgear.org/Nasal/daytime.nas)。 あとは FlightGear を起動するだけで反映されます。特に機体側の変更は必要ありません。OV10 でも時計がチャキチャキ進むのを確認しました。

* 処理概要 [#t8297fd7]
settimer で 1 秒毎に Daytime.schedule を呼び出しています。schedule 内では ワープ状態に応じて時計を進める処理をしています。また、安全措置として、ワープが早すぎる場合はデフォルトの速度に戻す処理も行っています。System クラスはそんなに大事ではないですが、コンコルドのクラスが全てこの System を利用するようになっていたので、そのまま残しておきました。
settimer で 1 秒毎に Daytime.schedule を呼び出しています。schedule 内では スピードアップ状態に応じて時計を進める処理をしています。また、安全措置としてスピードアップ(単位時間当たりの高度変化)が早すぎる場合はデフォルトの速度に戻す処理も行っています。System クラスはそんなに大事ではないですが、コンコルドの Nasal クラスが再利用のために全てこの System を利用するようになっていたので、そのまま残しておきました。

* ソース [#u781142e]
添付しようとしたら  #attach がないと怒られたのでとりあえず貼付けておきます。

 ###############################################################################
 # daytime.nas by Tatsuhiro Nishioka
 # - Clock that considers "warp" in FlightGear world, extracted from Concorde with
 #   some modification
 # Copyright (C) 2008 Tatsuhiro Nishioka (tat dot fgmacosx at gmail dot com)
 # This file is licensed under the GPL license version 2 or later.
 # $Id: air-racing.nas,v 1.2 2008/04/08 00:16:00 tat Exp $
 # 
 ###############################################################################
 
 var constant = {
            HOURTOMINUTE : 60,
            HOURTOSECOND : 3600,
            MINUTETOSECOND : 60,
 };
 
 
 # ======
 # SYSTEM
 # ======
 
 # for inheritance, the system must be the last of parents.
 var System = {};
 
 # not called by child classes !!!
 System.new = func {
    obj = { parents : [System],
 
            SYSSEC : 0.0,                               # to be defined !
 
            RELOCATIONFT : 0.0,                         # max descent speed around 6000 feet/minute.
 
            altseaft : 0.0,
 
            RELOCATIONFT : 0.0,                         # max descent speed around 6000 feet/minute. 
            altseaft : 0.0, 
            noinstrument : {},
            slave : {}
          };
 
    return obj;
 };
 
 System.init_ancestor = func( path ) {
    obj = System.new();
 
    me.SYSSEC = obj.SYSSEC;
    me.RELOCATIONFT = obj.RELOCATIONFT;
    me.altseaft = obj.altseaft;
    me.noinstrument = obj.noinstrument;
    me.slave = obj.slave;
 
    me.loadtree( path ~ "/slave" );
    me.loadprop( path ~ "/noinstrument" );
 }
 
 System.set_rate_ancestor = func( rates ) {
    me.SYSSEC = rates;
 
    me.RELOCATIONFT = constantaero.MAXFPM / ( constant.MINUTETOSECOND / me.SYSSEC );
 }
 
 # property access is faster through its node, than parsing its string
 System.loadtree = func( path ) {
    if( props.globals.getNode(path) != nil ) {
        children = props.globals.getNode(path).getChildren();
        foreach( c; children ) {
           name = c.getName();
           subchildren = c.getChildren();
 
           # <slave>
           #  <engine>
           #   <component>/engines</component>
           #   <subcomponent>engine</subcomponent>
           #  </engine>
           if( size(subchildren) > 0 ) {
               component = c.getChild("component").getValue();
               subcomponent = c.getChild("subcomponent").getValue();
               me.slave[name] = props.globals.getNode(component).getChildren(subcomponent);
           }
 
           #  <altimeter>/instrumentation/altimeter[0]</altimeter>
           # </slave>
           else {
               value = c.getValue();
               me.slave[name] = props.globals.getNode(value);
           }
       }
    }
 }
 
 System.loadprop = func( path ) {
    if( props.globals.getNode(path) != nil ) {
        children = props.globals.getNode(path).getChildren();
        foreach( c; children ) {
           name = c.getName();
           subchildren = c.getChildren();
 
           # <noinstrument>
           #  <cloud>
           #   <component>/environment/clouds</component>
           #   <subcomponent>layer</subcomponent>
           #  </cloud>
           if( size(subchildren) > 0 ) {
               component = c.getChild("component").getValue();
               subcomponent = c.getChild("subcomponent").getValue();
               me.noinstrument[name] = props.globals.getNode(component).getChildren(subcomponent);
           }
 
           #  <agl>/position/altitude-agl-ft</agl>
           # </noinstrument>
           else {
               value = c.getValue();
               me.noinstrument[name] = props.globals.getNode(value);
           }
        }
    }
 }
 
 System.is_moving = func {
    # must exist in XML
    aglft = me.noinstrument["agl"].getValue();
    speedkt = me.noinstrument["airspeed"].getValue();
 
    if( aglft >=  constantaero.AGLTOUCHFT or speedkt >= constantaero.TAXIKT ) {
        result = constant.TRUE;
    }
    else {
        result = constant.FALSE;
    }
 
    return result;
 }
 
 System.is_relocating = func {
    # must exist in XML
    altft = me.noinstrument["altitude"].getValue();
 
    # relocation in flight, or at another airport
    variationftpm = altft - me.altseaft;
    if( variationftpm < - me.RELOCATIONFT or variationftpm > me.RELOCATIONFT ) {
        result = constant.TRUE;
    }
    else {
        result = constant.FALSE;
    }
 
    me.altseaft = altft;
 
    return result;
 }
 #
 # Daytime considering wrap
 #
 
 # =============
 # SPEED UP TIME
 # =============
 
 var Daytime = {};
 
 Daytime.new = func {
    obj = { parents : [Daytime, System],
 
            thesim : nil,
            warpnode : nil,
 
            SPEEDUPSEC : 1.0,
 
            SPEEDUPSEC : 1.0, 
            CLIMBFTPMIN : 3500,                                           # max climb rate
            MAXSTEPFT : 0.0,                                              # altitude change for step
 
            lastft : 0.0
          };
 
    obj.init();
 
    return obj;
 }
 
 Daytime.init = func {
     climbftpsec = me.CLIMBFTPMIN / constant.MINUTETOSECOND;
     me.MAXSTEPFT = climbftpsec * me.SPEEDUPSEC;
 
     me.thesim = props.globals.getNode("/sim");
     me.warpnode = props.globals.getNode("/sim/time/warp");
 
     me.init_ancestor("/instrumentation/clock");
 }
 
 Daytime.schedule = func {
 #   altitudeft = me.noinstrument["altitude"].getValue();
    altitudeft = getprop("/position/altitude-ft");
 
    speedup = me.thesim.getChild("speed-up").getValue();
    if( speedup > 1 ) {
        # accelerate day time
        multiplier = speedup - 1;
        offsetsec = me.SPEEDUPSEC * multiplier;
        warp = me.warpnode.getValue() + offsetsec; 
        warp = me.warpnode.getValue() + offsetsec;
        me.warpnode.setValue(warp);
 
        # safety
        stepft = me.MAXSTEPFT * speedup;
        maxft = me.lastft + stepft;
        minft = me.lastft - stepft;
 
        # too fast
        if( altitudeft > maxft or altitudeft < minft ) {
            me.thesim.getChild("speed-up").setValue(1);
        }
    }
 
    me.lastft = altitudeft;
 }
 
 var daytime = nil;
 
 # called every second
 var cron_1sec = func {
   daytime.schedule();
   settimer( func { cron_1sec(); }, 1);
 }
 
 # start the cron loop when FDM is initialized
 _setlistener("/sim/signals/fdm-initialized", func { 
   daytime = Daytime.new();
   cron_1sec(); 
   if (getprop("/sim/aircraft") != "Concorde") {
     daytime = Daytime.new();
     cron_1sec(); 
   }
 });



トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS