using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("StatsUITweaks")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.0.0")]
[module: UnverifiableCode]
namespace StatsUITweaks;
public class PerformancePanelPatch
{
private static bool initialized;
private static UIButton foldBtn;
private static bool folded;
private static float scrollHeight = 398f;
private static float scrollY = 23.5f;
[HarmonyPostfix]
[HarmonyPatch(typeof(UIPerformancePanel), "_OnOpen")]
public static void Init(UIPerformancePanel __instance)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
if (initialized)
{
return;
}
try
{
GameObject obj = Object.Instantiate<GameObject>(((Component)UIRoot.instance.uiGame.researchQueue.pauseButton).gameObject, ((Component)__instance).transform);
((Object)obj).name = "CustomStats_Fold";
obj.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
obj.transform.localPosition = new Vector3(-550f, 390f, 0f);
Transform obj2 = obj.transform.Find("icon");
Image val = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
if ((Object)(object)val != (Object)null)
{
UIStarmap starmap = UIRoot.instance.uiGame.starmap;
Transform obj3 = ((Component)starmap.cursorFunctionButton2).transform.Find("icon");
object sprite;
if (obj3 == null)
{
sprite = null;
}
else
{
Image component = ((Component)obj3).GetComponent<Image>();
sprite = ((component != null) ? component.sprite : null);
}
val.sprite = (Sprite)sprite;
}
foldBtn = obj.GetComponent<UIButton>();
foldBtn.tips.tipTitle = "Fold 折叠饼图";
foldBtn.tips.tipText = "Click to fold/unfold pie chart";
foldBtn.onClick += OnFoldButtonClick;
if (foldBtn.transitions != null)
{
foldBtn.transitions[0].highlightColorOverride = new Color(0.5f, 0.6f, 0.7f, 0.1f);
}
obj.SetActive(true);
scrollHeight = __instance.cpuScrollRect.rectTransform.sizeDelta.y;
scrollY = ((Component)__instance.cpuScrollRect).transform.localPosition.y;
initialized = true;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)"PerformancePanelPatch initial fail!");
Plugin.Log.LogError((object)ex);
}
Toggle(folded);
}
public static void OnDestory()
{
Toggle(extendScroll: false);
UIButton obj = foldBtn;
Object.Destroy((Object)(object)((obj != null) ? ((Component)obj).gameObject : null));
initialized = false;
}
private static void OnFoldButtonClick(int obj)
{
folded = !folded;
foldBtn.highlighted = folded;
Toggle(folded);
}
private static void Toggle(bool extendScroll)
{
if (initialized)
{
UIPerformancePanel performancePanelUI = UIRoot.instance.uiGame.statWindow.performancePanelUI;
Adjust(performancePanelUI.cpuScrollRect.rectTransform, extendScroll);
Adjust(performancePanelUI.gpuScrollRect.rectTransform, extendScroll);
Adjust(performancePanelUI.dataScrollRect.rectTransform, extendScroll);
}
}
private static void Adjust(RectTransform scrollRect, bool extendScroll)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: 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_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
foreach (Transform item in ((Transform)scrollRect).parent)
{
((Component)item).gameObject.SetActive(!extendScroll);
}
((Component)scrollRect).gameObject.SetActive(true);
((Transform)scrollRect).localPosition = new Vector3(((Transform)scrollRect).localPosition.x, extendScroll ? (scrollY + 362f) : scrollY, 0f);
scrollRect.sizeDelta = new Vector2(scrollRect.sizeDelta.x, extendScroll ? (scrollHeight + 372f) : scrollHeight);
}
}
public class PlanetNamePatch
{
[HarmonyPrefix]
[HarmonyPatch(typeof(PlanetData), "RegenerateName")]
private static void RegenerateName(PlanetData __instance, bool notifychange, ref bool __runOriginal)
{
if (__runOriginal)
{
string text = (__instance.index + 1).ToString();
__instance.name = __instance.star.displayName + " " + text + Localization.Translate("号星");
if (notifychange && string.IsNullOrEmpty(__instance.overrideName))
{
__instance.NotifyOnDisplayNameChange();
}
__runOriginal = false;
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(GalaxyData), "RegeneratePlanetNames")]
private static void RegenerateName(GalaxyData __instance, ref bool __runOriginal)
{
if (__runOriginal)
{
StarData[] stars = __instance.stars;
for (int i = 0; i < stars.Length; i++)
{
stars[i].RegeneratePlanetNames(false);
}
__runOriginal = false;
}
}
}
[BepInPlugin("starfi5h.plugin.StatsUITweaks", "StatsUITweaks", "1.5.0")]
public class Plugin : BaseUnityPlugin
{
public const string GUID = "starfi5h.plugin.StatsUITweaks";
public const string NAME = "StatsUITweaks";
public const string VERSION = "1.5.0";
public static ManualLogSource Log;
public static ConfigEntry<bool> DisplayPerSecond;
private static Harmony harmony;
public void Awake()
{
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Expected O, but got Unknown
//IL_01c6: 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_01d0: Unknown result type (might be due to invalid IL or missing references)
//IL_01d5: 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_0246: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("AstroBox", "OrderByName", true, "Order list by system name.\n以星系名称排序列表");
ConfigEntry<int> val2 = ((BaseUnityPlugin)this).Config.Bind<int>("AstroBox", "DropDownCount", 15, "Number of items shown in drop-down list.\n下拉列表显示的个数");
ConfigEntry<string> val3 = ((BaseUnityPlugin)this).Config.Bind<string>("AstroBox", "SystemPrefix", "<color=yellow>", "Prefix string of star system in the list\n星系名称前缀");
ConfigEntry<string> val4 = ((BaseUnityPlugin)this).Config.Bind<string>("AstroBox", "SystemPostfix", "</color>", "Postfix string of star system in the list\n星系名称后缀");
ConfigEntry<string> val5 = ((BaseUnityPlugin)this).Config.Bind<string>("AstroBox", "PlanetPrefix", "ㅤ", "Prefix string of planet in the list\n星球名称前缀");
ConfigEntry<string> obj = ((BaseUnityPlugin)this).Config.Bind<string>("AstroBox", "PlanetPostfix", "", "Postfix string of planet in the list\n星球名称后缀");
ConfigEntry<KeyCode> val6 = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("AstroBox", "HotkeyListUp", (KeyCode)280, "Move to previous item in list.\n切换至列表中上一个项目");
ConfigEntry<KeyCode> obj2 = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("AstroBox", "HotkeyListDown", (KeyCode)281, "Move to next item in list.\n切换至列表中下一个项目");
ConfigEntry<int> val7 = ((BaseUnityPlugin)this).Config.Bind<int>("StatsUITweaks", "SignificantDigits", 0, new ConfigDescription("Significant figures of production/consumption (Default=0)\n产量有效位数(默认=0)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
ConfigEntry<int> val8 = ((BaseUnityPlugin)this).Config.Bind<int>("StatsUITweaks", "TimeSliderSlice", 20, "The number of divisions of the time range slider.\n时间范围滑杆的分割数");
ConfigEntry<int> val9 = ((BaseUnityPlugin)this).Config.Bind<int>("StatsUITweaks", "ListWidthOffeset", 70, "Increase width of the list.\n增加列表栏位宽度");
ConfigEntry<bool> val10 = ((BaseUnityPlugin)this).Config.Bind<bool>("StatsUITweaks", "NumericPlanetNo", false, "Convert planet no. from Roman numerals to numbers.\n将星球序号从罗马数字转为十进位数字");
ConfigEntry<bool> val11 = ((BaseUnityPlugin)this).Config.Bind<bool>("PerformancePanel", "FoldButton", true, "Add a button to fold pie chart.\n在性能面板加入一个折叠饼图的按钮");
BottleneckCompat();
Utils.OrderByName = val.Value;
Utils.DropDownCount = val2.Value;
Utils.HotkeyListUp = val6.Value;
Utils.HotkeyListDown = obj2.Value;
Utils.SystemPrefix = val3.Value;
Utils.SystemPostfix = val4.Value;
Utils.PlanetPrefix = val5.Value;
Utils.PlanetPostfix = obj.Value;
StatsWindowPatch.SignificantDigits = ((val7.Value > 0) ? val7.Value : 0);
StatsWindowPatch.TimeSliderSlice = val8.Value;
StatsWindowPatch.ListWidthOffeset = val9.Value;
harmony = new Harmony("starfi5h.plugin.StatsUITweaks");
harmony.PatchAll(typeof(StatsWindowPatch));
if (val10.Value)
{
harmony.PatchAll(typeof(PlanetNamePatch));
}
if (val11.Value)
{
harmony.PatchAll(typeof(PerformancePanelPatch));
}
harmony.PatchAll(typeof(UIControlPanelPatch));
}
private static void BottleneckCompat()
{
if (!Chainloader.PluginInfos.TryGetValue("Bottleneck", out var value))
{
return;
}
try
{
DisplayPerSecond = (ConfigEntry<bool>)(AccessTools.Field(((object)value.Instance).GetType().Assembly.GetType("Bottleneck.PluginConfig"), "displayPerSecond")?.GetValue(null) ?? null);
}
catch (Exception ex)
{
Log.LogWarning((object)"Can't find Bottleneck.PluginConfig.displayPerSecond");
Log.LogWarning((object)ex);
}
}
}
public class StatsWindowPatch
{
private struct Data
{
public long production;
public long consumption;
}
public static int SignificantDigits = 0;
public static int TimeSliderSlice = 20;
public static int ListWidthOffeset = 70;
private static bool initialized;
private static bool enable;
private static Slider timerSlider;
private static InputField filterInput;
private static UIButton locateBtn;
private static GameObject filterGo;
private static string searchStr = "";
private static float ratio = 1f;
private static readonly Dictionary<long[], Data> dict = new Dictionary<long[], Data>();
private static readonly string[] formatF = new string[11]
{
"F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9",
"F10"
};
[HarmonyPostfix]
[HarmonyPatch(typeof(UIStatisticsWindow), "_OnOpen")]
public static void Init(UIStatisticsWindow __instance)
{
//IL_022f: Unknown result type (might be due to invalid IL or missing references)
//IL_0249: Unknown result type (might be due to invalid IL or missing references)
//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0353: Unknown result type (might be due to invalid IL or missing references)
//IL_0358: Unknown result type (might be due to invalid IL or missing references)
//IL_0367: Unknown result type (might be due to invalid IL or missing references)
//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: 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)
if (initialized)
{
return;
}
initialized = true;
try
{
if (ListWidthOffeset > 0)
{
Reposition(((Component)__instance.productAstroBox).transform, ((Component)__instance.productTimeBox).transform);
if (ListWidthOffeset > 40)
{
((RectTransform)((Component)__instance.productSortBox).transform).sizeDelta = new Vector2(200f - (float)(ListWidthOffeset - 40), 30f);
((Component)__instance.productSortBox).transform.localPosition = new Vector3(135f - (float)(ListWidthOffeset - 40), ((Component)__instance.productSortBox).transform.localPosition.y);
}
Reposition(((Component)__instance.powerAstroBox).transform, ((Component)__instance.powerTimeBox).transform);
Reposition(((Component)__instance.researchAstroBox).transform, ((Component)__instance.researchTimeBox).transform);
Reposition(((Component)__instance.dysonAstroBox).transform, ((Component)__instance.dysonTimeBox).transform);
Reposition(((Component)__instance.killAstroBox).transform, ((Component)__instance.killTimeBox).transform);
if (ListWidthOffeset > 40)
{
((RectTransform)((Component)__instance.killSortBox).transform).sizeDelta = new Vector2(200f - (float)(ListWidthOffeset - 40), 30f);
((Component)__instance.killSortBox).transform.localPosition = new Vector3(135f - (float)(ListWidthOffeset - 40), ((Component)__instance.killSortBox).transform.localPosition.y);
}
}
Utils.EnableRichText(__instance.productAstroBox);
Utils.EnableRichText(__instance.powerAstroBox);
Utils.EnableRichText(__instance.researchAstroBox);
Utils.EnableRichText(__instance.dysonAstroBox);
Utils.EnableRichText(__instance.killAstroBox);
Slider slider = UIRoot.instance.uiGame.dysonEditor.controlPanel.inspector.layerInfo.slider0;
GameObject val = GameObject.Find("UI Root/Overlay Canvas/In Game/Windows/Control Panel Window/filter-group/sub-group/search-filter");
UIButton pauseButton = UIRoot.instance.uiGame.researchQueue.pauseButton;
GameObject obj = Object.Instantiate<GameObject>(((Component)slider).gameObject, ((Component)__instance.productTimeBox).transform);
((Object)obj).name = "CustomStats_Ratio";
obj.transform.localPosition = new Vector3(-153f, 8f, 0f);
obj.GetComponent<RectTransform>().sizeDelta = new Vector2(155.5f, 13f);
timerSlider = obj.GetComponent<Slider>();
timerSlider.minValue = 0f;
timerSlider.maxValue = TimeSliderSlice;
timerSlider.wholeNumbers = true;
timerSlider.value = timerSlider.maxValue;
((UnityEvent<float>)(object)timerSlider.onValueChanged).AddListener((UnityAction<float>)OnSliderChange);
obj.SetActive(true);
filterGo = Object.Instantiate<GameObject>(val, ((Component)__instance.productAstroBox).transform);
((Object)filterGo).name = "CustomStats_Fliter";
filterGo.transform.localPosition = new Vector3(0f, 20f, 0f);
filterInput = filterGo.GetComponentInChildren<InputField>();
filterInput.text = "";
((UnityEvent<string>)(object)filterInput.onValueChanged).AddListener((UnityAction<string>)OnInputValueChanged);
filterGo.GetComponent<RectTransform>().sizeDelta = new Vector2(((RectTransform)((Component)__instance.productAstroBox).transform).sizeDelta.x, 28f);
filterGo.SetActive(true);
GameObject obj2 = Object.Instantiate<GameObject>(((Component)pauseButton).gameObject, ((Component)__instance.productAstroBox).transform);
((Object)obj2).name = "CustomStats_Navi";
obj2.transform.localScale = new Vector3(0.33f, 0.33f, 0.33f);
obj2.transform.localPosition = new Vector3(2f, -6f, 0f);
Transform obj3 = obj2.transform.Find("icon");
Image val2 = ((obj3 != null) ? ((Component)obj3).GetComponent<Image>() : null);
if ((Object)(object)val2 != (Object)null)
{
UIStarmap starmap = UIRoot.instance.uiGame.starmap;
Transform obj4 = ((Component)starmap.cursorFunctionButton3).transform.Find("icon");
object sprite;
if (obj4 == null)
{
sprite = null;
}
else
{
Image component = ((Component)obj4).GetComponent<Image>();
sprite = ((component != null) ? component.sprite : null);
}
val2.sprite = (Sprite)sprite;
}
locateBtn = obj2.GetComponent<UIButton>();
locateBtn.tips.tipTitle = "Locate";
locateBtn.tips.tipText = "Left click: Navigate to planet\nRight click: Show planet in starmap";
locateBtn.onClick += OnLocateButtonClick;
locateBtn.onRightClick += OnLocateButtonRightClick;
obj2.SetActive(true);
enable = true;
if ((Object)(object)__instance.astroBox != (Object)(object)__instance.productAstroBox)
{
OnTabButtonClick(__instance);
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)"UI component initial fail!");
Plugin.Log.LogError((object)ex);
}
static void Reposition(Transform astroBoxtTansform, Transform timeBoxTransform)
{
//IL_0001: 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_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
((RectTransform)astroBoxtTansform).sizeDelta = new Vector2(200f + (float)ListWidthOffeset, 30f);
timeBoxTransform.localPosition = new Vector3((float)(330 - ListWidthOffeset), timeBoxTransform.localPosition.y);
}
}
public static void OnDestory()
{
Slider obj = timerSlider;
Object.Destroy((Object)(object)((obj != null) ? ((Component)obj).gameObject : null));
InputField obj2 = filterInput;
Object.Destroy((Object)(object)((obj2 != null) ? ((Component)obj2).gameObject : null));
UIButton obj3 = locateBtn;
Object.Destroy((Object)(object)((obj3 != null) ? ((Component)obj3).gameObject : null));
Object.Destroy((Object)(object)filterGo);
initialized = false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIStatisticsWindow), "OnTabButtonClick")]
private static void OnTabButtonClick(UIStatisticsWindow __instance)
{
if (enable)
{
if ((Object)(object)__instance.timeBox != (Object)null)
{
((Component)timerSlider).gameObject.transform.SetParent(((Component)__instance.timeBox).transform);
}
if ((Object)(object)__instance.astroBox != (Object)null)
{
filterGo.transform.SetParent(((Component)__instance.astroBox).transform);
((Component)locateBtn).gameObject.transform.SetParent(((Component)__instance.astroBox).transform);
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIStatisticsWindow), "_OnUpdate")]
private static void OnUpdate(UIStatisticsWindow __instance)
{
if (__instance.isStatisticsTab)
{
Utils.DetermineAstroBoxIndex(__instance.astroBox);
}
}
private static void OnLocateButtonClick(int obj)
{
int astroFilter = UIRoot.instance.uiGame.statWindow.astroFilter;
if (astroFilter > 0)
{
GameMain.mainPlayer.navigation.indicatorAstroId = astroFilter;
}
}
private static void OnLocateButtonRightClick(int obj)
{
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
int astroFilter = UIRoot.instance.uiGame.statWindow.astroFilter;
if (astroFilter <= 0)
{
return;
}
UIRoot.instance.uiGame.OpenStarmap();
int num = astroFilter / 100 - 1;
int num2 = astroFilter % 100 - 1;
UIStarmap starmap = UIRoot.instance.uiGame.starmap;
if (num < 0 || num >= starmap.starUIs.Length)
{
return;
}
if (num2 >= 0)
{
PlanetData val = GameMain.galaxy.PlanetById(astroFilter);
if (val != null)
{
starmap.focusPlanet = null;
starmap.focusStar = starmap.starUIs[num];
starmap.OnCursorFunction2Click(0);
starmap.screenCameraController.SetViewTarget(val, (StarData)null, (EnemyDFHiveSystem)null, (Player)null, VectorLF3.zero, (double)val.realRadius * 0.00025 * 6.0, (double)val.realRadius * 0.00025 * 16.0, true, false);
}
}
else
{
starmap.focusPlanet = null;
starmap.focusStar = starmap.starUIs[num];
starmap.OnCursorFunction2Click(0);
}
}
private static void OnInputValueChanged(string value)
{
searchStr = value;
UIRoot.instance.uiGame.statWindow.RefreshAstroBox();
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UIStatisticsWindow), "ValueToAstroBox")]
[HarmonyAfter(new string[] { "Bottleneck" })]
private static void FilterList(UIStatisticsWindow __instance, ref int __state)
{
if (!__instance.isStatisticsTab)
{
return;
}
int startIndex = 1;
if (!__instance.isDysonTab && __instance.gameData.localPlanet != null)
{
startIndex = 2;
if (__instance.astroBox.Items.Count > 2 && (__instance.astroBox.Items[2] == "Local System" || __instance.astroBox.Items[2] == "本地系统" || __instance.astroBox.Items[2] == Localization.Translate("localSystemLabel")))
{
startIndex = 3;
}
}
Utils.UpdateAstroBox(__instance.astroBox, startIndex, searchStr);
__state = __instance.astroBox.itemIndex;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIStatisticsWindow), "ValueToAstroBox")]
private static void RestoreItemIndex(UIStatisticsWindow __instance, int __state)
{
if (!__instance.isStatisticsTab || (Object)(object)__instance.astroBox == (Object)null)
{
return;
}
try
{
int count = __instance.astroBox.ItemsData.Count;
if (__state != __instance.astroBox.itemIndex && __state >= 0 && __state < count && __instance.astroBox.itemIndex < count && __instance.astroBox.ItemsData[__state] == __instance.astroBox.ItemsData[__instance.astroBox.itemIndex])
{
__instance.astroBox.itemIndex = __state;
}
}
catch (Exception)
{
}
if ((Object)(object)locateBtn == (Object)null)
{
return;
}
int astroFilter = __instance.astroFilter;
if (astroFilter <= 0)
{
locateBtn.tips.tipTitle = "Locate";
return;
}
string text = "Locate " + astroFilter;
PlanetData val = GameMain.galaxy.PlanetById(astroFilter);
if (val?.factory != null)
{
text = text + " idx=" + val.factory.index;
}
locateBtn.tips.tipTitle = text;
}
private static void OnSliderChange(float value)
{
if (value < 1f)
{
timerSlider.value = 1f;
return;
}
ratio = value / timerSlider.maxValue;
UIRoot.instance.uiGame.statWindow.ComputeDisplayEntriesDetail();
if (ratio == 1f)
{
UIRoot.instance.uiGame.statWindow.ValueToTimeBox();
}
else
{
ChangeTimeBoxText(UIRoot.instance.uiGame.statWindow);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIStatisticsWindow), "ValueToTimeBox")]
private static void ChangeTimeBoxText(UIStatisticsWindow __instance)
{
if (ratio != 1f && __instance.isStatisticsTab)
{
string text = $" ({100f * ratio:N0}%)";
InputField input = UIRoot.instance.uiGame.statWindow.timeBox.m_Input;
switch (__instance.timeLevel)
{
case 0:
input.text = (int)(60f * ratio + 0.5f) + Localization.Translate("空格秒") + text;
break;
case 1:
input.text = (10f * ratio).ToString("F1") + Localization.Translate("空格分钟") + text;
break;
case 2:
input.text = (60f * ratio).ToString("F1") + Localization.Translate("空格分钟") + text;
break;
case 3:
input.text = (10f * ratio).ToString("F1") + Localization.Translate("统计10小时").Replace("10", " ") + text;
break;
case 4:
input.text = (100f * ratio).ToString("F1") + Localization.Translate("统计100小时").Replace("100", " ") + text;
break;
case 5:
input.text = Localization.Translate("统计总计") + text;
break;
}
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UIStatisticsWindow), "ComputeDisplayEntriesDetail")]
private static void ClearData()
{
dict.Clear();
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UIStatisticsWindow), "ComputeFirstHalfDetail", new Type[]
{
typeof(int),
typeof(int),
typeof(int),
typeof(int[]),
typeof(long[])
})]
private static bool ComputeFirstHalfDetail(int lastCursor, int lvlen, int cur, int[] detail, long[] targetDetail)
{
if (ratio == 1f)
{
return true;
}
dict.TryGetValue(targetDetail, out var value);
int num = (int)((float)lvlen * (1f - ratio) + 0.5f);
int num2 = cur + num - 1;
for (int i = 0; i < lvlen - num; i++)
{
if (++num2 > lastCursor)
{
num2 -= lvlen;
}
long num3 = detail[num2];
value.production += num3;
int num4 = (int)((float)(i + 1) / ratio);
for (int j = (int)((float)i / ratio); j < num4; j++)
{
targetDetail[j] += num3;
}
}
dict[targetDetail] = value;
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UIStatisticsWindow), "ComputeFirstHalfDetail", new Type[]
{
typeof(int),
typeof(int),
typeof(int),
typeof(long[]),
typeof(long[])
})]
private static bool ComputeFirstHalfDetail(int lastCursor, int lvlen, int cur, long[] detail, long[] targetDetail)
{
if (ratio == 1f)
{
return true;
}
dict.TryGetValue(targetDetail, out var value);
int num = (int)((float)lvlen * (1f - ratio) + 0.5f);
int num2 = cur + num - 1;
for (int i = 0; i < lvlen - num; i++)
{
if (++num2 > lastCursor)
{
num2 -= lvlen;
}
long num3 = detail[num2];
value.production += num3;
int num4 = (int)((float)(i + 1) / ratio);
for (int j = (int)((float)i / ratio); j < num4; j++)
{
targetDetail[j] += num3;
}
}
dict[targetDetail] = value;
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UIStatisticsWindow), "ComputeSecondHalfDetail", new Type[]
{
typeof(int),
typeof(int),
typeof(int),
typeof(int[]),
typeof(long[])
})]
private static bool ComputeSecondHalfDetail(int lastCursor, int lvlen, int cur, int[] detail, long[] targetDetail)
{
if (ratio == 1f)
{
return true;
}
dict.TryGetValue(targetDetail, out var value);
int num = (int)((float)lvlen * (1f - ratio) + 0.5f);
int num2 = cur + num - 1;
for (int i = 0; i < lvlen - num; i++)
{
if (++num2 > lastCursor)
{
num2 -= lvlen;
}
long num3 = detail[num2];
value.consumption += num3;
int num4 = (int)((float)(i + 1) / ratio);
for (int j = (int)((float)i / ratio); j < num4; j++)
{
targetDetail[lvlen + j] += num3;
}
}
dict[targetDetail] = value;
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UIStatisticsWindow), "ComputeSecondHalfDetail", new Type[]
{
typeof(int),
typeof(int),
typeof(int),
typeof(long[]),
typeof(long[])
})]
private static bool ComputeSecondHalfDetail(int lastCursor, int lvlen, int cur, long[] detail, long[] targetDetail)
{
if (ratio == 1f)
{
return true;
}
dict.TryGetValue(targetDetail, out var value);
int num = (int)((float)lvlen * (1f - ratio) + 0.5f);
int num2 = cur + num - 1;
for (int i = 0; i < lvlen - num; i++)
{
if (++num2 > lastCursor)
{
num2 -= lvlen;
}
long num3 = detail[num2];
value.consumption += num3;
int num4 = (int)((float)(i + 1) / ratio);
for (int j = (int)((float)i / ratio); j < num4; j++)
{
targetDetail[lvlen + j] += num3;
}
}
dict[targetDetail] = value;
return false;
}
[HarmonyPostfix]
[HarmonyAfter(new string[] { "Bottleneck" })]
[HarmonyPriority(100)]
[HarmonyPatch(typeof(UIProductEntry), "_OnUpdate")]
private static void UIProductEntry_ShowInText(UIProductEntry __instance)
{
if (__instance.productionStatWindow.isPowerTab)
{
return;
}
int timeLevel = __instance.productionStatWindow.timeLevel;
if (ratio == 1f || !dict.TryGetValue(__instance.entryData.detail, out var value))
{
if (SignificantDigits > 0)
{
double num = __instance.entryData.production;
double num2 = __instance.entryData.consumption;
if (num < 0.0)
{
num = 0.0 - num;
}
if (num2 < 0.0)
{
num2 = 0.0 - num2;
}
if (timeLevel < 5)
{
num /= __instance.lvDivisors[timeLevel];
num2 /= __instance.lvDivisors[timeLevel];
}
if (Plugin.DisplayPerSecond != null && Plugin.DisplayPerSecond.Value)
{
num /= 60.0;
num2 /= 60.0;
}
__instance.productText.text = ToLevelString(num);
__instance.consumeText.text = ToLevelString(num2);
}
}
else
{
double num = value.production;
double num2 = value.consumption;
if (timeLevel != 5)
{
num /= __instance.lvDivisors[timeLevel] * (double)ratio;
num2 /= __instance.lvDivisors[timeLevel] * (double)ratio;
}
if (Plugin.DisplayPerSecond != null && Plugin.DisplayPerSecond.Value)
{
num /= 60.0;
num2 /= 60.0;
}
if (SignificantDigits <= 0)
{
__instance.productText.text = __instance.ToLevelString(num, timeLevel);
__instance.consumeText.text = __instance.ToLevelString(num2, timeLevel);
}
else
{
__instance.productText.text = ToLevelString(num);
__instance.consumeText.text = ToLevelString(num2);
}
}
}
private static string ToLevelString(double value)
{
if (value == 0.0)
{
return "0";
}
string text = "";
if (value >= 1000000.0)
{
value /= 1000000.0;
text = " M";
}
else if (value >= 10000.0)
{
value /= 1000.0;
text = " k";
}
int num = 0;
if (value >= 1000.0)
{
num = 3;
}
else if (value >= 100.0)
{
num = 2;
}
else if (value >= 10.0)
{
num = 1;
}
num = SignificantDigits - num - 1;
if (num < 0)
{
num = 0;
}
if (num >= formatF.Length)
{
num = formatF.Length - 1;
}
if (num > 0)
{
double num2 = 0.1;
for (int i = 0; i < num; i++)
{
num2 *= 0.1;
}
if (value - (double)(int)value < num2)
{
return value.ToString("F1") + text;
}
}
return value.ToString(formatF[num]) + text;
}
[HarmonyPostfix]
[HarmonyAfter(new string[] { "Bottleneck" })]
[HarmonyPriority(100)]
[HarmonyPatch(typeof(UIKillEntry), "_OnUpdate")]
private static void UIKillEntry_ShowInText(UIKillEntry __instance)
{
if (ratio != 1f && dict.TryGetValue(__instance.entryData.detail, out var value))
{
int timeLevel = __instance.productionStatWindow.timeLevel;
double num = value.production;
if (timeLevel != 5)
{
num /= __instance.lvDivisors[timeLevel] * (double)ratio;
}
if (Plugin.DisplayPerSecond != null && Plugin.DisplayPerSecond.Value)
{
num /= 60.0;
}
__instance.killText.text = __instance.ToLevelString(num, timeLevel);
}
}
}
public class UIControlPanelPatch
{
private static bool initialized;
[HarmonyPostfix]
[HarmonyPatch(typeof(UIControlPanelFilterPanel), "_OnOpen")]
public static void Init(UIControlPanelFilterPanel __instance)
{
if (!initialized)
{
initialized = true;
Utils.EnableRichText(__instance.astroFilterBox);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIControlPanelFilterPanel), "_OnUpdate")]
public static void OnUpdate(UIControlPanelFilterPanel __instance)
{
Utils.DetermineAstroBoxIndex(__instance.astroFilterBox);
}
[HarmonyPostfix]
[HarmonyPriority(200)]
[HarmonyPatch(typeof(UIControlPanelFilterPanel), "ReconstructAstroFilterBox")]
private static void FilterList(UIControlPanelFilterPanel __instance)
{
Utils.UpdateAstroBox(__instance.astroFilterBox, 2);
}
}
public static class Utils
{
public static bool OrderByName = true;
public static int DropDownCount = 15;
public static string PlanetPrefix = "ㅤ";
public static string PlanetPostfix = "";
public static string SystemPrefix = "<color=yellow>";
public static string SystemPostfix = "</color>";
public static KeyCode HotkeyListUp = (KeyCode)280;
public static KeyCode HotkeyListDown = (KeyCode)281;
private static readonly Dictionary<int, int> astroIndex = new Dictionary<int, int>();
private static readonly List<(string, int)> systemList = new List<(string, int)>();
private static readonly List<string> newItems = new List<string>();
private static readonly List<int> newItemData = new List<int>();
public static void DetermineAstroBoxIndex(UIComboBox astroBox)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
int num = astroBox.itemIndex;
if (Input.GetKeyDown(HotkeyListUp))
{
if (VFInput.control)
{
int num2;
do
{
num = ((num > 0) ? (num - 1) : (astroBox.ItemsData.Count - 1));
num2 = astroBox.ItemsData[num];
}
while ((num2 % 100 != 0 || num2 <= 0) && num2 != -1 && num != astroBox.itemIndex);
astroBox.itemIndex = num;
}
else
{
astroBox.itemIndex = ((num > 0) ? (num - 1) : (astroBox.ItemsData.Count - 1));
}
}
else
{
if (!Input.GetKeyDown(HotkeyListDown))
{
return;
}
if (VFInput.control)
{
int num3;
do
{
num = (num + 1) % astroBox.ItemsData.Count;
num3 = astroBox.ItemsData[num];
}
while ((num3 % 100 != 0 || num3 <= 0) && num3 != -1 && num != astroBox.itemIndex);
astroBox.itemIndex = num;
}
else
{
astroBox.itemIndex = (num + 1) % astroBox.ItemsData.Count;
}
}
}
public static void EnableRichText(UIComboBox uIComboBox)
{
uIComboBox.m_Text.supportRichText = true;
uIComboBox.m_EmptyItemRes.supportRichText = true;
((Component)uIComboBox.m_ListItemRes).GetComponentInChildren<Text>().supportRichText = true;
foreach (Button itemButton in uIComboBox.ItemButtons)
{
((Component)itemButton).GetComponentInChildren<Text>().supportRichText = true;
}
uIComboBox.DropDownCount = DropDownCount;
}
public static void UpdateAstroBox(UIComboBox astroBox, int startIndex, string searchStr = "")
{
if (astroBox.Items.Count <= startIndex)
{
return;
}
astroIndex.Clear();
systemList.Clear();
newItems.Clear();
newItemData.Clear();
for (int i = startIndex; i < astroBox.Items.Count; i++)
{
int num = astroBox.ItemsData[i];
if (num % 100 == 0)
{
if (astroIndex.ContainsKey(num))
{
Plugin.Log.LogDebug((object)$"[{num}] => {astroBox.Items[i]}");
systemList[astroIndex[num]] = (astroBox.Items[i], num);
}
else
{
astroIndex[num] = systemList.Count;
systemList.Add((astroBox.Items[i], astroBox.ItemsData[i]));
}
}
}
if (OrderByName)
{
systemList.Sort();
}
foreach (var system in systemList)
{
int num2 = system.Item2 / 100;
for (int j = startIndex; j < astroBox.Items.Count; j++)
{
int num3 = astroBox.ItemsData[j];
if (num3 / 100 != num2)
{
continue;
}
string text = astroBox.Items[j];
if (num3 % 100 != 0)
{
if (!text.StartsWith(PlanetPrefix) || !text.EndsWith(PlanetPostfix))
{
text = PlanetPrefix + text + PlanetPostfix;
}
}
else if (!text.StartsWith(SystemPrefix) || !text.EndsWith(SystemPostfix))
{
text = SystemPrefix + text + SystemPostfix;
}
newItems.Add(text);
newItemData.Add(astroBox.ItemsData[j]);
}
}
astroBox.Items.RemoveRange(startIndex, astroBox.Items.Count - startIndex);
astroBox.ItemsData.RemoveRange(startIndex, astroBox.ItemsData.Count - startIndex);
astroBox.Items.AddRange(newItems);
astroBox.ItemsData.AddRange(newItemData);
if (string.IsNullOrEmpty(searchStr))
{
return;
}
for (int num4 = astroBox.Items.Count - 1; num4 >= startIndex; num4--)
{
int startIndex2 = ((astroBox.ItemsData[num4] % 100 == 0) ? SystemPrefix.Length : PlanetPrefix.Length);
int num5 = astroBox.Items[num4].Length - ((astroBox.ItemsData[num4] % 100 == 0) ? SystemPostfix.Length : PlanetPostfix.Length);
int num6 = astroBox.Items[num4].IndexOf(searchStr, startIndex2, StringComparison.OrdinalIgnoreCase);
if (num6 == -1 || num6 + searchStr.Length > num5)
{
astroBox.Items.RemoveAt(num4);
astroBox.ItemsData.RemoveAt(num4);
}
}
}
}