using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("HeliAgilityCap")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HeliAgilityCap")]
[assembly: AssemblyTitle("HeliAgilityCap")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace HeliAgilityCap
{
[BepInPlugin("local.ravenfield.heliagilitycap", "Helicopter Agility Cap", "1.8.2")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
internal static ConfigEntry<float> MaxAngularVelocity;
internal static ConfigEntry<string> Mode;
internal static ConfigEntry<string> Names;
internal static ConfigEntry<string> RateMode;
internal static ConfigEntry<string> RateNames;
internal static ConfigEntry<string> RollRates;
internal static ConfigEntry<string> PitchRates;
internal static ConfigEntry<string> YawRates;
internal static ConfigEntry<string> ThrustRpm;
internal static ConfigEntry<string> ThrustRpmNames;
internal static ConfigEntry<string> Vpitch;
internal static ConfigEntry<string> Fmax;
internal static ConfigEntry<string> RotorSpoolTime;
internal static ConfigEntry<string> RotorForce;
internal static ConfigEntry<string> VerticalMode;
internal static ConfigEntry<string> AerodynamicLift;
internal static ConfigEntry<string> GroundEffectAcceleration;
internal static ConfigEntry<string> Drag;
internal static readonly FloatMapCache VpitchMap = new FloatMapCache("Vpitch");
internal static readonly FloatMapCache FmaxMap = new FloatMapCache("Fmax");
internal static readonly FloatMapCache SpoolMap = new FloatMapCache("RotorSpoolTime");
internal static readonly FloatMapCache RotorForceMap = new FloatMapCache("RotorForce");
internal static readonly FloatMapCache LiftMap = new FloatMapCache("AerodynamicLift");
internal static readonly FloatMapCache GeaMap = new FloatMapCache("GroundEffectAcceleration");
internal static readonly FloatMapCache DragMap = new FloatMapCache("Drag");
private void Awake()
{
//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
MaxAngularVelocity = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaxAngularVelocity", 10f, "直升机类载具角速度上限(rad/s)。原版=1.5(约 86°/s) //给使用原版操控的载具用的");
Mode = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Mode", "names", "生效范围:all=所有直升机;player=仅玩家驾驶的;names=载具名包含 Names 列表的。");
Names = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Names", "UFO,FPV", "Mode=names 时生效,逗号分隔,不区分大小写。");
RateMode = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RateMode", "on", "穿越机式姿态控制模式:off=不处理(杆量);actual(或 on)=旋转改为\"杆量直接映射到目标角速度\"(Betaflight Actual 曲线),接管后此载具的 manouverability、m_AngularDrag和角速度 1.5 上限都不再起作用。");
RateNames = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RateNames", "FPV", "RateMode 对哪些载具生效:载具名包含列表中任一词即可,逗号分隔、不区分大小写。留空 = 对所有直升机生效。");
RollRates = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RollRates", "270,500,0.1", "翻滚轴 Actual 参数,格式:中心灵敏度(deg/s), 满杆速率(deg/s), expo(0~1)。");
PitchRates = ((BaseUnityPlugin)this).Config.Bind<string>("General", "PitchRates", "270,500,0.1", "俯仰轴 Actual 参数,格式同上。");
YawRates = ((BaseUnityPlugin)this).Config.Bind<string>("General", "YawRates", "270,490,0.0", "偏航轴 Actual 参数,格式同上。");
ThrustRpm = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ThrustRpm", "on", "启用定距桨气动模型:off=不处理;on=杆量映射桨叶转速。");
ThrustRpmNames = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ThrustRpmNames", "FPV", "定距桨气动模型对哪些载具生效:载具名包含列表中任一词即可,逗号分隔、不区分大小写。留空 = 对所有直升机生效。");
Vpitch = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Vpitch", "FPV:80", "桨距速度(m/s,主要决定极速):轴向速度达到该值时推力归零。格式:名称:值,名称:值,...——只有列出的载具单独设置;未列出(或写 -1)= 用默认 80。如 \"FPV:13,Mi-8:54\"。");
Fmax = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Fmax", "FPV:1.25", "下降缓冲上限(未单独设置时用 1.25 = 下降时最多 +25% 推力)。格式同上。");
RotorSpoolTime = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RotorSpoolTime", "FPV:0.05", "转速响应时间(秒;未单独设置时用 0.05 ≈ 打杆后 0.15 秒到 95%,0=瞬时)。格式同上。");
RotorForce = ((BaseUnityPlugin)this).Config.Bind<string>("General", "RotorForce", "FPV:100", "旋翼满转静态推力(覆盖原版载具属性)(m/s²,悬停转速=√(9.81/该值),务必 > 9.81):只有列出的载具生效(值必须 >0),如 \"FPV:125,Mi-8:150\";未列出(或值 ≤0)= 用原版载具属性。");
VerticalMode = ((BaseUnityPlugin)this).Config.Bind<string>("General", "VerticalMode", "", "垂直杆量重映射(仅玩家、且当前载具在新气动名单内时生效):留空(默认)=自动 full;off=不处理;clamp=负杆量按 0 计;full=整杆程映射为 0~1(杆到底=0)。填值即覆盖自动。");
AerodynamicLift = ((BaseUnityPlugin)this).Config.Bind<string>("General", "AerodynamicLift", "FPV:0.01", "aerodynamicLift(覆盖原版载具属性)(前飞升力系数:沿机身 up 施加 前飞速度×该值)。只有列出的载具生效,如 \"FPV:0.05,Mi-8:0.01\"(值 0 = 该车取消前飞升力);未列出(或写 -1)= 所有载具都不动(用文件值)。");
GroundEffectAcceleration = ((BaseUnityPlugin)this).Config.Bind<string>("General", "GroundEffectAcceleration", "FPV:0", "groundEffectAcceleration(覆盖原版载具属性)(地效上限加速度,离地越近推力越强)。只有列出的载具生效,如 \"FPV:0\"(值 0 = 关地效);未列出(或写 -1)= 所有载具都不动(用文件值)。");
Drag = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Drag", "FPV:0.02", "线性空气阻力(覆盖原版载具属性)(线性空气阻力 1/s)。只有列出的载具生效,如 \"FPV:0.05,Mi-8:0.02\";未列出(或写 -1)= 所有载具都不动(用文件值)。");
((BaseUnityPlugin)this).Config.Save();
new Harmony("local.ravenfield.heliagilitycap").PatchAll(typeof(Plugin).Assembly);
Log.LogInfo((object)"Helicopter Agility Cap 1.8.2 已加载。");
Log.LogInfo((object)("driverInput 反射: " + ((DriverInputAccess.Ref != null) ? "OK" : "失败(将使用兜底取值)")));
Log.LogInfo((object)("RateMode 配置: \"" + RateMode.Value + "\" → " + (RateModeEnabled() ? "启用" : "未启用")));
Log.LogInfo((object)("ThrustRpm 配置: \"" + ThrustRpm.Value + "\" → " + (ThrustRpmEnabled() ? "启用" : "未启用")));
Log.LogInfo((object)("VerticalMode 配置: \"" + VerticalMode.Value + "\" → " + (string.IsNullOrWhiteSpace(VerticalMode.Value) ? "自动(full)" : VerticalMode.Value.Trim())));
}
internal static bool ShouldApply(Helicopter heli)
{
switch (Mode.Value.Trim().ToLowerInvariant())
{
case "all":
return true;
case "player":
if (((Vehicle)heli).HasDriver())
{
return ((Vehicle)heli).HasPlayerDriver();
}
return false;
case "names":
{
string text = ((Vehicle)heli).name ?? string.Empty;
string[] array = Names.Value.Split(new char[1] { ',' });
for (int i = 0; i < array.Length; i++)
{
string text2 = array[i].Trim();
if (text2.Length > 0 && text.IndexOf(text2, StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
}
return false;
}
default:
return false;
}
}
internal static bool RateModeEnabled()
{
string text = RateMode.Value.Trim().ToLowerInvariant();
if (!(text == "actual"))
{
return text == "on";
}
return true;
}
internal static bool RateModeAppliesTo(Vehicle vehicle)
{
return MatchesVehicleNameList(((Object)(object)vehicle != (Object)null) ? vehicle.name : null, RateNames.Value);
}
internal static bool ThrustRpmEnabled()
{
string text = ThrustRpm.Value.Trim().ToLowerInvariant();
if (!(text == "on"))
{
return text == "true";
}
return true;
}
internal static bool ThrustRpmAppliesTo(Vehicle vehicle)
{
return MatchesVehicleNameList(((Object)(object)vehicle != (Object)null) ? vehicle.name : null, ThrustRpmNames.Value);
}
internal static bool MatchesVehicleNameList(string vehicleName, string list)
{
if (string.IsNullOrWhiteSpace(list))
{
return true;
}
vehicleName = vehicleName ?? string.Empty;
string[] array = list.Split(new char[1] { ',' });
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim();
if (text.Length > 0 && vehicleName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
}
return false;
}
}
internal sealed class FloatMapCache
{
private readonly string keyName;
private string raw;
private string[] names = new string[0];
private float[] values = new float[0];
internal FloatMapCache(string keyName)
{
this.keyName = keyName;
}
internal float Resolve(string rawText, string vehicleName, float fallback)
{
if (rawText != raw)
{
Rebuild(rawText);
}
if (!string.IsNullOrEmpty(vehicleName))
{
for (int i = 0; i < names.Length; i++)
{
if (vehicleName.IndexOf(names[i], StringComparison.OrdinalIgnoreCase) >= 0)
{
if (!(values[i] < 0f))
{
return values[i];
}
return fallback;
}
}
}
return fallback;
}
private void Rebuild(string text)
{
raw = text;
List<string> list = new List<string>();
List<float> list2 = new List<float>();
if (!string.IsNullOrEmpty(text))
{
string[] array = text.Split(new char[1] { ',' });
for (int i = 0; i < array.Length; i++)
{
string text2 = array[i].Trim();
if (text2.Length == 0)
{
continue;
}
int num = text2.LastIndexOf(':');
if (num > 0)
{
string text3 = text2.Substring(0, num).Trim();
string s = text2.Substring(num + 1).Trim();
if (text3.Length > 0 && float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
{
list.Add(text3);
list2.Add(result);
continue;
}
}
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)(keyName + ":配置格式无法解析,已忽略该项:" + text2));
}
}
}
names = list.ToArray();
values = list2.ToArray();
}
}
internal static class DriverInputAccess
{
internal static readonly FieldRef<Vehicle, Vector4> Ref = Create();
private static FieldRef<Vehicle, Vector4> Create()
{
try
{
return AccessTools.FieldRefAccess<Vehicle, Vector4>("driverInput");
}
catch
{
return null;
}
}
internal static Vector4 Get(Helicopter heli)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
if (Ref != null)
{
try
{
return Ref.Invoke((Vehicle)(object)heli);
}
catch
{
}
}
try
{
return Clamp(((Vehicle)heli).Driver().controller.HelicopterInput()) * ((Vehicle)heli).engine.power;
}
catch
{
return Vector4.zero;
}
}
private static Vector4 Clamp(Vector4 v)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
return new Vector4(Mathf.Clamp(v.x, -1f, 1f), Mathf.Clamp(v.y, -1f, 1f), Mathf.Clamp(v.z, -1f, 1f), Mathf.Clamp(v.w, -1f, 1f));
}
}
[HarmonyPatch(typeof(Helicopter), "FixedUpdate")]
internal static class HelicopterFixedUpdatePatch
{
private static void Postfix(Helicopter __instance)
{
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Vehicle)__instance).rigidbody == (Object)null) && (!Plugin.RateModeEnabled() || !Plugin.RateModeAppliesTo((Vehicle)(object)__instance)) && Plugin.ShouldApply(__instance))
{
((Vehicle)__instance).rigidbody.maxAngularVelocity = Plugin.MaxAngularVelocity.Value;
}
}
}
[HarmonyPatch(typeof(FpsActorController), "HelicopterInput")]
internal static class HelicopterInputVerticalPatch
{
private static void Postfix(FpsActorController __instance, ref Vector4 __result)
{
if (!Plugin.ThrustRpmEnabled())
{
return;
}
Vehicle currentVehicle = GetCurrentVehicle(__instance);
if ((Object)(object)currentVehicle == (Object)null || !Plugin.ThrustRpmAppliesTo(currentVehicle))
{
return;
}
string text = Plugin.VerticalMode.Value.Trim().ToLowerInvariant();
if (!(text == "off"))
{
if (text == "clamp")
{
__result.y = Mathf.Clamp(__result.y, 0f, 1f);
return;
}
float num = Mathf.Clamp(__result.y, -1f, 1f);
__result.y = (num + 1f) * 0.5f;
}
}
private static Vehicle GetCurrentVehicle(FpsActorController controller)
{
Actor val = (((Object)(object)controller == (Object)null) ? null : ((ActorController)controller).actor);
if ((Object)(object)val == (Object)null || (Object)(object)val.seat == (Object)null)
{
return null;
}
return val.seat.vehicle;
}
}
[HarmonyPatch(typeof(Helicopter), "FixedUpdate")]
internal static class HelicopterFieldOverridePatch
{
private static readonly HashSet<int> LiftLogged = new HashSet<int>();
private static readonly HashSet<int> GeaLogged = new HashSet<int>();
private static readonly HashSet<int> DragLogged = new HashSet<int>();
private static void Prefix(Helicopter __instance)
{
if ((Object)(object)__instance == (Object)null || (Object)(object)((Vehicle)__instance).rigidbody == (Object)null)
{
return;
}
string name = ((Vehicle)__instance).name;
float num = Plugin.LiftMap.Resolve(Plugin.AerodynamicLift.Value, name, -1f);
if (num >= 0f)
{
float aerodynamicLift = __instance.aerodynamicLift;
if (aerodynamicLift != num)
{
__instance.aerodynamicLift = num;
}
if (LiftLogged.Add(((Object)__instance).GetInstanceID()))
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("aerodynamicLift 已覆盖:" + (name ?? "?") + " = " + num + "(文件值 " + aerodynamicLift + ")"));
}
}
}
float num2 = Plugin.GeaMap.Resolve(Plugin.GroundEffectAcceleration.Value, name, -1f);
if (num2 >= 0f)
{
float groundEffectAcceleration = __instance.groundEffectAcceleration;
if (groundEffectAcceleration != num2)
{
__instance.groundEffectAcceleration = num2;
}
if (GeaLogged.Add(((Object)__instance).GetInstanceID()))
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)("groundEffectAcceleration 已覆盖:" + (name ?? "?") + " = " + num2 + "(文件值 " + groundEffectAcceleration + ")"));
}
}
}
float num3 = Plugin.DragMap.Resolve(Plugin.Drag.Value, name, -1f);
if (!(num3 >= 0f))
{
return;
}
float drag = ((Vehicle)__instance).rigidbody.drag;
if (drag != num3)
{
((Vehicle)__instance).rigidbody.drag = num3;
}
if (DragLogged.Add(((Object)__instance).GetInstanceID()))
{
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogInfo((object)("Rigidbody.drag 已覆盖:" + (name ?? "?") + " = " + num3 + "(文件值 " + drag + ")"));
}
}
}
}
[HarmonyPatch(typeof(Helicopter), "FixedUpdate")]
internal static class HelicopterRateModePatch
{
private static readonly HashSet<int> AppliedLogged = new HashSet<int>();
private static readonly HashSet<int> NotMatchedLogged = new HashSet<int>();
private static void Postfix(Helicopter __instance)
{
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
if (!Plugin.RateModeEnabled() || (Object)(object)__instance == (Object)null || (Object)(object)((Vehicle)__instance).rigidbody == (Object)null || ((Vehicle)__instance).dead || !((Vehicle)__instance).HasDriver())
{
return;
}
if (!Plugin.RateModeAppliesTo((Vehicle)(object)__instance))
{
if (NotMatchedLogged.Add(((Object)__instance).GetInstanceID()))
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("RateMode 未生效(名单不匹配):" + (((Vehicle)__instance).name ?? "?") + ",RateNames=" + Plugin.RateNames.Value));
}
}
return;
}
Vector4 val = DriverInputAccess.Get(__instance);
ParseRateTriple(Plugin.RollRates.Value, 150f, 400f, 0.6f, out var cs, out var mr, out var expo);
ParseRateTriple(Plugin.PitchRates.Value, 120f, 350f, 0.5f, out var cs2, out var mr2, out var expo2);
ParseRateTriple(Plugin.YawRates.Value, 100f, 300f, 0.3f, out var cs3, out var mr3, out var expo3);
float num = (((Vehicle)__instance).burning ? __instance.controlWhenBurning : 1f);
Vector3 val2 = new Vector3(ActualRate(val.w, cs2 * ((float)Math.PI / 180f), mr2 * ((float)Math.PI / 180f), expo2), ActualRate(val.x, cs3 * ((float)Math.PI / 180f), mr3 * ((float)Math.PI / 180f), expo3), 0f - ActualRate(val.z, cs * ((float)Math.PI / 180f), mr * ((float)Math.PI / 180f), expo)) * num;
float num2 = 1f + ((Vehicle)__instance).rigidbody.angularDrag * Time.fixedDeltaTime;
((Vehicle)__instance).rigidbody.maxAngularVelocity = Mathf.Max(((Vector3)(ref val2)).magnitude * num2 + 1f, 2f);
__instance.manouverability = 0f;
((Vehicle)__instance).rigidbody.angularVelocity = ((Component)__instance).transform.rotation * (val2 * num2);
if (AppliedLogged.Add(((Object)__instance).GetInstanceID()))
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)("RateMode 已生效:" + (((Vehicle)__instance).name ?? "?") + "(Roll=" + Plugin.RollRates.Value + " Pitch=" + Plugin.PitchRates.Value + " Yaw=" + Plugin.YawRates.Value + ")"));
}
}
}
private static void ParseRateTriple(string text, float defaultCs, float defaultMr, float defaultExpo, out float cs, out float mr, out float expo)
{
cs = defaultCs;
mr = defaultMr;
expo = defaultExpo;
if (string.IsNullOrWhiteSpace(text))
{
return;
}
string[] array = text.Split(new char[1] { ',' });
if (array.Length >= 3)
{
if (!float.TryParse(array[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out cs))
{
cs = defaultCs;
}
if (!float.TryParse(array[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out mr))
{
mr = defaultMr;
}
if (!float.TryParse(array[2].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out expo))
{
expo = defaultExpo;
}
}
}
private static float ActualRate(float stick, float cs, float mr, float expo)
{
float num = Mathf.Abs(stick);
if (num > 1f)
{
num = 1f;
}
float num2 = Mathf.Clamp01(expo);
float num3 = num * (Mathf.Pow(num, 5f) * num2 + num * (1f - num2));
float num4 = cs * num + (mr - cs) * num3;
return Mathf.Sign(stick) * num4;
}
}
[HarmonyPatch(typeof(Helicopter), "FixedUpdate")]
internal static class HelicopterThrustRpmPatch
{
private sealed class OmegaState
{
public float omega;
}
private static readonly ConditionalWeakTable<Helicopter, OmegaState> OmegaStates = new ConditionalWeakTable<Helicopter, OmegaState>();
private static readonly HashSet<int> AppliedLogged = new HashSet<int>();
private static readonly HashSet<int> NotMatchedLogged = new HashSet<int>();
private static void Postfix(Helicopter __instance)
{
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
//IL_021b: Unknown result type (might be due to invalid IL or missing references)
//IL_021d: Unknown result type (might be due to invalid IL or missing references)
//IL_0222: Unknown result type (might be due to invalid IL or missing references)
//IL_023c: Unknown result type (might be due to invalid IL or missing references)
//IL_0258: Unknown result type (might be due to invalid IL or missing references)
//IL_025c: Unknown result type (might be due to invalid IL or missing references)
//IL_0261: Unknown result type (might be due to invalid IL or missing references)
//IL_0269: Unknown result type (might be due to invalid IL or missing references)
//IL_026b: Unknown result type (might be due to invalid IL or missing references)
//IL_026d: Unknown result type (might be due to invalid IL or missing references)
if (!Plugin.ThrustRpmEnabled() || (Object)(object)__instance == (Object)null || (Object)(object)((Vehicle)__instance).rigidbody == (Object)null)
{
return;
}
if (!Plugin.ThrustRpmAppliesTo((Vehicle)(object)__instance))
{
if (NotMatchedLogged.Add(((Object)__instance).GetInstanceID()))
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("ThrustRpm 未生效(名单不匹配):" + (((Vehicle)__instance).name ?? "?") + ",ThrustRpmNames=" + Plugin.ThrustRpmNames.Value));
}
}
return;
}
OmegaState orCreateValue = OmegaStates.GetOrCreateValue(__instance);
if (((Vehicle)__instance).dead || !((Vehicle)__instance).HasDriver())
{
orCreateValue.omega = 0f;
return;
}
float fixedDeltaTime = Time.fixedDeltaTime;
float y = DriverInputAccess.Get(__instance).y;
float num = Mathf.Clamp01(y);
string name = ((Vehicle)__instance).name;
float num2 = Plugin.VpitchMap.Resolve(Plugin.Vpitch.Value, name, 80f);
float num3 = Plugin.FmaxMap.Resolve(Plugin.Fmax.Value, name, 1.25f);
float num4 = Plugin.SpoolMap.Resolve(Plugin.RotorSpoolTime.Value, name, 0.05f);
float rotorForce = __instance.rotorForce;
float num5 = Plugin.RotorForceMap.Resolve(Plugin.RotorForce.Value, name, 0f);
float num6 = ((num5 > 0f) ? num5 : rotorForce);
if (num4 <= 0.0001f)
{
orCreateValue.omega = num;
}
else
{
orCreateValue.omega += (num - orCreateValue.omega) * Mathf.Min(1f, fixedDeltaTime / num4);
}
float omega = orCreateValue.omega;
Vector3 val = ((Component)__instance).transform.up + ((Component)__instance).transform.forward * 0.05f;
Vector3 normalized = ((Vector3)(ref val)).normalized;
Vector3 val2 = Vector3.Project(normalized, Vector3.up);
val = normalized - 0.05f * val2;
normalized = ((Vector3)(ref val)).normalized;
float num7 = Vector3.Dot(((Vehicle)__instance).rigidbody.velocity, normalized);
float num8 = Mathf.Clamp(1f - num7 / Mathf.Max(num2, 1f), 0f, num3);
Vector3 val3 = ComputeGameThrust(__instance, y, normalized);
float num9 = (((Vehicle)__instance).burning ? 0.3f : 1f);
float num10 = ComputeGameGroundEffect(__instance, y, normalized);
float num11 = num6 * omega * omega * num8 * num9 + num10;
Vector3 val4 = normalized * num11;
((Vehicle)__instance).rigidbody.AddForce(val4 - val3, (ForceMode)5);
if (AppliedLogged.Add(((Object)__instance).GetInstanceID()))
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)("ThrustRpm 已生效:" + (((Vehicle)__instance).name ?? "?") + "(Vpitch=" + num2 + " Fmax=" + num3 + " Spool=" + num4 + " rotorForce=" + num6 + ((num5 > 0f) ? ("(配置;文件值 " + rotorForce + " 已忽略)") : "(文件)") + ")"));
}
}
}
private static Vector3 ComputeGameThrust(Helicopter heli, float yRaw, Vector3 dir)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
Vector3 velocity = ((Vehicle)heli).rigidbody.velocity;
float num = Mathf.Clamp01(0f - Vector3.Dot(dir, ((Vector3)(ref velocity)).normalized));
float num2 = 1f + Mathf.Lerp(0f, heli.extraForceWhenStopping, num);
float num3 = ComputeGameGroundEffect(heli, yRaw, dir) + yRaw * heli.rotorForce * num2;
float num4 = (((Vehicle)heli).burning ? 0.3f : 1f);
return dir * ((num3 - Physics.gravity.y - 0.5f) * num4);
}
private static float ComputeGameGroundEffect(Helicopter heli, float yRaw, Vector3 dir)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
return Mathf.Clamp01(Mathf.Max(yRaw, 0f) * Vector3.Dot(dir, Vector3.up) * (20f - heli.altitude) * 0.1f) * heli.groundEffectAcceleration;
}
}
}