using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Player;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("AdvancedBIOCOM")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("AdvancedBIOCOM")]
[assembly: AssemblyTitle("AdvancedBIOCOM")]
[assembly: AssemblyVersion("0.1.0.0")]
namespace HoloAmmo;
[BepInPlugin("AdvancedBIOCOM", "Advanced BIOCOM", "1.0.0")]
public class Plugin : BasePlugin
{
public const string GUID = "AdvancedBIOCOM";
internal static ManualLogSource L;
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<bool> ShowClip;
internal static ConfigEntry<bool> ShowReserve;
internal static ConfigEntry<bool> ShowBars;
internal static ConfigEntry<bool> HideInMenus;
internal static ConfigEntry<bool> FollowFov;
internal static ConfigEntry<bool> HotReload;
internal static ConfigEntry<bool> EmpEnabled;
internal static ConfigEntry<bool> EmpIgnore;
internal static Plugin Instance;
internal static ConfigEntry<float> OffsetX;
internal static ConfigEntry<float> OffsetY;
internal static ConfigEntry<float> OffsetZ;
internal static ConfigEntry<float> ScreenOffsetX;
internal static ConfigEntry<float> ScreenOffsetY;
internal static ConfigEntry<float> WidgetScale;
internal static ConfigEntry<float> ClipFontSize;
internal static ConfigEntry<float> ReserveFontSize;
internal static ConfigEntry<int> BarCount;
internal static ConfigEntry<float> BarWidth;
internal static ConfigEntry<float> BarGap;
internal static ConfigEntry<float> BarHeight;
internal static ConfigEntry<float> ReserveOffsetY;
internal static ConfigEntry<string> ClipColor;
internal static ConfigEntry<string> ReserveColor;
internal static ConfigEntry<string> LowColor;
internal static ConfigEntry<int> LowPercent;
internal static ConfigEntry<float> Opacity;
internal static ConfigEntry<float> OutlineWidth;
internal static ConfigEntry<float> ReferenceDistance;
internal static ConfigEntry<float> ReferenceFov;
internal static ConfigEntry<float> MinScale;
internal static ConfigEntry<float> MaxScale;
internal static ConfigEntry<float> AdsFovThreshold;
internal static ConfigEntry<float> AdsViewportX;
internal static ConfigEntry<float> AdsViewportY;
internal static ConfigEntry<float> AdsOffsetX;
internal static ConfigEntry<float> AdsOffsetY;
internal static ConfigEntry<float> AdsScale;
internal static ConfigEntry<float> SmoothSpeed;
internal static ConfigEntry<bool> DebugLog;
public override void Load()
{
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Expected O, but got Unknown
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Expected O, but got Unknown
//IL_037c: Unknown result type (might be due to invalid IL or missing references)
//IL_0386: Expected O, but got Unknown
//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
//IL_03c3: Expected O, but got Unknown
//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0400: Expected O, but got Unknown
//IL_050b: Unknown result type (might be due to invalid IL or missing references)
//IL_0515: Expected O, but got Unknown
//IL_0548: Unknown result type (might be due to invalid IL or missing references)
//IL_0552: Expected O, but got Unknown
//IL_0628: Unknown result type (might be due to invalid IL or missing references)
L = ((BasePlugin)this).Log;
Instance = this;
Enabled = ((BasePlugin)this).Config.Bind<bool>("1-General", "Enabled", true, "总开关。\nMaster switch.");
HideInMenus = ((BasePlugin)this).Config.Bind<bool>("1-General", "HideInMenus", true, "打开地图/ESC 菜单/结束时隐藏。\nHide while the map, menu or end screen is open.");
FollowFov = ((BasePlugin)this).Config.Bind<bool>("1-General", "FollowFov", true, "整体随距离和 FOV 缩放(开镜会放大)。\nScale with distance and FOV.");
HotReload = ((BasePlugin)this).Config.Bind<bool>("1-General", "HotReload", true, "改完 cfg 存盘后立即生效,不用重启游戏(每秒检查一次)。\nReload the config live: saved edits apply within a second, no restart.");
ShowClip = ((BasePlugin)this).Config.Bind<bool>("2-Content", "ShowClip", true, "显示弹匣数字。\nShow magazine count.");
ShowReserve = ((BasePlugin)this).Config.Bind<bool>("2-Content", "ShowReserve", true, "显示备弹数字。\nShow reserve count.");
ShowBars = ((BasePlugin)this).Config.Bind<bool>("2-Content", "ShowBars", true, "显示分段弹药条。\nShow segmented ammo bars.");
BarCount = ((BasePlugin)this).Config.Bind<int>("2-Content", "BarCount", 4, new ConfigDescription("弹药条段数(0 = 不画)。\nNumber of ammo bars (0 = none).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 12), Array.Empty<object>()));
WidgetScale = ((BasePlugin)this).Config.Bind<float>("3-Size", "WidgetScale", 1f, new ConfigDescription("整体大小倍率,微调时优先改这个。\nOverall size multiplier; the easiest knob for sizing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 3f), Array.Empty<object>()));
ClipFontSize = ((BasePlugin)this).Config.Bind<float>("3-Size", "ClipFontSize", 46f, "弹匣数字字号。\nClip font size.");
ReserveFontSize = ((BasePlugin)this).Config.Bind<float>("3-Size", "ReserveFontSize", 26f, "备弹数字字号。\nReserve font size.");
BarWidth = ((BasePlugin)this).Config.Bind<float>("3-Size", "BarWidth", 5f, "弹药条每段宽度。\nBar width.");
BarGap = ((BasePlugin)this).Config.Bind<float>("3-Size", "BarGap", 6f, "弹药条段间距。\nGap between bars.");
BarHeight = ((BasePlugin)this).Config.Bind<float>("3-Size", "BarHeight", 38f, "弹药条高度。\nBar height.");
ReserveOffsetY = ((BasePlugin)this).Config.Bind<float>("3-Size", "ReserveOffsetY", -48f, "备弹相对弹匣数字的纵向偏移。\nReserve Y offset from the clip number.");
OffsetX = ((BasePlugin)this).Config.Bind<float>("4-Position", "OffsetX", -0.02f, "武器局部 X 偏移(米)。往枪身方向调大。\nWeapon-local X offset (m).");
OffsetY = ((BasePlugin)this).Config.Bind<float>("4-Position", "OffsetY", 0.02f, "武器局部 Y 偏移(米)。往上调大。\nWeapon-local Y offset (m).");
OffsetZ = ((BasePlugin)this).Config.Bind<float>("4-Position", "OffsetZ", 0.15f, "武器局部 Z 偏移(米)。往远处调大。\nWeapon-local Z offset (m).");
ScreenOffsetX = ((BasePlugin)this).Config.Bind<float>("4-Position", "ScreenOffsetX", 0f, "屏幕像素微调 X(腰射)。\nScreen-space X offset in pixels (hip fire).");
ScreenOffsetY = ((BasePlugin)this).Config.Bind<float>("4-Position", "ScreenOffsetY", 0f, "屏幕像素微调 Y(腰射)。\nScreen-space Y offset in pixels (hip fire).");
ClipColor = ((BasePlugin)this).Config.Bind<string>("5-Style", "ClipColor", "#FFFFFF", "弹匣数字颜色(#RRGGBB)。\nClip colour (#RRGGBB).");
ReserveColor = ((BasePlugin)this).Config.Bind<string>("5-Style", "ReserveColor", "#D0D0D0", "备弹数字颜色。\nReserve colour.");
LowColor = ((BasePlugin)this).Config.Bind<string>("5-Style", "LowColor", "#FF4A3D", "低弹时的颜色。\nLow-ammo colour.");
LowPercent = ((BasePlugin)this).Config.Bind<int>("5-Style", "LowPercent", 25, new ConfigDescription("弹匣剩余百分比 ≤ 该值时变红。\nTurns red when the magazine is at or below this percentage.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
Opacity = ((BasePlugin)this).Config.Bind<float>("5-Style", "Opacity", 0.85f, new ConfigDescription("整体不透明度(1 = 完全不透明)。\nOverall opacity (1 = fully opaque).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()));
OutlineWidth = ((BasePlugin)this).Config.Bind<float>("5-Style", "OutlineWidth", 0.15f, new ConfigDescription("文字描边宽度(0 = 关闭)。\nText outline width (0 = off).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
ReferenceDistance = ((BasePlugin)this).Config.Bind<float>("6-Scaling", "ReferenceDistance", 0.55f, "缩放参考距离(米)。\nReference distance (m).");
ReferenceFov = ((BasePlugin)this).Config.Bind<float>("6-Scaling", "ReferenceFov", 60f, "缩放参考 FOV。\nReference FOV.");
MinScale = ((BasePlugin)this).Config.Bind<float>("6-Scaling", "MinScale", 0.35f, "最小缩放。\nMinimum scale.");
MaxScale = ((BasePlugin)this).Config.Bind<float>("6-Scaling", "MaxScale", 2.2f, "最大缩放。\nMaximum scale.");
SmoothSpeed = ((BasePlugin)this).Config.Bind<float>("6-Scaling", "SmoothSpeed", 14f, "位置/缩放平滑速度,越大越跟手(8 更飘,20 几乎无延迟)。\nSmoothing speed; higher follows faster.");
AdsFovThreshold = ((BasePlugin)this).Config.Bind<float>("7-ADS", "AdsFovThreshold", 55f, "FOV 低于该值判定为开镜。\nFOV below which aiming down sights is detected.");
AdsViewportX = ((BasePlugin)this).Config.Bind<float>("7-ADS", "ViewportX", 0.3f, new ConfigDescription("开镜时 UI 的横向位置(屏宽百分比,0=最左)。\nADS anchor as a fraction of screen width.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
AdsViewportY = ((BasePlugin)this).Config.Bind<float>("7-ADS", "ViewportY", 0.17f, new ConfigDescription("开镜时 UI 的纵向位置(屏高百分比,0=最下)。\nADS anchor as a fraction of screen height.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
AdsOffsetX = ((BasePlugin)this).Config.Bind<float>("7-ADS", "AdsOffsetX", 0f, "开镜位置额外的像素偏移 X。\nExtra ADS pixel offset X.");
AdsOffsetY = ((BasePlugin)this).Config.Bind<float>("7-ADS", "AdsOffsetY", 0f, "开镜位置额外的像素偏移 Y。\nExtra ADS pixel offset Y.");
AdsScale = ((BasePlugin)this).Config.Bind<float>("7-ADS", "AdsScale", 0.85f, "开镜时的额外缩放倍率。\nExtra scale multiplier while aiming.");
EmpEnabled = ((BasePlugin)this).Config.Bind<bool>("8-EMP", "Enabled", true, "检测 EMP MOD 的压制状态。\nDetect the EMP mod's suppression state.");
EmpIgnore = ((BasePlugin)this).Config.Bind<bool>("8-EMP", "IgnoreEMP", false, "true = EMP 期间仍然显示本 UI;false = 跟随游戏一起被禁用(默认)。\ntrue = keep this UI visible during EMP; false = hide it like the rest of the HUD (default).");
DebugLog = ((BasePlugin)this).Config.Bind<bool>("9-Debug", "LogEveryTwoSeconds", false, "每两秒把状态打到日志(排查用,平时关掉)。\nLog state every two seconds (debugging only).");
try
{
new Harmony("AdvancedBIOCOM").PatchAll(typeof(HudVisibilityPatch));
L.LogInfo((object)"[BIOCOM] Harmony patch applied (PlayerGuiLayer.SetVisible).");
}
catch (Exception ex)
{
L.LogWarning((object)("[BIOCOM] Harmony patch failed: " + ex.Message));
}
L.LogInfo((object)"[BIOCOM] v1.0.0 loaded.");
((BasePlugin)this).AddComponent<HoloAmmoBehaviour>();
}
}
public class HoloAmmoBehaviour : MonoBehaviour
{
private RectTransform _canvasRect;
private RectTransform _root;
private TextMeshProUGUI _clip;
private TextMeshProUGUI _reserve;
private Image[] _bars;
private Sprite _barSprite;
private Vector2 _smoothPos;
private float _smoothScale = 1f;
private Vector2 _targetPos;
private float _targetScale = 1f;
private bool _wasVisible;
private float _logTimer;
private bool _warned;
private string _lastGate = "";
internal static bool HudVisible = true;
private string _cfgPath;
private DateTime _cfgStamp;
private float _cfgTimer;
private int _lastClip = int.MinValue;
private int _lastClipMax = int.MinValue;
private int _lastReserve = int.MinValue;
private bool _lastLow;
private bool _lastReloading;
private bool _colorsReady;
private Color _cClip = Color.white;
private Color _cReserve = Color.gray;
private Color _cLow = Color.red;
private float _empPoll;
private bool _empCached;
private IntPtr _cachedItemPtr;
private BulletWeapon _cachedBullet;
private bool _hasCachedItem;
private float _reservePoll;
private int _cachedReserve = -1;
private static bool _empResolved;
private static object _empHudInstance;
private static MethodInfo _empIsEmped;
private static bool _empLast;
private static float _empRetryAt;
private static float _empClock;
private static Color Parse(string hex, Color fallback)
{
//IL_001b: 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_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
try
{
Color result = default(Color);
if (!string.IsNullOrEmpty(hex) && ColorUtility.TryParseHtmlString(hex, ref result))
{
return result;
}
}
catch
{
}
return fallback;
}
private void LateUpdate()
{
//IL_028e: Unknown result type (might be due to invalid IL or missing references)
//IL_0294: Unknown result type (might be due to invalid IL or missing references)
//IL_029b: Unknown result type (might be due to invalid IL or missing references)
//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
//IL_024c: Unknown result type (might be due to invalid IL or missing references)
//IL_0251: Unknown result type (might be due to invalid IL or missing references)
//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
//IL_02db: Unknown result type (might be due to invalid IL or missing references)
//IL_0302: Unknown result type (might be due to invalid IL or missing references)
//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0336: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!Plugin.Enabled.Value)
{
Hide();
return;
}
CheckConfigReload();
if (!EnsureUi())
{
return;
}
PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
if ((Object)(object)localPlayerAgent == (Object)null)
{
Hide();
return;
}
FirstPersonItemHolder fPItemHolder = localPlayerAgent.FPItemHolder;
ItemEquippable val = ((fPItemHolder != null) ? fPItemHolder.WieldedItem : null);
if ((Object)(object)val == (Object)null)
{
Hide();
return;
}
IntPtr pointer = ((Il2CppObjectBase)val).Pointer;
if (!_hasCachedItem || pointer != _cachedItemPtr)
{
_cachedItemPtr = pointer;
_cachedBullet = ((Il2CppObjectBase)val).TryCast<BulletWeapon>();
_hasCachedItem = true;
}
BulletWeapon cachedBullet = _cachedBullet;
if ((Object)(object)cachedBullet == (Object)null)
{
Hide();
return;
}
if (Plugin.DebugLog.Value)
{
_logTimer += Time.deltaTime;
if (_logTimer >= 2f)
{
_logTimer = 0f;
Plugin.L.LogInfo((object)string.Format("[BIOCOM] state: hudVisible={0} focus={1} gate={2}", HudVisible, Application.isFocused, Gate() ?? "-"));
}
}
if (Plugin.HideInMenus.Value)
{
string text = Gate();
if (text != null)
{
if (_lastGate != text)
{
_lastGate = text;
Plugin.L.LogInfo((object)("[BIOCOM] hidden by: " + text));
}
Hide();
return;
}
_lastGate = "";
}
int currentClip = ((ItemEquippable)cachedBullet).GetCurrentClip();
int maxClip = ((ItemEquippable)cachedBullet).GetMaxClip();
_reservePoll += Time.deltaTime;
if (_reservePoll >= 0.1f)
{
_reservePoll = 0f;
_cachedReserve = Reserve(val);
}
int cachedReserve = _cachedReserve;
bool low = maxClip > 0 && (float)currentClip * 100f / (float)maxClip <= (float)Plugin.LowPercent.Value;
bool isReloading = val.IsReloading;
UpdateVisuals(currentClip, maxClip, cachedReserve, low, isReloading);
if (!Position(val, out var cam))
{
Hide();
return;
}
((Component)_root).gameObject.SetActive(true);
ApplyScale(cam, val);
if (!_wasVisible)
{
_smoothPos = _targetPos;
_smoothScale = _targetScale;
}
else
{
float num = 1f - Mathf.Exp((0f - Mathf.Max(0.01f, Plugin.SmoothSpeed.Value)) * Time.deltaTime);
_smoothPos = Vector2.Lerp(_smoothPos, _targetPos, num);
_smoothScale = Mathf.Lerp(_smoothScale, _targetScale, num);
}
_wasVisible = true;
Vector2 val2 = _root.anchoredPosition - _smoothPos;
if (((Vector2)(ref val2)).sqrMagnitude > 0.04f)
{
_root.anchoredPosition = _smoothPos;
}
if (Math.Abs(((Transform)_root).localScale.x - _smoothScale) > 0.002f)
{
((Transform)_root).localScale = new Vector3(_smoothScale, _smoothScale, 1f);
}
ProbeTick(cam, val, currentClip, maxClip, cachedReserve);
}
catch (Exception ex)
{
if (!_warned)
{
_warned = true;
Plugin.L.LogWarning((object)("[BIOCOM] tick failed: " + ex.GetType().Name + " " + ex.Message));
}
Hide();
}
}
private string Gate()
{
if (Plugin.EmpEnabled.Value && !Plugin.EmpIgnore.Value)
{
_empPoll += Time.deltaTime;
if (_empPoll >= 0.2f)
{
_empPoll = 0f;
_empCached = EmpActive();
}
if (_empCached)
{
return "emp";
}
}
if (!HudVisible)
{
return "hud-hidden";
}
if (!Application.isFocused)
{
return "unfocused";
}
return null;
}
private static bool EmpActive()
{
_empClock += Time.deltaTime;
if (!_empResolved || (_empHudInstance == null && _empClock >= _empRetryAt))
{
_empResolved = true;
_empRetryAt = _empClock + 10f;
try
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
if (assembly.GetName().Name != "Inas07.EOSExt.EMP")
{
continue;
}
Type type = assembly.GetType("EOSExt.EMP.Impl.Handlers.EMPPlayerHudHandler");
if (!(type == null))
{
PropertyInfo property = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);
if (!(property == null))
{
_empHudInstance = property.GetValue(null);
_empIsEmped = type.GetMethod("IsEMPed", BindingFlags.Instance | BindingFlags.Public);
Plugin.L.LogInfo((object)("[BIOCOM] EMP bridge: instance=" + (_empHudInstance != null) + " method=" + (_empIsEmped != null)));
}
}
break;
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[BIOCOM] EMP bridge failed: " + ex.Message));
}
}
if (_empHudInstance == null || _empIsEmped == null)
{
return false;
}
try
{
bool flag = (bool)_empIsEmped.Invoke(_empHudInstance, null);
if (flag != _empLast)
{
_empLast = flag;
Plugin.L.LogInfo((object)("[BIOCOM] EMP state -> " + (flag ? "suppressed" : "normal")));
}
return flag;
}
catch
{
return false;
}
}
private void CheckConfigReload()
{
if (!Plugin.HotReload.Value || Plugin.Instance == null)
{
return;
}
_cfgTimer += Time.deltaTime;
if (_cfgTimer < 1f)
{
return;
}
_cfgTimer = 0f;
try
{
if (_cfgPath == null)
{
_cfgPath = ((BasePlugin)Plugin.Instance).Config.ConfigFilePath;
}
if (string.IsNullOrEmpty(_cfgPath) || !File.Exists(_cfgPath))
{
return;
}
DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(_cfgPath);
if (!(lastWriteTimeUtc == _cfgStamp))
{
bool num = _cfgStamp == default(DateTime);
_cfgStamp = lastWriteTimeUtc;
if (!num)
{
((BasePlugin)Plugin.Instance).Config.Reload();
RebuildUi();
Plugin.L.LogInfo((object)"[BIOCOM] config reloaded from disk.");
}
}
}
catch (Exception ex)
{
Plugin.L.LogWarning((object)("[BIOCOM] config reload failed: " + ex.Message));
}
}
private void RebuildUi()
{
try
{
if ((Object)(object)_root != (Object)null)
{
Object.Destroy((Object)(object)((Component)_root).gameObject);
}
}
catch
{
}
_root = null;
_clip = null;
_reserve = null;
_bars = null;
_wasVisible = false;
_colorsReady = false;
_lastClip = int.MinValue;
}
private void ProbeTick(Camera cam, ItemEquippable item, int clip, int clipMax, int reserve)
{
if (Plugin.DebugLog.Value)
{
_logTimer += Time.deltaTime;
if (!(_logTimer < 2f))
{
_logTimer = 0f;
Plugin.L.LogInfo((object)$"[BIOCOM] clip={clip}/{clipMax} reserve={reserve} fov={cam.fieldOfView:0.0} ads={AdsBlend(cam):0.00} scale={_smoothScale:0.00} pos=({_smoothPos.x:0},{_smoothPos.y:0}) hudVisible={HudVisible} focus={Application.isFocused}");
}
}
}
private void UpdateVisuals(int clip, int clipMax, int reserve, bool low, bool reloading)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//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_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_028f: Unknown result type (might be due to invalid IL or missing references)
//IL_026f: Unknown result type (might be due to invalid IL or missing references)
//IL_0275: Unknown result type (might be due to invalid IL or missing references)
//IL_027b: Unknown result type (might be due to invalid IL or missing references)
//IL_0288: Unknown result type (might be due to invalid IL or missing references)
//IL_0290: Unknown result type (might be due to invalid IL or missing references)
//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
if (!_colorsReady)
{
_cClip = Parse(Plugin.ClipColor.Value, Color.white);
_cReserve = Parse(Plugin.ReserveColor.Value, Color.gray);
_cLow = Parse(Plugin.LowColor.Value, Color.red);
_colorsReady = true;
_lastClip = int.MinValue;
_lastReserve = int.MinValue;
_lastLow = !low;
}
float num = Mathf.Clamp01(Plugin.Opacity.Value);
Color val = (low ? _cLow : _cClip);
Color cReserve = _cReserve;
val.a *= num;
cReserve.a *= num;
bool flag = clip != _lastClip || clipMax != _lastClipMax;
bool num2 = reserve != _lastReserve;
bool flag2 = low != _lastLow;
if (flag)
{
((TMP_Text)_clip).text = (Plugin.ShowClip.Value ? clip.ToString(CultureInfo.InvariantCulture) : "");
LayoutBars();
}
if (flag || flag2)
{
((Graphic)_clip).color = val;
((Component)_clip).gameObject.SetActive(Plugin.ShowClip.Value);
}
bool flag3 = Plugin.ShowReserve.Value && reserve >= 0;
if (num2 || flag2 || flag)
{
((TMP_Text)_reserve).text = (flag3 ? reserve.ToString(CultureInfo.InvariantCulture) : "");
((Graphic)_reserve).color = cReserve;
((Component)_reserve).gameObject.SetActive(flag3);
}
_lastClip = clip;
_lastClipMax = clipMax;
_lastReserve = reserve;
_lastLow = low;
if (_bars == null || (!(flag || flag2 || reloading) && !_lastReloading))
{
return;
}
int num3 = Mathf.CeilToInt(((clipMax > 0) ? Mathf.Clamp01((float)clip / (float)clipMax) : 0f) * (float)_bars.Length);
float num4 = (reloading ? (0.35f + 0.65f * Mathf.PingPong(Time.time * 2.5f, 1f)) : 1f);
bool value = Plugin.ShowBars.Value;
for (int i = 0; i < _bars.Length; i++)
{
Image val2 = _bars[i];
if (!((Object)(object)val2 == (Object)null))
{
Color color = (Color)((i < num3) ? val : new Color(val.r, val.g, val.b, 0.18f * num));
color.a *= num4;
((Graphic)val2).color = color;
((Component)val2).gameObject.SetActive(value);
}
}
_lastReloading = reloading;
}
private void LayoutBars()
{
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
if (_bars == null || _bars.Length == 0)
{
return;
}
float value = Plugin.BarWidth.Value;
float value2 = Plugin.BarGap.Value;
float num = ((TMP_Text)_clip).preferredWidth + value2;
for (int i = 0; i < _bars.Length; i++)
{
Image val = _bars[i];
if (!((Object)(object)val == (Object)null))
{
((Graphic)val).rectTransform.anchoredPosition = new Vector2(num + (float)i * (value + value2), 0f);
}
}
}
private static float AdsBlend(Camera cam)
{
if ((Object)(object)cam == (Object)null)
{
return 0f;
}
if (!(cam.fieldOfView < Plugin.AdsFovThreshold.Value))
{
return 0f;
}
return 1f;
}
private static int Reserve(ItemEquippable item)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
try
{
PlayerBackpack localBackpack = PlayerBackpackManager.LocalBackpack;
if (localBackpack == null)
{
return -1;
}
PlayerAmmoStorage ammoStorage = localBackpack.AmmoStorage;
if (ammoStorage == null)
{
return -1;
}
return ammoStorage.GetBulletsInPack(item.AmmoType);
}
catch
{
return -1;
}
}
private bool EnsureUi()
{
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Expected O, but got Unknown
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Expected O, but got Unknown
//IL_018b: Unknown result type (might be due to invalid IL or missing references)
//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0207: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_022a: Unknown result type (might be due to invalid IL or missing references)
//IL_023f: Unknown result type (might be due to invalid IL or missing references)
//IL_0254: Unknown result type (might be due to invalid IL or missing references)
//IL_0273: Unknown result type (might be due to invalid IL or missing references)
//IL_029b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_clip != (Object)null && (Object)(object)_root != (Object)null)
{
return true;
}
if ((Object)(object)_canvasRect == (Object)null)
{
GameObject val = new GameObject("HoloAmmoCanvas");
Object.DontDestroyOnLoad((Object)(object)val);
Canvas obj = val.AddComponent<Canvas>();
obj.renderMode = (RenderMode)0;
obj.sortingOrder = 100;
CanvasScaler obj2 = val.AddComponent<CanvasScaler>();
obj2.uiScaleMode = (ScaleMode)1;
obj2.referenceResolution = new Vector2(1920f, 1080f);
obj2.matchWidthOrHeight = 0.5f;
_canvasRect = val.GetComponent<RectTransform>();
}
GameObject val2 = new GameObject("HoloAmmoRoot");
_root = val2.AddComponent<RectTransform>();
((Transform)_root).SetParent((Transform)(object)_canvasRect, false);
_root.anchorMin = new Vector2(0.5f, 0.5f);
_root.anchorMax = new Vector2(0.5f, 0.5f);
_root.pivot = new Vector2(0f, 0.5f);
_root.sizeDelta = new Vector2(240f, 160f);
_clip = MakeText("Clip", _root, Plugin.ClipFontSize.Value);
_reserve = MakeText("Reserve", _root, Plugin.ReserveFontSize.Value);
((TMP_Text)_reserve).rectTransform.anchoredPosition = new Vector2(2f, Plugin.ReserveOffsetY.Value);
Texture2D val3 = new Texture2D(1, 1);
val3.SetPixel(0, 0, Color.white);
val3.Apply();
_barSprite = Sprite.Create(val3, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f));
int num = Mathf.Clamp(Plugin.BarCount.Value, 0, 12);
_bars = (Image[])(object)new Image[num];
for (int i = 0; i < num; i++)
{
GameObject val4 = new GameObject("Bar" + i);
RectTransform obj3 = val4.AddComponent<RectTransform>();
((Transform)obj3).SetParent((Transform)(object)_root, false);
obj3.anchorMin = new Vector2(0f, 0.5f);
obj3.anchorMax = new Vector2(0f, 0.5f);
obj3.pivot = new Vector2(0f, 0.5f);
obj3.sizeDelta = new Vector2(Plugin.BarWidth.Value, Plugin.BarHeight.Value);
obj3.anchoredPosition = new Vector2((float)i * (Plugin.BarWidth.Value + Plugin.BarGap.Value), 0f);
Image val5 = val4.AddComponent<Image>();
val5.sprite = _barSprite;
((Graphic)val5).raycastTarget = false;
_bars[i] = val5;
}
Plugin.L.LogInfo((object)("[BIOCOM] UI built (bars=" + num + ")."));
return true;
}
private TextMeshProUGUI MakeText(string name, RectTransform parent, float size)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(name);
RectTransform obj = val.AddComponent<RectTransform>();
((Transform)obj).SetParent((Transform)(object)parent, false);
obj.anchorMin = new Vector2(0f, 0.5f);
obj.anchorMax = new Vector2(0f, 0.5f);
obj.pivot = new Vector2(0f, 0.5f);
obj.sizeDelta = new Vector2(200f, 80f);
TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)val2).font = TMP_Settings.defaultFontAsset;
if ((Object)(object)((TMP_Text)val2).font == (Object)null)
{
Plugin.L.LogWarning((object)"[BIOCOM] TMP default font asset is null.");
}
((TMP_Text)val2).fontSize = size;
((Graphic)val2).color = Color.white;
((TMP_Text)val2).alignment = (TextAlignmentOptions)513;
((TMP_Text)val2).enableWordWrapping = false;
((Graphic)val2).raycastTarget = false;
((TMP_Text)val2).text = "0";
float value = Plugin.OutlineWidth.Value;
if (value > 0f)
{
try
{
((TMP_Text)val2).outlineWidth = value;
((TMP_Text)val2).outlineColor = new Color32((byte)0, (byte)0, (byte)0, (byte)170);
}
catch
{
}
}
return val2;
}
private void Hide()
{
_wasVisible = false;
if ((Object)(object)_root != (Object)null && ((Component)_root).gameObject.activeSelf)
{
((Component)_root).gameObject.SetActive(false);
}
}
private static float Distance(Camera cam, ItemEquippable item)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
return Vector3.Distance(((Component)cam).transform.position, ((Component)item).transform.position);
}
private void ApplyScale(Camera cam, ItemEquippable item)
{
float num = 1f;
if (Plugin.FollowFov.Value)
{
float num2 = Mathf.Max(0.05f, Distance(cam, item));
float num3 = Mathf.Max(1f, cam.fieldOfView);
float num4 = Mathf.Tan(Plugin.ReferenceFov.Value * 0.5f * ((float)Math.PI / 180f));
float num5 = Mathf.Tan(num3 * 0.5f * ((float)Math.PI / 180f));
num = Plugin.ReferenceDistance.Value / num2 * (num4 / num5);
}
float num6 = AdsBlend(cam);
if (num6 > 0f)
{
num *= Mathf.Lerp(1f, Plugin.AdsScale.Value, num6);
}
num *= Plugin.WidgetScale.Value;
_targetScale = Mathf.Clamp(num, Plugin.MinScale.Value, Plugin.MaxScale.Value);
}
private bool Position(ItemEquippable item, out Camera cam)
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
cam = Camera.main;
if ((Object)(object)cam == (Object)null)
{
Il2CppReferenceArray<Camera> allCameras = Camera.allCameras;
if (allCameras != null && ((Il2CppArrayBase<Camera>)(object)allCameras).Length > 0)
{
cam = ((Il2CppArrayBase<Camera>)(object)allCameras)[0];
}
}
if ((Object)(object)cam == (Object)null)
{
return false;
}
Vector3 val = ((Component)item).transform.TransformPoint(new Vector3(Plugin.OffsetX.Value, Plugin.OffsetY.Value, Plugin.OffsetZ.Value));
Vector3 val2 = cam.WorldToScreenPoint(val);
if (val2.z <= 0.05f)
{
return false;
}
Vector2 val3 = default(Vector2);
((Vector2)(ref val3))..ctor(val2.x + Plugin.ScreenOffsetX.Value, val2.y + Plugin.ScreenOffsetY.Value);
float num = AdsBlend(cam);
if (num > 0f)
{
Vector2 val4 = default(Vector2);
((Vector2)(ref val4))..ctor((float)Screen.width * Plugin.AdsViewportX.Value + Plugin.AdsOffsetX.Value, (float)Screen.height * Plugin.AdsViewportY.Value + Plugin.AdsOffsetY.Value);
val3 = Vector2.Lerp(val3, val4, num);
}
Vector2 targetPos = default(Vector2);
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(_canvasRect, val3, (Camera)null, ref targetPos))
{
return false;
}
_targetPos = targetPos;
return true;
}
}
[HarmonyPatch(typeof(PlayerGuiLayer), "SetVisible")]
internal static class HudVisibilityPatch
{
[HarmonyPostfix]
private static void Postfix(bool visible)
{
HoloAmmoBehaviour.HudVisible = visible;
try
{
Plugin.L.LogDebug((object)("[BIOCOM] PlayerGuiLayer.SetVisible(" + visible + ")"));
}
catch
{
}
}
}