Nasal スクリプト集

概要

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

インストール方法

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

処理概要

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

ソース

添付しようとしたら #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, 
           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, 
           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;
       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 { 
  if (getprop("/sim/aircraft") != "Concorde") {
    daytime = Daytime.new();
    cron_1sec(); 
  }
});

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