- 追加された行はこの色です。
- 削除された行はこの色です。
[[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]
このソースは参考迄に表示しています。ダウンロードは下の添付から行ってください。
###############################################################################
# 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();
}
});