--[[ 冷戦レギュ Jet機燃料制限レギュ関数 最終更新090729 2300時 1.設定法 引数にエンジンの数を指定してください。 単発ならば1、双発ならば2です。 ドロップタンクを設定し、そちらから優先的に燃料が消費されるようにするには、 指定したいチップにUser2の値を設定する必要があります。User2が設定されたチ ップは、その値ごとにグループ化されて"燃料タンク"とみなされて、User2が大 きい"燃料タンク"から順に燃料が消費されていきます。これによって、先にドロ ップタンクから燃料を使い、会敵したら切り離す等が可能です。また、User2を 設定しないチップはUser2が0と扱われますので、User2が0の"燃料タンク"は機体 本体のタンクとなり、最後に使われることになります。 またミサイル・ロケット・爆弾など、機体本体から分離して使用される装備の根 元チップ(BYEやSPLITで指定するチップ)のUser2を40として下さい。機体重量から 除外し、推力重量比の算出に用います。 なお、Jetの出力を計算する際に、構造材に使っていて計算対象からはずしたい Jetがある場合、そのJetのuser2を41にしておくと、計算対象にならず、わずかな 計算負荷軽減が期待できます。 また、他のシナリオなどでUser2を使用する可能性があるので、User2の値は39以 内にしてください。 2.燃料の計り方 下の変数を見てください・・・ではなくて、説明。 まず、モデル全体で残っている燃料の値が AllFuelLeft です。これが0以下にな った機体はエンジンを止めなくてはなりません。又、同様にモデル全体の燃料の 最大値は AllFuelmax なので、(AllFuelLeft/AllFuelMax)が現在の燃料の残りの 割合です。 又、個々の燃料タンクについても、 FuelLeft[そのタンクのUser2] で残量が、 FuelMax[そのタンクのUser2]でそのタンクの燃料最大値が、取得できます。 また、今どのタンクから燃料が消費されているかについては、 FuelTankNumberUsed が、現在使用してるタンクのUser2を示しています。 3.まとめ LimitFuelRegulation(1) → 単発 LimitFuelRegulation(2) → 双発 User2=0  → 機内タンク。特に設定する必要無し User2=40 → 機外装備の根元チップ User2=41 → 構造材Jet User2=1-39 → 機外タンク。番号の大きい物から優先消費 AllFuelMax  → モデル全体の燃料最大値(機外タンク含む) AllFuelLeft → モデル全体での燃料残量(機外タンク含む) FuelMax[n]  → User2=nのタンクの燃料最大値。機内タンクはn=0 FuelLeft[n] → User2=nのタンクでの燃料残量。機内タンクはn=0 ]] FuelMax = {};--タンクごとの燃料最大値 FuelLeft = {};--タンクごとの燃料残量 FuelTankList = {};--燃料タンクのUser2のリスト FuelTankNumberUsed = 0;--現在使用中の燃料タンクのUser2 AllFuelMax = 0;--モデル全体での燃料の最大値 AllFuelLeft = 0;--モデル全体での燃料の残量 JetChipList = {};--Jetチップのリスト FuelCost = 0.04;--Jet出力の何倍の燃料を消費するか FuelSupply = 30 * 1000--駐機中の1Fあたりの燃料回復量 MilPow = 0;--通常推力の最大値 ABCost = 5;--AB使用時に通常時の何倍燃料を消費するか ExtensionList = {};--機外装備チップのリスト ExtensionWeight = 0;--機外装備の重量 --以下内部で使う変数 local __oldWeight = _WEIGHT();--1F前の重さ。これが今の重さと違うときは被弾・分離があった local __usedFuelTankNumber = 1;--今使っている燃料タンクのFuelTankListにおけるindex(User2じゃないよ!) local __suppliableFuelMax = {};--燃料タンクごとの補給で回復できる燃料の最大値。すでに切り離した部分には補給できないのでこれが必要 local __isBreakFound = {};--壊れているのを一度スキャンしているかどうかのフラグ local __getn = table.getn; local __abs = math.abs; local __min = math.min; local __max = math.max; local __limit = function (val,min,max) return min>val and min or max 0 and user2 <= 40 then--user2=40の場合は機外武装、1-39はタンク table.insert(ExtensionList, i); __isExtension[i] = true end end --燃料タンクリストをUser2の大きいものから順に並び替えて, --FuelTankList[1]のuser2のタンクから順に使えばいいようにする table.sort(FuelTankList, function(a, b) return a > b end) FuelTankNumberUsed = FuelTankList[1]; local lastgetn;-- local getn; while true do lastgetn = getn or 1; getn = __getn(ExtensionList); for i=lastgetn,getn do--機外装備リスト中のチップに対して for j=ExtensionList[i]+1 , ExtensionList[i+1] or n do--機外装備チップの次チップから次機外装備の前チップまで if _PARENT(j) == ExtensionList[i] and not __isExtension[j] then--親チップがリストのチップかつ未だリストに入ってなければリスト入り table.insert(ExtensionList, j); end end end if __getn(ExtensionList) == getn then--テーブル長が前回と同じ=新規チップが無ければスキャン終了 break; end end for i=1,__getn(ExtensionList) do--機外装備リストのチップの重量計算 local chipweight = 0 local type = _TYPE(ExtensionList[i]); --以下でチプの種類を見て重量を計算する if type == 0 then--core chipweight = 25.200002670288086 elseif type == 1 then--chip chipweight = 25.200002670288086 elseif type == 2 then--rudder chipweight = 25.200002670288086 elseif type == 3 then--rim chipweight = 42.411502838134766 elseif type == 4 then--wheel chipweight = 36.756637573242188 elseif type == 5 then--RLW chipweight = 36.756637573242188 elseif type == 6 then--trim chipweight = 25.200002670288086 elseif type == 7 then--jet chipweight = 36.756637573242188 elseif type == 8 then--weight chipweight = 100.800010681152340 * __limit( _OPTION(ExtensionList[i]), 1, 8 ); elseif type == 10 then--arm chipweight = 50.400005340576172 elseif type == 33 then--frame chipweight = 12.600001335144043 elseif type == 34 then--rudderf chipweight = 12.600001335144043 elseif type == 35 then--trimf chipweight = 12.600001335144043 end ExtensionWeight = ExtensionWeight + chipweight;--機外装備の合計重量を計算 end MilPow = math.min(100000,(_WEIGHT()-ExtensionWeight)*58.8/engines);--本体重量=最大通常推力になる値を決定 isLimitFuelInitialized = true;--初期化完了! else--初期化終わってる場合 if _WEIGHT() == __oldWeight then--ひだん等なし local n = __getn(JetChipList); local sumConsumedFuel = 0;--1Fで消費する燃料の合計 for i = 1, n do--Jet全部について出力*燃費だけ燃料を消費 if __abs(_POWER(JetChipList[i])) > MilPow+1 then--通常出力を超えてるか。MilPowに+1しないと内部の計算誤差で不当にAB判定喰らうので注意 sumConsumedFuel = sumConsumedFuel + __abs(_POWER(JetChipList[i])) * FuelCost * ABCost;--超えていれば定数掛けて消費量増大 else sumConsumedFuel = sumConsumedFuel + __abs(_POWER(JetChipList[i])) * FuelCost;--超えてなければ普通に計算 end end local reallyConsumedFuel = __min(sumConsumedFuel, FuelLeft[FuelTankNumberUsed]);--燃料残量が0になりそうなら今のタンク全部使ったところで終わる FuelLeft[FuelTankNumberUsed] = FuelLeft[FuelTankNumberUsed] - reallyConsumedFuel;--今のタンクと AllFuelLeft = AllFuelLeft - reallyConsumedFuel;--全体とから使った分の燃料を引く if FuelLeft[FuelTankNumberUsed] <= 0 then--タンク空になったよー __usedFuelTankNumber = __min(__usedFuelTankNumber+1, __getn(FuelTankList));--FuelTankListで1つ次のタンクに進む FuelTankNumberUsed = FuelTankList[__usedFuelTankNumber];--user2であらわすとこちら。 end --補給の可能性を見るコード local h = _H(0); if 0 <= h and h < 2 then--コアの対地高度が2m以下 local vz = _VZ(0); if __abs(vz) < 3 then--速度3m/s以下 local n = __getn(FuelTankList); local fuelTankNumber = 0; for i = n, 1, -1 do--すべてのタンクをuser2が小さいほうからチェックして、満タンじゃないやつを見つけたら給油 fuelTankNumber = FuelTankList[i];--i番目のタンクのuser2 if FuelLeft[fuelTankNumber] < __suppliableFuelMax[fuelTankNumber] then--満タンじゃない local supply = __min(FuelSupply, __suppliableFuelMax[fuelTankNumber] - FuelLeft[fuelTankNumber]);--消費のときと一緒であふれそうなら満タンでとめる FuelLeft[fuelTankNumber] = FuelLeft[fuelTankNumber] + supply;--タンクに補給して AllFuelLeft = AllFuelLeft + supply;--全体でも増える __usedFuelTankNumber = i;--使用中のタンクを戻さないと補給後も胴体タンクから消費されたりする FuelTankNumberUsed = fuelTankNumber;--上に同じ break; end end end end else--被弾か切り離しかがあった local chips = _CHIPS() - 1; local deadFuel = {};--死んだチップに残ってる燃料を殺す local deadFuelMax = {};--死んだチップの最大燃料 local BrokenTankList = {};--今フレームで総容量が減ったタンクのリスト for i = 0, chips do--全部のチプについてスキャン local user2 = _USER2(i); if _TOP(i) ~= 0 and not __isBreakFound[i] and user2~=40 then--壊れているのが新規に発見された local chipFuel = 0; local type = _TYPE(i); deadFuel[user2] = deadFuel[user2] or 0 deadFuelMax[user2] = deadFuelMax[user2] or 0 --初期燃料計算のときと同じコードでチプの燃料を計算 if type == 0 then--core chipFuel = 2000000 elseif type == 1 then--chip chipFuel = 1000000 elseif type == 2 then--rudder chipFuel = 1000000 elseif type == 6 then--trim chipFuel = 1000000 elseif type == 8 then--weight chipFuel = 6000000 * __limit( _OPTION(i), 1, 8 ); elseif type == 33 then--frame chipFuel = 500000 elseif type == 34 then--rudderf chipFuel = 500000 elseif type == 35 then--trimf chipFuel = 500000 end deadFuelMax[user2] = deadFuelMax[user2] + chipFuel;--死んだチップが持てる最大燃料をタンク別集計 local chipLeftFuel = FuelLeft[user2]/FuelMax[user2] * chipFuel;--このチップの残り燃料 deadFuel[user2] = deadFuel[user2] + chipLeftFuel;--死んだチップに残ってる燃料をタンク別に集計 table.insert(BrokenTankList,user2);--壊れたチップのタンク番号をリスト化 __isBreakFound[i] = true;--壊れているのを一度見つけたチプは二度目以降は燃料を引かない(当たり前 end end local n = __getn(BrokenTankList); for i = 1, n do--壊れたタンクをチェック local fuelTankNumber = BrokenTankList[i];--i番目のタンクのuser2 FuelLeft[fuelTankNumber] = FuelLeft[fuelTankNumber] - deadFuel[fuelTankNumber];--タンクの燃料から壊れたチップに残っていた燃料を引き __suppliableFuelMax[fuelTankNumber] = __suppliableFuelMax[fuelTankNumber] - deadFuelMax[fuelTankNumber];--タンクの回復可能な最大値も減らしておく AllFuelLeft = AllFuelLeft - deadFuel[fuelTankNumber];--当然全体の残量も壊れたチップに入ってたぶんだけへる end end __oldWeight = _WEIGHT(); --AllFuelLeftの計算誤差回避コード。FuelLeftと独立して計算してるので誤差が出るっぽい。 --FuelLeft[0](機内タンク)は残量0になるけどAllFuelLeftは残量が0.0000001程度余って0にならない。 --よって少々重くはなるがもしもの時のためにAllFuelLeftの独立計算を残したまま誤差チェックを実装する。 local SumFuelLeft = 0;--FuelLeftの合計 local n = __getn(FuelTankList); for i=1, n do local fuelTankNumber = FuelTankList[i];--i番目のタンクのuser2 SumFuelLeft = SumFuelLeft + FuelLeft[fuelTankNumber];--全タンクの燃料を加算して合計を求める(計算誤差回避) end if AllFuelLeft ~= SumFuelLeft then--AllFuelLeftとFuelLeftの計算に誤差が出てたら AllFuelLeft = SumFuelLeft;--FuelLeftの合計を優先する end end end