using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterMarketPlus.Compatibility;
using BetterMarketPlus.Localization;
using HarmonyLib;
using Newtonsoft.Json;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BetterMarketPlus")]
[assembly: AssemblyDescription("BetterMarketPlus By Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("BetterMarketPlus")]
[assembly: AssemblyCopyright("Copyright © 2025 Ice Box Studio All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("EAAD3296-E8E3-4C52-BF86-6907CB4F80E6")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BetterMarketPlus
{
[BepInPlugin("BetterMarketPlus", "BetterMarketPlus", "1.0.0")]
[BepInIncompatibility("ViViKo.BetterMarket")]
public class BetterMarketPlus : BaseUnityPlugin
{
private readonly Harmony harmony = new Harmony("BetterMarketPlus");
public static BetterMarketPlus Instance;
private bool patchesApplied;
internal static ManualLogSource Logger { get; private set; }
private void Awake()
{
Instance = this;
Logger = ((BaseUnityPlugin)this).Logger;
try
{
_ = LocalizationManager.Instance;
Logger.LogInfo((object)"=============================================");
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.initializing"));
Logger.LogInfo((object)(LocalizationManager.Instance.GetLocalizedText("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.runtime", Environment.Version));
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.unity_version", Application.unityVersion));
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.harmony_version", HarmonyVersion()));
Logger.LogInfo((object)"=============================================");
ApplyPatches();
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.initialized"));
}
catch (Exception ex)
{
Logger.LogError((object)("BetterMarketPlus 初始化错误: " + ex.Message + "\n" + ex.StackTrace));
}
}
private string HarmonyVersion()
{
try
{
return typeof(Harmony).Assembly.GetName().Version.ToString();
}
catch
{
return LocalizationManager.Instance.GetLocalizedText("plugin.unknown");
}
}
private void ApplyPatches()
{
if (!patchesApplied)
{
try
{
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.applying_patches"));
harmony.PatchAll();
patchesApplied = true;
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.patches_applied"));
return;
}
catch (Exception ex)
{
Logger.LogError((object)("应用 BetterMarketPlus 时出错: " + ex.Message + "\n" + ex.StackTrace));
return;
}
}
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.patches_skipped"));
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "BetterMarketPlus";
public const string PLUGIN_NAME = "BetterMarketPlus";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace BetterMarketPlus.Patches
{
[HarmonyPatch(typeof(BlockAlcoholMachine))]
public class BlockAlcoholMachinePatch
{
private static readonly FieldInfo currentOutputField = AccessTools.Field(typeof(BlockAlcoholMachine), "currentOutput");
private static readonly FieldInfo remainingDaysField = AccessTools.Field(typeof(BlockAlcoholMachine), "remainingDays");
private static long GetCurrentOutput(BlockAlcoholMachine instance)
{
object value = currentOutputField.GetValue(instance);
return (long)value.GetType().GetProperty("Value").GetValue(value);
}
private static int GetRemainingDays(BlockAlcoholMachine instance)
{
object value = remainingDaysField.GetValue(instance);
return (int)value.GetType().GetProperty("Value").GetValue(value);
}
[HarmonyPatch("GetDescription")]
[HarmonyPostfix]
private static void Postfix(BlockAlcoholMachine __instance, ref string __result)
{
long currentOutput = GetCurrentOutput(__instance);
int remainingDays = GetRemainingDays(__instance);
if (currentOutput != -1)
{
ItemSO itemById = GameManager.Instance.GetItemById(currentOutput);
__result = itemById.GetLocalizedName();
if (remainingDays > 0)
{
string localizedDaysWithPrefix = LocalizationManager.Instance.GetLocalizedDaysWithPrefix("common.remaining_prefix", remainingDays);
__result = __result + " <i><color=yellow>[" + localizedDaysWithPrefix + "]</color></i>";
}
}
}
}
[HarmonyPatch(typeof(BlockAnimal))]
public class BlockAnimalPatch
{
private static readonly FieldInfo animalSOField = AccessTools.Field(typeof(BlockAnimal), "animalSO");
[HarmonyPatch("GetDescription")]
[HarmonyPostfix]
private static void Postfix(BlockAnimal __instance, ref string __result)
{
object? value = animalSOField.GetValue(__instance);
AnimalSO val = (AnimalSO)((value is AnimalSO) ? value : null);
if (__instance.dayCounter.Value < val.daysToHarvestAfterGrowth)
{
int days = val.daysToHarvestAfterGrowth - __instance.dayCounter.Value;
string localizedDaysWithPrefix = LocalizationManager.Instance.GetLocalizedDaysWithPrefix("common.remaining_prefix", days);
__result = __result + " <i><color=yellow>[" + localizedDaysWithPrefix + "]</color></i>";
}
}
}
[HarmonyPatch(typeof(BlockBeeHive))]
public class BlockBeeHivePatch
{
private static readonly FieldInfo dayCounterField = AccessTools.Field(typeof(BlockBeeHive), "dayCounter");
private static readonly FieldInfo hasBeeField = AccessTools.Field(typeof(BlockBeeHive), "hasBee");
private static readonly FieldInfo blockBlueprintField = AccessTools.Field(typeof(PlayerInventory), "blockBlueprint");
private static Dictionary<int, RadiusVisualizer> visualizers = new Dictionary<int, RadiusVisualizer>();
private static HashSet<int> targetedThisFrame = new HashSet<int>();
private static HashSet<int> targetedLastFrame = new HashSet<int>();
private static int lastUpdateFrame;
private static Dictionary<GameObject, RadiusVisualizer> ghostVisualizers = new Dictionary<GameObject, RadiusVisualizer>();
private static int GetDayCounter(BlockBeeHive instance)
{
object value = dayCounterField.GetValue(instance);
return (int)value.GetType().GetProperty("Value").GetValue(value);
}
private static bool GetHasBee(BlockBeeHive instance)
{
object value = hasBeeField.GetValue(instance);
return (bool)value.GetType().GetProperty("Value").GetValue(value);
}
private static GameObject GetBlockBlueprint(PlayerInventory instance)
{
object? value = blockBlueprintField.GetValue(instance);
return (GameObject)((value is GameObject) ? value : null);
}
private static int CountTreesAround(BlockBeeHive instance)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
int num = 0;
Collider[] array = Physics.OverlapSphere(((Component)instance).transform.position, (float)instance.treeDetectionRadius);
foreach (Collider val in array)
{
if (!val.isTrigger && (Object)(object)((Component)val).GetComponent<BlockTree>() != (Object)null)
{
num++;
}
}
return num;
}
private static int CalculateHoneyOutput(int treeCount)
{
if (treeCount < 3)
{
return 1;
}
if (treeCount < 6)
{
return 2;
}
return 3;
}
[HarmonyPatch("GetDescription")]
[HarmonyPostfix]
private static void GetDescriptionPatch(BlockBeeHive __instance, ref string __result)
{
int instanceID = ((Object)__instance).GetInstanceID();
targetedThisFrame.Add(instanceID);
if (visualizers.TryGetValue(instanceID, out var value))
{
value.SetTargeted(targeted: true);
}
int dayCounter = GetDayCounter(__instance);
if (GetHasBee(__instance) && dayCounter < __instance.requiredDays)
{
int days = __instance.requiredDays - dayCounter;
int num = CountTreesAround(__instance);
int num2 = CalculateHoneyOutput(num);
string localizedDaysWithPrefix = LocalizationManager.Instance.GetLocalizedDaysWithPrefix("common.remaining_prefix", days);
string localizedText = LocalizationManager.Instance.GetLocalizedText("beehive.trees", num);
string localizedText2 = LocalizationManager.Instance.GetLocalizedText("beehive.output", num2);
string text = localizedDaysWithPrefix + "," + localizedText + "," + localizedText2;
__result = ((ItemSO)((Block)__instance).blockSO).GetLocalizedName() + " <i><color=yellow>[" + text + "]</color></i>";
}
}
[HarmonyPatch("OnNetworkSpawn")]
[HarmonyPostfix]
private static void OnNetworkSpawnPatch(BlockBeeHive __instance)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: 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)
GameObject val = new GameObject($"BeeHiveRadius_{((Object)__instance).GetInstanceID()}");
val.transform.SetParent(((Component)__instance).transform);
val.transform.localPosition = Vector3.zero;
RadiusVisualizer radiusVisualizer = val.AddComponent<RadiusVisualizer>();
radiusVisualizer.Initialize(__instance.treeDetectionRadius);
visualizers[((Object)__instance).GetInstanceID()] = radiusVisualizer;
}
[HarmonyPatch("OnNetworkDespawn")]
[HarmonyPostfix]
private static void OnNetworkDespawnPatch(BlockBeeHive __instance)
{
int instanceID = ((Object)__instance).GetInstanceID();
visualizers.Remove(instanceID);
targetedThisFrame.Remove(instanceID);
targetedLastFrame.Remove(instanceID);
}
[HarmonyPatch(typeof(PlayerInventory), "Update")]
[HarmonyPostfix]
private static void PlayerInventoryUpdatePatch()
{
if (Time.frameCount == lastUpdateFrame)
{
return;
}
lastUpdateFrame = Time.frameCount;
foreach (int item in targetedLastFrame)
{
if (!targetedThisFrame.Contains(item) && visualizers.TryGetValue(item, out var value))
{
value.SetTargeted(targeted: false);
}
}
HashSet<int> hashSet = targetedLastFrame;
targetedLastFrame = targetedThisFrame;
targetedThisFrame = hashSet;
targetedThisFrame.Clear();
}
[HarmonyPatch(typeof(PlayerInventory), "HandleNewBlockPlacement")]
[HarmonyPostfix]
private static void HandleNewBlockPlacementPatch(PlayerInventory __instance)
{
//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_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: 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)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
GameObject blockBlueprint = GetBlockBlueprint(__instance);
if ((Object)(object)blockBlueprint == (Object)null)
{
return;
}
InventorySlot currentInventorySlot = __instance.GetCurrentInventorySlot();
if (currentInventorySlot.itemId == -1)
{
return;
}
ItemSO itemById = GameManager.Instance.GetItemById(currentInventorySlot.itemId);
if ((Object)(object)itemById == (Object)null)
{
return;
}
BlockSO val = (BlockSO)(object)((itemById is BlockSO) ? itemById : null);
if (!((Object)(object)val != (Object)null) || !((Object)(object)((ItemSO)val).prefab.GetComponent<BlockBeeHive>() != (Object)null) || ghostVisualizers.ContainsKey(blockBlueprint))
{
return;
}
int radius = 3;
BlockBeeHive component = blockBlueprint.GetComponent<BlockBeeHive>();
if ((Object)(object)component != (Object)null)
{
radius = component.treeDetectionRadius;
}
else if ((Object)(object)((ItemSO)val).prefab != (Object)null)
{
BlockBeeHive component2 = ((ItemSO)val).prefab.GetComponent<BlockBeeHive>();
if ((Object)(object)component2 != (Object)null)
{
radius = component2.treeDetectionRadius;
}
}
GameObject val2 = new GameObject($"GhostBeeHiveRadius_{((Object)blockBlueprint).GetInstanceID()}");
val2.transform.SetParent(blockBlueprint.transform);
val2.transform.localPosition = Vector3.zero;
RadiusVisualizer radiusVisualizer = val2.AddComponent<RadiusVisualizer>();
radiusVisualizer.Initialize(radius);
radiusVisualizer.SetTargeted(targeted: true);
ghostVisualizers[blockBlueprint] = radiusVisualizer;
}
[HarmonyPatch(typeof(PlayerInventory), "DestroyBlockBlueprint")]
[HarmonyPrefix]
private static void DestroyBlockBlueprintPatch(PlayerInventory __instance)
{
GameObject blockBlueprint = GetBlockBlueprint(__instance);
if ((Object)(object)blockBlueprint != (Object)null && ghostVisualizers.ContainsKey(blockBlueprint))
{
ghostVisualizers.Remove(blockBlueprint);
}
}
[HarmonyPatch(typeof(PlayerInventory), "OnCurrentSlotChanged")]
[HarmonyPrefix]
private static void OnCurrentSlotChangedPatch(PlayerInventory __instance)
{
GameObject blockBlueprint = GetBlockBlueprint(__instance);
if ((Object)(object)blockBlueprint != (Object)null && ghostVisualizers.ContainsKey(blockBlueprint))
{
ghostVisualizers.Remove(blockBlueprint);
}
}
}
public class RadiusVisualizer : MonoBehaviour
{
private int radius;
private float pulseSpeed = 0.5f;
private LineRenderer circleRenderer;
private Dictionary<int, LineRenderer> treeConnections = new Dictionary<int, LineRenderer>();
private bool isTargeted;
private bool isVisible;
private float fadeSpeed = 3f;
private float currentAlpha;
private float targetAlpha;
private float hideDelay = 1f;
private float hideDelayTimer;
public void Initialize(int radius)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
this.radius = radius;
circleRenderer = ((Component)this).gameObject.AddComponent<LineRenderer>();
((Renderer)circleRenderer).material = new Material(Shader.Find("Sprites/Default"));
circleRenderer.startColor = new Color(1f, 0.5f, 0f, 0f);
circleRenderer.endColor = new Color(1f, 0.5f, 0f, 0f);
circleRenderer.startWidth = 0.05f;
circleRenderer.endWidth = 0.05f;
circleRenderer.positionCount = 51;
circleRenderer.useWorldSpace = true;
DrawCircle();
}
private void DrawCircle()
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: 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_0055: Unknown result type (might be due to invalid IL or missing references)
float num = 0f;
float num2 = (float)Math.PI / 25f;
for (int i = 0; i <= 50; i++)
{
float num3 = Mathf.Sin(num) * (float)radius;
float num4 = Mathf.Cos(num) * (float)radius;
Vector3 val = ((Component)this).transform.position + new Vector3(num3, 0.1f, num4);
circleRenderer.SetPosition(i, val);
num += num2;
}
}
public void SetTargeted(bool targeted)
{
if (isTargeted != targeted)
{
isTargeted = targeted;
if (targeted)
{
targetAlpha = 1f;
hideDelayTimer = 0f;
}
else
{
hideDelayTimer = hideDelay;
}
}
}
private void Update()
{
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
if (!isTargeted && hideDelayTimer > 0f)
{
hideDelayTimer -= Time.deltaTime;
if (hideDelayTimer <= 0f)
{
targetAlpha = 0f;
}
}
if (Mathf.Abs(currentAlpha - targetAlpha) > 0.01f)
{
currentAlpha = Mathf.MoveTowards(currentAlpha, targetAlpha, fadeSpeed * Time.deltaTime);
UpdateVisibility();
}
if (currentAlpha <= 0.01f)
{
if (isVisible)
{
SetVisibility(visible: false);
}
return;
}
if (!isVisible)
{
SetVisibility(visible: true);
}
DrawCircle();
float num = 0.7f + Mathf.PingPong(Time.time * pulseSpeed, 0.3f);
float num2 = currentAlpha * num;
Color val = default(Color);
((Color)(ref val))..ctor(1f, 0.5f, 0f, num2 * 0.3f);
circleRenderer.startColor = val;
circleRenderer.endColor = val;
UpdateTreeConnections(num2);
}
private void UpdateTreeConnections(float alphaWithPulse)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, (float)radius);
HashSet<int> hashSet = new HashSet<int>();
Collider[] array2 = array;
Color val2 = default(Color);
foreach (Collider val in array2)
{
if (!val.isTrigger && (Object)(object)((Component)val).GetComponent<BlockTree>() != (Object)null)
{
int instanceID = ((Object)val).GetInstanceID();
hashSet.Add(instanceID);
if (!treeConnections.ContainsKey(instanceID))
{
CreateTreeConnection(instanceID, ((Component)val).transform);
}
else
{
UpdateTreeConnection(instanceID, ((Component)val).transform);
}
if (treeConnections.TryGetValue(instanceID, out var value))
{
((Color)(ref val2))..ctor(0f, 1f, 0f, alphaWithPulse * 0.8f);
value.startColor = val2;
value.endColor = val2;
}
}
}
List<int> list = new List<int>();
foreach (int key in treeConnections.Keys)
{
if (!hashSet.Contains(key))
{
list.Add(key);
}
}
foreach (int item in list)
{
if ((Object)(object)treeConnections[item] != (Object)null)
{
Object.Destroy((Object)(object)((Component)treeConnections[item]).gameObject);
}
treeConnections.Remove(item);
}
}
private void UpdateVisibility()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: 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_007e: 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)
Color startColor = circleRenderer.startColor;
startColor.a = currentAlpha * 0.3f;
circleRenderer.startColor = startColor;
circleRenderer.endColor = startColor;
Color val = default(Color);
((Color)(ref val))..ctor(0f, 1f, 0f, currentAlpha * 0.8f);
foreach (LineRenderer value in treeConnections.Values)
{
if ((Object)(object)value != (Object)null)
{
value.startColor = val;
value.endColor = val;
}
}
}
private void SetVisibility(bool visible)
{
isVisible = visible;
((Renderer)circleRenderer).enabled = visible;
foreach (LineRenderer value in treeConnections.Values)
{
if ((Object)(object)value != (Object)null)
{
((Renderer)value).enabled = visible;
}
}
}
private void CreateTreeConnection(int treeId, Transform treeTransform)
{
//IL_0010: 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_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: 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)
GameObject val = new GameObject($"TreeConnection_{treeId}");
val.transform.SetParent(((Component)this).transform);
LineRenderer val2 = val.AddComponent<LineRenderer>();
((Renderer)val2).material = new Material(Shader.Find("Sprites/Default"));
val2.startColor = new Color(0f, 1f, 0f, currentAlpha * 0.8f);
val2.endColor = new Color(0f, 1f, 0f, currentAlpha * 0.8f);
val2.startWidth = 0.04f;
val2.endWidth = 0.04f;
val2.positionCount = 2;
val2.useWorldSpace = true;
((Renderer)val2).enabled = isVisible;
val2.SetPosition(0, ((Component)this).transform.position + new Vector3(0f, 0.1f, 0f));
val2.SetPosition(1, treeTransform.position + new Vector3(0f, 0.1f, 0f));
treeConnections[treeId] = val2;
}
private void UpdateTreeConnection(int treeId, Transform treeTransform)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: 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_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: 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)
if (treeConnections.ContainsKey(treeId) && (Object)(object)treeConnections[treeId] != (Object)null)
{
LineRenderer obj = treeConnections[treeId];
obj.SetPosition(0, ((Component)this).transform.position + new Vector3(0f, 0.1f, 0f));
obj.SetPosition(1, treeTransform.position + new Vector3(0f, 0.1f, 0f));
}
}
private void OnDestroy()
{
foreach (LineRenderer value in treeConnections.Values)
{
if ((Object)(object)value != (Object)null)
{
Object.Destroy((Object)(object)((Component)value).gameObject);
}
}
treeConnections.Clear();
}
}
[HarmonyPatch(typeof(BlockCheeseMachine))]
public class BlockCheeseMachinePatch
{
private static readonly FieldInfo currentOutputField = AccessTools.Field(typeof(BlockCheeseMachine), "currentOutput");
private static readonly FieldInfo remainingDaysField = AccessTools.Field(typeof(BlockCheeseMachine), "remainingDays");
private static long GetCurrentOutput(BlockCheeseMachine instance)
{
object value = currentOutputField.GetValue(instance);
return (long)value.GetType().GetProperty("Value").GetValue(value);
}
private static int GetRemainingDays(BlockCheeseMachine instance)
{
object value = remainingDaysField.GetValue(instance);
return (int)value.GetType().GetProperty("Value").GetValue(value);
}
[HarmonyPatch("GetDescription")]
[HarmonyPostfix]
private static void GetDescriptionPatch(BlockCheeseMachine __instance, ref string __result)
{
long currentOutput = GetCurrentOutput(__instance);
int remainingDays = GetRemainingDays(__instance);
if (currentOutput == -1)
{
return;
}
ItemSO itemById = GameManager.Instance.GetItemById(currentOutput);
if ((Object)(object)itemById != (Object)null)
{
__result = itemById.GetLocalizedName();
if (remainingDays > 0)
{
string localizedDaysWithPrefix = LocalizationManager.Instance.GetLocalizedDaysWithPrefix("common.remaining_prefix", remainingDays);
__result = __result + " <i><color=yellow>[" + localizedDaysWithPrefix + "]</color></i>";
}
}
else
{
string localizedText = LocalizationManager.Instance.GetLocalizedText("common.unknown_item");
string localizedDaysWithPrefix2 = LocalizationManager.Instance.GetLocalizedDaysWithPrefix("common.remaining_prefix", remainingDays);
__result = localizedText + " <i><color=yellow>[" + localizedDaysWithPrefix2 + "]</color></i>";
}
}
}
[HarmonyPatch(typeof(BlockDirt))]
public class BlockDirtPatch
{
private static readonly FieldInfo currentSeedField = AccessTools.Field(typeof(BlockDirt), "currentSeed");
[HarmonyPatch("GetDescription")]
[HarmonyPostfix]
private static void Postfix(BlockDirt __instance, ref string __result)
{
object value = currentSeedField.GetValue(__instance);
long num = (long)value.GetType().GetProperty("Value").GetValue(value);
if (num != -1)
{
ItemSO itemById = GameManager.Instance.GetItemById(num);
SeedSO val = (SeedSO)(object)((itemById is SeedSO) ? itemById : null);
if (__instance.dayCounter.Value < val.daysToFullGrowth)
{
int days = val.daysToFullGrowth - __instance.dayCounter.Value;
string localizedDaysWithPrefix = LocalizationManager.Instance.GetLocalizedDaysWithPrefix("common.remaining_prefix", days);
__result = __result + " <i><color=yellow>[" + localizedDaysWithPrefix + "]</color></i>";
}
}
}
}
[HarmonyPatch(typeof(BlockSprinkler))]
public class BlockSprinklerPatch
{
private static readonly FieldInfo radiusField = AccessTools.Field(typeof(BlockSprinkler), "radius");
private static readonly FieldInfo blockBlueprintField = AccessTools.Field(typeof(PlayerInventory), "blockBlueprint");
private static Dictionary<int, SprinklerRadiusVisualizer> visualizers = new Dictionary<int, SprinklerRadiusVisualizer>();
private static HashSet<int> targetedThisFrame = new HashSet<int>();
private static HashSet<int> targetedLastFrame = new HashSet<int>();
private static int lastUpdateFrame;
private static Dictionary<GameObject, SprinklerRadiusVisualizer> ghostVisualizers = new Dictionary<GameObject, SprinklerRadiusVisualizer>();
private static GameObject GetBlockBlueprint(PlayerInventory instance)
{
object? value = blockBlueprintField.GetValue(instance);
return (GameObject)((value is GameObject) ? value : null);
}
private static float GetRadius(BlockSprinkler instance)
{
return (float)radiusField.GetValue(instance);
}
[HarmonyPatch("GetDescription")]
[HarmonyPostfix]
private static void GetDescriptionPatch(BlockSprinkler __instance, ref string __result)
{
int instanceID = ((Object)__instance).GetInstanceID();
targetedThisFrame.Add(instanceID);
if (visualizers.TryGetValue(instanceID, out var value))
{
value.SetTargeted(targeted: true);
}
}
[HarmonyPatch("OnNetworkSpawn")]
[HarmonyPostfix]
private static void OnNetworkSpawnPatch(BlockSprinkler __instance)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: 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)
GameObject val = new GameObject($"SprinklerRadius_{((Object)__instance).GetInstanceID()}");
val.transform.SetParent(((Component)__instance).transform);
val.transform.localPosition = Vector3.zero;
SprinklerRadiusVisualizer sprinklerRadiusVisualizer = val.AddComponent<SprinklerRadiusVisualizer>();
sprinklerRadiusVisualizer.Initialize(GetRadius(__instance));
visualizers[((Object)__instance).GetInstanceID()] = sprinklerRadiusVisualizer;
}
[HarmonyPatch("OnNetworkDespawn")]
[HarmonyPostfix]
private static void OnNetworkDespawnPatch(BlockSprinkler __instance)
{
int instanceID = ((Object)__instance).GetInstanceID();
visualizers.Remove(instanceID);
targetedThisFrame.Remove(instanceID);
targetedLastFrame.Remove(instanceID);
}
[HarmonyPatch(typeof(PlayerInventory), "Update")]
[HarmonyPostfix]
private static void PlayerInventoryUpdatePatch()
{
if (Time.frameCount == lastUpdateFrame)
{
return;
}
lastUpdateFrame = Time.frameCount;
foreach (int item in targetedLastFrame)
{
if (!targetedThisFrame.Contains(item) && visualizers.TryGetValue(item, out var value))
{
value.SetTargeted(targeted: false);
}
}
HashSet<int> hashSet = targetedLastFrame;
targetedLastFrame = targetedThisFrame;
targetedThisFrame = hashSet;
targetedThisFrame.Clear();
}
[HarmonyPatch(typeof(PlayerInventory), "HandleNewBlockPlacement")]
[HarmonyPostfix]
private static void HandleNewBlockPlacementPatch(PlayerInventory __instance)
{
//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_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
GameObject blockBlueprint = GetBlockBlueprint(__instance);
if ((Object)(object)blockBlueprint == (Object)null)
{
return;
}
InventorySlot currentInventorySlot = __instance.GetCurrentInventorySlot();
if (currentInventorySlot.itemId == -1)
{
return;
}
ItemSO itemById = GameManager.Instance.GetItemById(currentInventorySlot.itemId);
if ((Object)(object)itemById == (Object)null)
{
return;
}
BlockSO val = (BlockSO)(object)((itemById is BlockSO) ? itemById : null);
if (!((Object)(object)val != (Object)null) || !((Object)(object)((ItemSO)val).prefab.GetComponent<BlockSprinkler>() != (Object)null) || ghostVisualizers.ContainsKey(blockBlueprint))
{
return;
}
float radius = 2f;
BlockSprinkler component = blockBlueprint.GetComponent<BlockSprinkler>();
if ((Object)(object)component != (Object)null)
{
radius = GetRadius(component);
}
else if ((Object)(object)((ItemSO)val).prefab != (Object)null)
{
BlockSprinkler component2 = ((ItemSO)val).prefab.GetComponent<BlockSprinkler>();
if ((Object)(object)component2 != (Object)null)
{
radius = GetRadius(component2);
}
}
GameObject val2 = new GameObject($"GhostSprinklerRadius_{((Object)blockBlueprint).GetInstanceID()}");
val2.transform.SetParent(blockBlueprint.transform);
val2.transform.localPosition = Vector3.zero;
SprinklerRadiusVisualizer sprinklerRadiusVisualizer = val2.AddComponent<SprinklerRadiusVisualizer>();
sprinklerRadiusVisualizer.Initialize(radius);
sprinklerRadiusVisualizer.SetTargeted(targeted: true);
ghostVisualizers[blockBlueprint] = sprinklerRadiusVisualizer;
}
[HarmonyPatch(typeof(PlayerInventory), "DestroyBlockBlueprint")]
[HarmonyPrefix]
private static void DestroyBlockBlueprintPatch(PlayerInventory __instance)
{
GameObject blockBlueprint = GetBlockBlueprint(__instance);
if ((Object)(object)blockBlueprint != (Object)null && ghostVisualizers.ContainsKey(blockBlueprint))
{
ghostVisualizers.Remove(blockBlueprint);
}
}
[HarmonyPatch(typeof(PlayerInventory), "OnCurrentSlotChanged")]
[HarmonyPrefix]
private static void OnCurrentSlotChangedPatch(PlayerInventory __instance)
{
GameObject blockBlueprint = GetBlockBlueprint(__instance);
if ((Object)(object)blockBlueprint != (Object)null && ghostVisualizers.ContainsKey(blockBlueprint))
{
ghostVisualizers.Remove(blockBlueprint);
}
}
}
public class SprinklerRadiusVisualizer : MonoBehaviour
{
private float radius;
private float pulseSpeed = 0.5f;
private LineRenderer circleRenderer;
private bool isTargeted;
private bool isVisible;
private float fadeSpeed = 3f;
private float currentAlpha;
private float targetAlpha;
private float hideDelay = 1f;
private float hideDelayTimer;
public void Initialize(float radius)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
this.radius = radius;
circleRenderer = ((Component)this).gameObject.AddComponent<LineRenderer>();
((Renderer)circleRenderer).material = new Material(Shader.Find("Sprites/Default"));
circleRenderer.startColor = new Color(0f, 0.7f, 1f, 0f);
circleRenderer.endColor = new Color(0f, 0.7f, 1f, 0f);
circleRenderer.startWidth = 0.05f;
circleRenderer.endWidth = 0.05f;
circleRenderer.positionCount = 51;
circleRenderer.useWorldSpace = true;
DrawCircle();
}
private void DrawCircle()
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
float num = 0f;
float num2 = (float)Math.PI / 25f;
for (int i = 0; i <= 50; i++)
{
float num3 = Mathf.Sin(num) * radius;
float num4 = Mathf.Cos(num) * radius;
Vector3 val = ((Component)this).transform.position + new Vector3(num3, 0.1f, num4);
circleRenderer.SetPosition(i, val);
num += num2;
}
}
public void SetTargeted(bool targeted)
{
if (isTargeted != targeted)
{
isTargeted = targeted;
if (targeted)
{
targetAlpha = 1f;
hideDelayTimer = 0f;
}
else
{
hideDelayTimer = hideDelay;
}
}
}
private void Update()
{
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
if (!isTargeted && hideDelayTimer > 0f)
{
hideDelayTimer -= Time.deltaTime;
if (hideDelayTimer <= 0f)
{
targetAlpha = 0f;
}
}
if (Mathf.Abs(currentAlpha - targetAlpha) > 0.01f)
{
currentAlpha = Mathf.MoveTowards(currentAlpha, targetAlpha, fadeSpeed * Time.deltaTime);
UpdateVisibility();
}
if (currentAlpha <= 0.01f)
{
if (isVisible)
{
SetVisibility(visible: false);
}
return;
}
if (!isVisible)
{
SetVisibility(visible: true);
}
DrawCircle();
float num = 0.7f + Mathf.PingPong(Time.time * pulseSpeed, 0.3f);
float num2 = currentAlpha * num;
Color val = default(Color);
((Color)(ref val))..ctor(0f, 0.7f, 1f, num2 * 0.3f);
circleRenderer.startColor = val;
circleRenderer.endColor = val;
}
private void UpdateVisibility()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: 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)
Color startColor = circleRenderer.startColor;
startColor.a = currentAlpha * 0.3f;
circleRenderer.startColor = startColor;
circleRenderer.endColor = startColor;
}
private void SetVisibility(bool visible)
{
isVisible = visible;
((Renderer)circleRenderer).enabled = visible;
}
}
[HarmonyPatch(typeof(BlockTree))]
public class BlockTreePatch
{
private static readonly FieldInfo treeSOField = AccessTools.Field(typeof(BlockTree), "treeSO");
[HarmonyPatch("GetDescription")]
[HarmonyPostfix]
private static void Postfix(BlockTree __instance, ref string __result)
{
object? value = treeSOField.GetValue(__instance);
TreeSO val = (TreeSO)((value is TreeSO) ? value : null);
if (__instance.dayCounter.Value < val.daysToHarvestAfterGrowth)
{
int days = val.daysToHarvestAfterGrowth - __instance.dayCounter.Value;
string localizedDaysWithPrefix = LocalizationManager.Instance.GetLocalizedDaysWithPrefix("common.remaining_prefix", days);
__result = __result + " <i><color=yellow>[" + localizedDaysWithPrefix + "]</color></i>";
}
}
}
[HarmonyPatch(typeof(DockOrderTile))]
public class DockOrderTilePatch
{
[HarmonyPatch("SetData")]
[HarmonyPostfix]
private static void SetDataPatch(DockOrderTile __instance, ProductSO productSO)
{
if (BetterDockOrderCompatibility.ShouldShowInventoryHint())
{
int productAmount = GetProductAmount(productSO);
TextMeshProUGUI textTitle = __instance.textTitle;
string localizedText = LocalizationManager.Instance.GetLocalizedText("order.inventory", productAmount);
((TMP_Text)textTitle).text = ((TMP_Text)textTitle).text + $" <color=yellow>[{localizedText}]</color>";
}
}
public static int GetProductAmount(ProductSO product)
{
return (from x in Object.FindObjectsOfType<Item>()
where x.itemSO is ProductSO && x.itemSO.itemName == ((ItemSO)product).itemName
select x).Sum((Item item) => item.amount.Value);
}
}
[HarmonyPatch(typeof(PlayerInventory))]
public class PlayerInventoryPatch
{
private static readonly HashSet<string> AllowPlacementAnywhere = new HashSet<string>
{
"floor_sign", "wall_sign", "big_fence", "chandelier", "lantern", "small_fence", "wall_candle", "paper_lantern_1", "paper_lantern_2", "paper_lantern_3",
"paper_lantern_4", "golden_candle"
};
private static readonly FieldRef<PlayerInventory, GameObject> blockBlueprint = AccessTools.FieldRefAccess<PlayerInventory, GameObject>("blockBlueprint");
private static readonly FieldRef<PlayerInventory, GameObject> itemBlueprint = AccessTools.FieldRefAccess<PlayerInventory, GameObject>("itemBlueprint");
private static readonly FieldRef<PlayerInventory, int> activeSlots = AccessTools.FieldRefAccess<PlayerInventory, int>("activeSlots");
[HarmonyPatch(typeof(PlayerInventory), "HandleItemPlacement")]
[HarmonyPrefix]
public static bool PatchItemRotation(PlayerInventory __instance)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: 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)
GameObject val = itemBlueprint.Invoke(__instance);
if ((Object)(object)val == (Object)null)
{
return true;
}
PlayerActions player = InputManager.Instance.inputMaster.Player;
if (((PlayerActions)(ref player)).Rotate.WasPerformedThisFrame())
{
LeanTweenExt.LeanRotateAroundLocal(val, Vector3.up, 45f, 0.1f);
return false;
}
return true;
}
[HarmonyPatch("HandleNewBlockPlacement")]
[HarmonyPrefix]
public static bool HandleNewBlockPlacementPatch(PlayerInventory __instance)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: 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_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_037f: Unknown result type (might be due to invalid IL or missing references)
//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
//IL_03b4: Expected O, but got Unknown
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_047b: Unknown result type (might be due to invalid IL or missing references)
//IL_0480: Unknown result type (might be due to invalid IL or missing references)
//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0243: Unknown result type (might be due to invalid IL or missing references)
//IL_0248: Unknown result type (might be due to invalid IL or missing references)
//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
//IL_04d3: Expected O, but got Unknown
//IL_046a: Unknown result type (might be due to invalid IL or missing references)
//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0200: Unknown result type (might be due to invalid IL or missing references)
//IL_0212: Unknown result type (might be due to invalid IL or missing references)
//IL_021c: Unknown result type (might be due to invalid IL or missing references)
//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0506: Unknown result type (might be due to invalid IL or missing references)
//IL_050b: Unknown result type (might be due to invalid IL or missing references)
//IL_050f: Unknown result type (might be due to invalid IL or missing references)
//IL_0514: Unknown result type (might be due to invalid IL or missing references)
//IL_0518: Unknown result type (might be due to invalid IL or missing references)
//IL_051d: Unknown result type (might be due to invalid IL or missing references)
//IL_0526: Unknown result type (might be due to invalid IL or missing references)
//IL_052b: Unknown result type (might be due to invalid IL or missing references)
//IL_049a: Unknown result type (might be due to invalid IL or missing references)
//IL_0431: Unknown result type (might be due to invalid IL or missing references)
//IL_043d: Unknown result type (might be due to invalid IL or missing references)
//IL_044f: Unknown result type (might be due to invalid IL or missing references)
//IL_0459: Unknown result type (might be due to invalid IL or missing references)
//IL_05e2: Unknown result type (might be due to invalid IL or missing references)
//IL_05e7: Unknown result type (might be due to invalid IL or missing references)
//IL_061e: Unknown result type (might be due to invalid IL or missing references)
//IL_062a: Unknown result type (might be due to invalid IL or missing references)
//IL_062f: Unknown result type (might be due to invalid IL or missing references)
try
{
PlayerActions player = InputManager.Instance.inputMaster.Player;
if (((PlayerActions)(ref player)).Place.IsPressed() || (Object)(object)itemBlueprint.Invoke(__instance) != (Object)null)
{
return true;
}
InventorySlot currentInventorySlot = __instance.GetCurrentInventorySlot();
if (currentInventorySlot.itemId == -1)
{
return true;
}
ItemSO itemById = GameManager.Instance.GetItemById(currentInventorySlot.itemId);
BlockSO val = (BlockSO)(object)((itemById is BlockSO) ? itemById : null);
if ((Object)(object)val == (Object)null)
{
return true;
}
bool flag = AllowPlacementAnywhere.Contains(((ItemSO)val).itemName);
Ray val2 = ((Camera)AccessTools.Field(typeof(PlayerInventory), "playerCamera").GetValue(__instance)).ViewportPointToRay(Vector3.one / 2f);
LayerMask val3 = LayerMask.op_Implicit(~LayerMask.op_Implicit(__instance.blockIgnoredLayerMask));
LayerMask.op_Implicit(flag ? (-1) : (-1 & LayerMask.op_Implicit(val3)));
QueryTriggerInteraction val4 = (QueryTriggerInteraction)1;
int num = 1;
if (((ItemSO)val).prefab.CompareTag("Boat") || ((ItemSO)val).prefab.CompareTag("Floatable"))
{
val4 = (QueryTriggerInteraction)2;
num = 2;
}
RaycastHit val5 = default(RaycastHit);
if (Physics.Raycast(val2, ref val5, __instance.buildDistance * (float)num, flag ? (-1) : (-1 & LayerMask.op_Implicit(val3)), val4))
{
if (!flag && !LayerMaskExtensions.Includes(val.placementLayerMask, ((Component)((RaycastHit)(ref val5)).collider).gameObject.layer))
{
AccessTools.Method(typeof(PlayerInventory), "DestroyBlockBlueprint", (Type[])null, (Type[])null).Invoke(__instance, null);
return false;
}
GameObject val6 = blockBlueprint.Invoke(__instance);
if ((Object)(object)val6 == (Object)null)
{
Quaternion rotation = ((RaycastHit)(ref val5)).transform.rotation;
string text = LayerMask.LayerToName(((Component)((RaycastHit)(ref val5)).collider).gameObject.layer);
if (GameManager.Instance.mapSO.id == 0 && (text == "Water" || text == "Terrain"))
{
((Quaternion)(ref rotation)).eulerAngles = new Vector3(((Quaternion)(ref rotation)).eulerAngles.x, ((Quaternion)(ref rotation)).eulerAngles.y - 28.85f, ((Quaternion)(ref rotation)).eulerAngles.z);
}
AccessTools.Field(typeof(PlayerInventory), "blockBlueprint").SetValue(__instance, Object.Instantiate<GameObject>(((ItemSO)val).prefab, ((RaycastHit)(ref val5)).point, rotation));
AccessTools.Field(typeof(PlayerInventory), "blockBlueprintHit").SetValue(__instance, ((RaycastHit)(ref val5)).transform);
GameObject val7 = blockBlueprint.Invoke(__instance);
Collider[] componentsInChildren = val7.GetComponentsInChildren<Collider>();
for (int i = 0; i < componentsInChildren.Length; i++)
{
componentsInChildren[i].enabled = false;
}
val7.GetComponent<NetworkObject>().AutoObjectParentSync = false;
BoxCollider blueprintTrigger = val7.GetComponent<Block>().blueprintTrigger;
AccessTools.Field(typeof(PlayerInventory), "blueprintTrigger").SetValue(__instance, blueprintTrigger);
((Component)blueprintTrigger).gameObject.layer = LayerMask.NameToLayer("IgnoreBlockCollision");
ObstacleColliderVisualizer val8 = default(ObstacleColliderVisualizer);
if (((Component)blueprintTrigger).TryGetComponent<ObstacleColliderVisualizer>(ref val8))
{
((Behaviour)val8).enabled = true;
}
if ((Object)(object)blueprintTrigger != (Object)null)
{
((Collider)blueprintTrigger).enabled = true;
}
AccessTools.Field(typeof(PlayerInventory), "meshRenderersBlockBlueprint").SetValue(__instance, val7.GetComponentsInChildren<MeshRenderer>().ToList());
AccessTools.Method(typeof(PlayerInventory), "ShowObstacleVisualizers", (Type[])null, (Type[])null).Invoke(__instance, new object[1] { true });
return false;
}
val6.transform.position = ((RaycastHit)(ref val5)).point;
if ((Object)(Transform)AccessTools.Field(typeof(PlayerInventory), "blockBlueprintHit").GetValue(__instance) != (Object)(object)((RaycastHit)(ref val5)).transform)
{
AccessTools.Field(typeof(PlayerInventory), "blockBlueprintHit").SetValue(__instance, ((RaycastHit)(ref val5)).transform);
string text2 = LayerMask.LayerToName(((Component)((RaycastHit)(ref val5)).collider).gameObject.layer);
Quaternion rotation2 = ((RaycastHit)(ref val5)).transform.rotation;
if (GameManager.Instance.mapSO.id == 0 && (text2 == "Water" || text2 == "Terrain"))
{
((Quaternion)(ref rotation2)).eulerAngles = new Vector3(((Quaternion)(ref rotation2)).eulerAngles.x, ((Quaternion)(ref rotation2)).eulerAngles.y - 28.85f, ((Quaternion)(ref rotation2)).eulerAngles.z);
}
val6.transform.rotation = rotation2;
}
player = InputManager.Instance.inputMaster.Player;
if (((PlayerActions)(ref player)).Rotate.WasPerformedThisFrame() && !val.disableRotation)
{
LeanTweenExt.LeanRotateAroundLocal(val6, Vector3.up, 45f, 0.1f);
}
bool flag2 = true;
BoxCollider val9 = (BoxCollider)AccessTools.Field(typeof(PlayerInventory), "blueprintTrigger").GetValue(__instance);
if ((Object)(object)val9 == (Object)null)
{
Debug.LogError((object)"Block needs a blueprint collider!");
}
else
{
Vector3 val10 = Vector3.Scale(val9.size, ((Component)val9).transform.lossyScale) / 2f;
Bounds bounds = ((Collider)val9).bounds;
flag2 = Physics.CheckBox(((Bounds)(ref bounds)).center, val10, ((Component)val9).transform.rotation, LayerMask.op_Implicit(val3), (QueryTriggerInteraction)2);
}
List<MeshRenderer> obj = (List<MeshRenderer>)AccessTools.Field(typeof(PlayerInventory), "meshRenderersBlockBlueprint").GetValue(__instance);
Material val11 = (flag2 ? __instance.materialBlueprintInvalid : __instance.materialBlueprintValid);
foreach (MeshRenderer item in obj)
{
int num2 = ((Renderer)item).sharedMaterials.Length;
Material[] array = (Material[])(object)new Material[num2];
for (int j = 0; j < num2; j++)
{
array[j] = val11;
}
((Renderer)item).materials = array;
}
if (flag2)
{
return false;
}
player = InputManager.Instance.inputMaster.Player;
if (((PlayerActions)(ref player)).Put.WasPerformedThisFrame())
{
__instance.audioSource.PlayOneShot(__instance.placementSound, 0.2f);
__instance.PlaceBlockServerRpc(((ItemSO)val).id, val6.transform.position, val6.transform.rotation, currentInventorySlot.dayCounter);
__instance.UseItem();
AccessTools.Method(typeof(PlayerInventory), "DestroyBlockBlueprint", (Type[])null, (Type[])null).Invoke(__instance, null);
return false;
}
}
else
{
AccessTools.Method(typeof(PlayerInventory), "DestroyBlockBlueprint", (Type[])null, (Type[])null).Invoke(__instance, null);
}
return false;
}
catch (Exception ex)
{
BetterMarketPlus.Logger.LogError((object)("方块放置错误: " + ex.Message + "\n" + ex.StackTrace));
return true;
}
}
}
[HarmonyPatch(typeof(UIManager))]
public class UIManagerCoinTooltipPatch
{
private static readonly FieldInfo dailyTransactionsField;
static UIManagerCoinTooltipPatch()
{
dailyTransactionsField = AccessTools.Field(typeof(GameManager), "dailyTransactions");
BetterMarketEvents.OnTransactionAdded += RefreshCoinTooltip;
}
private static void RefreshCoinTooltip()
{
if ((Object)(object)UIManager.Instance != (Object)null && (Object)(object)GameManager.Instance != (Object)null)
{
UIManager.Instance.SetCoinTooltip(GameManager.Instance.GetBankruptcyDayCounterValue(), GameManager.Instance.maxDaysForBankruptcy);
}
}
[HarmonyPatch("SetCoinTooltip")]
[HarmonyPostfix]
private static void SetCoinTooltipPatch(UIManager __instance)
{
//IL_0042: 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_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: 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_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected I4, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
string text = "";
int num = 0;
int num2 = 0;
int num3 = 0;
int num4 = 0;
int num5 = 0;
int num6 = 0;
if (dailyTransactionsField.GetValue(GameManager.Instance) is List<Transaction> list)
{
foreach (Transaction item in list)
{
TransactionType transactionType = item.TransactionType;
switch ((int)transactionType)
{
case 0:
num += item.Amount;
break;
case 5:
num4 += item.Amount;
break;
case 4:
num2 += item.Amount;
break;
case 3:
num3 += item.Amount;
break;
case 1:
num5 += item.Amount;
break;
case 6:
num6 += item.Amount;
break;
}
}
}
int rent = GameManager.Instance.GetRent();
int maintenanceValue = GameManager.Instance.GetMaintenanceValue();
if (num2 == 0)
{
num2 = -rent;
}
if (num3 == 0)
{
num3 = -maintenanceValue;
}
int num7 = Math.Abs(num2) + Math.Abs(num3);
if (num4 < 0)
{
num7 += Math.Abs(num4);
}
int num8 = num7;
if (num5 < 0)
{
num8 += Math.Abs(num5);
}
if (num6 < 0)
{
num8 += Math.Abs(num6);
}
int num9 = num - num8;
int num10 = GameManager.Instance.initialTaxPercentage;
EventSO currentEvent = GameManager.Instance.GetCurrentEvent();
if ((Object)(object)currentEvent != (Object)null)
{
num10 = Mathf.RoundToInt((float)num10 * currentEvent.taxMultiplier);
}
int num11 = Mathf.RoundToInt((float)Math.Max(0, num9) * ((float)num10 / 100f));
int num12 = num9 - num11;
int num13 = num8 + num11;
text += string.Format("\n<color=#8A5125>{0}</color>\n{1} C", LocalizationManager.Instance.GetLocalizedText("financial.sales"), num);
text += string.Format("\n<color=#8A5125>{0}</color>\n{1}%", LocalizationManager.Instance.GetLocalizedText("financial.current_tax_rate"), num10);
string arg = ((num11 > 0) ? "-" : "");
text += string.Format("\n<color=#8A5125>{0}</color>\n{1}{2} C", LocalizationManager.Instance.GetLocalizedText("financial.tax"), arg, num11);
string arg2 = ((num12 >= 0) ? "+" : "");
text += string.Format("\n<color=#8A5125>{0}</color>\n{1}{2} C", LocalizationManager.Instance.GetLocalizedText("financial.net_profit"), arg2, num12);
string arg3 = ((num13 > 0) ? "-" : "");
text += string.Format("\n<color=#8A5125>{0}</color>\n{1}{2} C", LocalizationManager.Instance.GetLocalizedText("financial.total_expenses"), arg3, num13);
TooltipTrigger tooltipTriggerCoins = __instance.tooltipTriggerCoins;
tooltipTriggerCoins.content += text;
}
}
[HarmonyPatch(typeof(GameManager))]
[HarmonyPatch("IncrementCoinsServer")]
public class GameManagerTransactionPatch
{
[HarmonyPostfix]
private static void IncrementCoinsServerPatch(GameManager __instance, int value, TransactionType type, string desc)
{
BetterMarketEvents.TriggerTransactionAdded();
}
}
public static class BetterMarketEvents
{
public static event Action OnTransactionAdded;
public static void TriggerTransactionAdded()
{
BetterMarketEvents.OnTransactionAdded?.Invoke();
}
}
[HarmonyPatch(typeof(UIManager))]
public class UIManagerRecipePatch
{
[HarmonyPatch("OpenRecipesPanel")]
[HarmonyPrefix]
private static void OpenRecipesPanelPrefix(UIManager __instance)
{
Transform listRecipes = __instance.listRecipes;
if ((Object)(object)listRecipes != (Object)null && listRecipes.childCount > 0)
{
for (int num = listRecipes.childCount - 1; num >= 0; num--)
{
Object.DestroyImmediate((Object)(object)((Component)listRecipes.GetChild(num)).gameObject);
}
}
}
[HarmonyPatch("OpenRecipesPanel")]
[HarmonyPostfix]
private static void OpenRecipesPanelPatch(UIManager __instance, List<RecipeSO> recipes)
{
Transform listRecipes = __instance.listRecipes;
if ((Object)(object)listRecipes == (Object)null)
{
return;
}
for (int i = 0; i < listRecipes.childCount; i++)
{
if (i >= recipes.Count)
{
continue;
}
ListButton component = ((Component)listRecipes.GetChild(i)).gameObject.GetComponent<ListButton>();
if ((Object)(object)component == (Object)null)
{
continue;
}
TextMeshProUGUI textTitle = component.textTitle;
if ((Object)(object)textTitle == (Object)null)
{
continue;
}
RecipeSO val = recipes[i];
if (!((Object)(object)val == (Object)null) && val.requiredDays > 0)
{
string text = ((TMP_Text)textTitle).text;
int num = text.IndexOf("\n<color=yellow>");
if (num > 0)
{
text = text.Substring(0, num);
}
string localizedDaysWithPrefix = LocalizationManager.Instance.GetLocalizedDaysWithPrefix("recipe.required_prefix", val.requiredDays);
((TMP_Text)textTitle).text = text + "\n<color=yellow>" + localizedDaysWithPrefix + "</color>";
}
}
}
[HarmonyPatch("UpdateRecipeIngredients")]
[HarmonyPostfix]
private static void UpdateRecipeIngredientsPatch(UIManager __instance, RecipeSO recipeSO)
{
if ((Object)(object)recipeSO == (Object)null || recipeSO.requiredDays <= 0)
{
return;
}
TextMeshProUGUI textRecipeOutput = __instance.textRecipeOutput;
if (!((Object)(object)textRecipeOutput == (Object)null))
{
string text = ((TMP_Text)textRecipeOutput).text;
int num = text.IndexOf("\n<color=yellow>");
if (num > 0)
{
text = text.Substring(0, num);
}
string localizedDaysWithPrefix = LocalizationManager.Instance.GetLocalizedDaysWithPrefix("recipe.required_prefix", recipeSO.requiredDays);
((TMP_Text)textRecipeOutput).text = text + "\n<color=yellow>" + localizedDaysWithPrefix + "</color>";
}
}
}
[HarmonyPatch(typeof(UIManager))]
[HarmonyPatch("OpenJournal")]
public class UIManagerJournalPatch
{
private class FinancialData
{
public int salesIncome;
public int rentCost;
public int maintenanceCost;
public int employeeCost;
public int orderCost;
public int otherCost;
public int taxCost;
}
private static readonly FieldInfo dailyTransactionsField = AccessTools.Field(typeof(GameManager), "dailyTransactions");
[HarmonyPostfix]
private static void OpenJournalPatch(UIManager __instance)
{
try
{
GameObject panelJournal = __instance.panelJournal;
if ((Object)(object)panelJournal == (Object)null)
{
return;
}
Transform val = panelJournal.transform.Find("Content/Row/Content");
if ((Object)(object)val == (Object)null)
{
return;
}
Transform val2 = val.Find("Stats");
if ((Object)(object)val2 == (Object)null)
{
return;
}
Transform val3 = val2.Find("Column");
if ((Object)(object)val3 == (Object)null)
{
return;
}
FinancialData financialData = CalculateFinancialData();
for (int i = 0; i < val3.childCount; i++)
{
Transform child = val3.GetChild(i);
if (((Object)child).name.StartsWith("Financial_"))
{
Object.Destroy((Object)(object)((Component)child).gameObject);
}
}
int num = -1;
for (int j = 0; j < val3.childCount; j++)
{
if (((Object)val3.GetChild(j)).name == "Maintenance")
{
num = j;
break;
}
}
int salesIncome = financialData.salesIncome;
int rentCost = financialData.rentCost;
int maintenanceCost = financialData.maintenanceCost;
int employeeCost = financialData.employeeCost;
int orderCost = financialData.orderCost;
int otherCost = financialData.otherCost;
int num2 = Math.Abs(rentCost) + Math.Abs(maintenanceCost);
if (employeeCost < 0)
{
num2 += Math.Abs(employeeCost);
}
int num3 = num2;
if (orderCost < 0)
{
num3 += Math.Abs(orderCost);
}
if (otherCost < 0)
{
num3 += Math.Abs(otherCost);
}
int num4 = salesIncome - num3;
int num5 = Math.Max(0, num4);
int num6 = GameManager.Instance.initialTaxPercentage;
EventSO currentEvent = GameManager.Instance.GetCurrentEvent();
if ((Object)(object)currentEvent != (Object)null)
{
num6 = Mathf.RoundToInt((float)num6 * currentEvent.taxMultiplier);
}
int num7 = Mathf.RoundToInt((float)num5 * ((float)num6 / 100f));
int num8 = num4 - num7;
int num9 = num3 + num7;
int siblingIndex = num + 1;
CreateFinancialEntry(val3, siblingIndex++, "Financial_Sales", LocalizationManager.Instance.GetLocalizedText("financial.sales"), $"{salesIncome} C");
string arg = ((num7 > 0) ? "-" : "");
CreateFinancialEntry(val3, siblingIndex++, "Financial_Tax", LocalizationManager.Instance.GetLocalizedText("financial.tax"), $"{arg}{num7} C");
string arg2 = ((num8 >= 0) ? "+" : "");
CreateFinancialEntry(val3, siblingIndex++, "Financial_NetProfit", LocalizationManager.Instance.GetLocalizedText("financial.net_profit"), $"{arg2}{num8} C");
string arg3 = ((num9 > 0) ? "-" : "");
CreateFinancialEntry(val3, siblingIndex, "Financial_TotalExpenses", LocalizationManager.Instance.GetLocalizedText("financial.total_expenses"), $"{arg3}{num9} C");
}
catch (Exception arg4)
{
Debug.LogError((object)$"[BetterMarketPlus] Error in UIManagerJournalPatch: {arg4}");
}
}
private static void CreateFinancialEntry(Transform parent, int siblingIndex, string name, string leftText, string rightText)
{
Transform val = parent.Find("Capacity");
if ((Object)(object)val == (Object)null)
{
return;
}
GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
((Object)obj).name = name;
obj.transform.SetSiblingIndex(siblingIndex);
Transform val2 = obj.transform.Find("Left");
Transform val3 = obj.transform.Find("Right");
if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null)
{
TextMeshProUGUI componentInChildren = ((Component)val2).GetComponentInChildren<TextMeshProUGUI>();
if ((Object)(object)componentInChildren != (Object)null)
{
((TMP_Text)componentInChildren).text = leftText;
}
TextMeshProUGUI componentInChildren2 = ((Component)val3).GetComponentInChildren<TextMeshProUGUI>();
if ((Object)(object)componentInChildren2 != (Object)null)
{
((TMP_Text)componentInChildren2).text = rightText;
}
}
}
private static FinancialData CalculateFinancialData()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: 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_0039: 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_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected I4, but got Unknown
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: 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)
FinancialData financialData = new FinancialData();
if (dailyTransactionsField.GetValue(GameManager.Instance) is List<Transaction> list)
{
foreach (Transaction item in list)
{
TransactionType transactionType = item.TransactionType;
switch ((int)transactionType)
{
case 0:
financialData.salesIncome += item.Amount;
break;
case 5:
financialData.employeeCost += item.Amount;
break;
case 4:
financialData.rentCost += item.Amount;
break;
case 3:
financialData.maintenanceCost += item.Amount;
break;
case 1:
financialData.orderCost += item.Amount;
break;
case 2:
financialData.taxCost += item.Amount;
break;
case 6:
financialData.otherCost += item.Amount;
break;
}
}
}
int rent = GameManager.Instance.GetRent();
int maintenanceValue = GameManager.Instance.GetMaintenanceValue();
if (financialData.rentCost == 0)
{
financialData.rentCost = -rent;
}
if (financialData.maintenanceCost == 0)
{
financialData.maintenanceCost = -maintenanceValue;
}
return financialData;
}
}
}
namespace BetterMarketPlus.Localization
{
public static class LocalizationHelper
{
private static readonly string[] DefaultTranslationLanguages = new string[3] { "zh", "zh-Hant", "en" };
public static void InitializeLanguageFiles()
{
string text = Path.Combine(Paths.ConfigPath, "BetterMarketPlus", "Localization");
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
string[] defaultTranslationLanguages = DefaultTranslationLanguages;
foreach (string text2 in defaultTranslationLanguages)
{
string filePath = Path.Combine(text, text2 + ".json");
EnsureLanguageFile(text2, filePath);
}
}
private static void EnsureLanguageFile(string language, string filePath)
{
Dictionary<string, string> defaultTranslations = GetDefaultTranslations(language);
if (File.Exists(filePath))
{
string text = File.ReadAllText(filePath);
Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(text);
bool flag = false;
foreach (KeyValuePair<string, string> item in defaultTranslations)
{
if (!dictionary.ContainsKey(item.Key))
{
dictionary[item.Key] = item.Value;
flag = true;
}
}
if (flag)
{
text = JsonConvert.SerializeObject((object)dictionary, (Formatting)1);
File.WriteAllText(filePath, text);
}
}
else
{
string contents = JsonConvert.SerializeObject((object)defaultTranslations, (Formatting)1);
File.WriteAllText(filePath, contents);
}
}
public static Dictionary<string, string> GetDefaultTranslations(string language)
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
switch (language)
{
case "zh":
dictionary.Add("financial.sales", "销售总额");
dictionary.Add("financial.tax", "应缴税费");
dictionary.Add("financial.current_tax_rate", "当前税率");
dictionary.Add("financial.net_profit", "净利润");
dictionary.Add("financial.total_expenses", "总支出");
dictionary.Add("plugin.initialized", "BetterMarketPlus 初始化成功!");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initializing", "BetterMarketPlus 开始初始化...");
dictionary.Add("plugin.runtime", "当前运行时: {0}");
dictionary.Add("plugin.unity_version", "Unity 版本: {0}");
dictionary.Add("plugin.harmony_version", "Harmony 版本: {0}");
dictionary.Add("plugin.unknown", "未知");
dictionary.Add("plugin.applying_patches", "正在应用 BetterMarketPlus...");
dictionary.Add("plugin.patches_applied", "BetterMarketPlus 已成功应用!");
dictionary.Add("plugin.patches_skipped", "补丁已应用,跳过...");
dictionary.Add("plugin.language_fallback", "不支持的语言 {0},使用英语作为备用。");
dictionary.Add("common.remaining_prefix", "剩余:");
dictionary.Add("common.day_single", "{0} 天");
dictionary.Add("common.day_plural", "{0} 天");
dictionary.Add("recipe.required_prefix", "需要:");
dictionary.Add("order.inventory", "库存:{0}");
dictionary.Add("beehive.trees", "周围树木:{0} 颗");
dictionary.Add("beehive.output", "预计产出:{0} 箱");
dictionary.Add("common.unknown_item", "未知物品");
dictionary.Add("compatibility.betterorder_enabled", "检测到 BetterOrder 模组已启用库存提示,已禁用本模组的库存提示。");
break;
case "zh-Hant":
dictionary.Add("financial.sales", "銷售總額");
dictionary.Add("financial.tax", "應繳稅費");
dictionary.Add("financial.current_tax_rate", "當前稅率");
dictionary.Add("financial.net_profit", "淨利潤");
dictionary.Add("financial.total_expenses", "總支出");
dictionary.Add("plugin.initialized", "BetterMarketPlus 初始化成功!");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initializing", "BetterMarketPlus 開始初始化...");
dictionary.Add("plugin.runtime", "當前運行時: {0}");
dictionary.Add("plugin.unity_version", "Unity 版本: {0}");
dictionary.Add("plugin.harmony_version", "Harmony 版本: {0}");
dictionary.Add("plugin.unknown", "未知");
dictionary.Add("plugin.applying_patches", "正在應用 BetterMarketPlus...");
dictionary.Add("plugin.patches_applied", "BetterMarketPlus 已成功應用!");
dictionary.Add("plugin.patches_skipped", "補丁已應用,跳過...");
dictionary.Add("plugin.language_fallback", "不支持的語言 {0},使用英語作為備用。");
dictionary.Add("common.remaining_prefix", "剩餘:");
dictionary.Add("common.day_single", "{0} 天");
dictionary.Add("common.day_plural", "{0} 天");
dictionary.Add("recipe.required_prefix", "需要:");
dictionary.Add("order.inventory", "庫存:{0}");
dictionary.Add("beehive.trees", "周圍樹木:{0} 顆");
dictionary.Add("beehive.output", "預計產出:{0} 箱");
dictionary.Add("common.unknown_item", "未知物品");
dictionary.Add("compatibility.betterorder_enabled", "檢測到 BetterOrder 模組已啟用庫存提示,已禁用本模組的庫存提示。");
break;
default:
dictionary.Add("financial.sales", "Total Sales");
dictionary.Add("financial.tax", "Tax Payable");
dictionary.Add("financial.current_tax_rate", "Current Tax Rate");
dictionary.Add("financial.net_profit", "Net Profit");
dictionary.Add("financial.total_expenses", "Total Expenses");
dictionary.Add("plugin.initialized", "BetterMarketPlus initialized successfully!");
dictionary.Add("plugin.author_prefix", "Author: ");
dictionary.Add("plugin.initializing", "BetterMarketPlus initializing...");
dictionary.Add("plugin.runtime", "Current Runtime: {0}");
dictionary.Add("plugin.unity_version", "Unity Version: {0}");
dictionary.Add("plugin.harmony_version", "Harmony Version: {0}");
dictionary.Add("plugin.unknown", "Unknown");
dictionary.Add("plugin.applying_patches", "Applying BetterMarketPlus patches...");
dictionary.Add("plugin.patches_applied", "BetterMarketPlus patches applied successfully!");
dictionary.Add("plugin.patches_skipped", "Patches already applied, skipping...");
dictionary.Add("plugin.language_fallback", "Unsupported language {0}, using English as fallback.");
dictionary.Add("common.remaining_prefix", "Remaining: ");
dictionary.Add("common.day_single", "1 day");
dictionary.Add("common.day_plural", "{0} days");
dictionary.Add("recipe.required_prefix", "Required: ");
dictionary.Add("order.inventory", "Stock: {0}");
dictionary.Add("beehive.trees", "Trees: {0}");
dictionary.Add("beehive.output", "Est. Output: {0} boxes");
dictionary.Add("common.unknown_item", "Unknown Item");
dictionary.Add("compatibility.betterorder_enabled", "Detected that the BetterOrder mod has enabled inventory prompts, this mod's inventory prompts have been disabled.");
break;
}
return dictionary;
}
}
public class LocalizationManager
{
private static LocalizationManager _instance;
private Dictionary<string, Dictionary<string, string>> _localizations = new Dictionary<string, Dictionary<string, string>>();
private string _currentLocale = "zh";
public static readonly string[] SupportedLanguages = new string[12]
{
"zh", "zh-Hant", "en", "fr", "de", "ja", "ko", "pt", "ru", "es",
"tr", "uk"
};
private static readonly string[] DefaultTranslationLanguages = new string[3] { "zh", "zh-Hant", "en" };
public static LocalizationManager Instance => _instance ?? (_instance = new LocalizationManager());
private LocalizationManager()
{
Initialize();
}
public void Initialize()
{
//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)
if ((Object)(object)LocalizationSettings.SelectedLocale != (Object)null)
{
LocaleIdentifier identifier = LocalizationSettings.SelectedLocale.Identifier;
_currentLocale = ((LocaleIdentifier)(ref identifier)).Code;
}
LocalizationHelper.InitializeLanguageFiles();
string path = Path.Combine(Paths.ConfigPath, "BetterMarketPlus", "Localization");
string[] supportedLanguages = SupportedLanguages;
foreach (string text in supportedLanguages)
{
string filePath = Path.Combine(path, text + ".json");
LoadLanguageFile(text, filePath);
}
LocalizationSettings.SelectedLocaleChanged += OnGameLanguageChanged;
}
private void OnGameLanguageChanged(Locale locale)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)locale != (Object)null)
{
LocaleIdentifier identifier = locale.Identifier;
string code = ((LocaleIdentifier)(ref identifier)).Code;
if (_localizations.ContainsKey(code))
{
_currentLocale = code;
return;
}
_currentLocale = "en";
BetterMarketPlus.Logger.LogInfo((object)GetLocalizedText("plugin.language_fallback", code));
}
}
private void LoadLanguageFile(string language, string filePath)
{
if (File.Exists(filePath))
{
try
{
Dictionary<string, string> value = JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(filePath));
_localizations[language] = value;
return;
}
catch
{
if (Array.IndexOf(DefaultTranslationLanguages, language) >= 0)
{
_localizations[language] = GetDefaultTranslations(language);
}
return;
}
}
if (Array.IndexOf(DefaultTranslationLanguages, language) >= 0)
{
_localizations[language] = GetDefaultTranslations(language);
}
}
private Dictionary<string, string> GetDefaultTranslations(string language)
{
MethodInfo methodInfo = AccessTools.Method(typeof(LocalizationHelper), "GetDefaultTranslations", (Type[])null, (Type[])null);
if (methodInfo != null)
{
return methodInfo.Invoke(null, new object[1] { language }) as Dictionary<string, string>;
}
return new Dictionary<string, string>();
}
public string GetLocalizedText(string key, params object[] args)
{
if (string.IsNullOrEmpty(_currentLocale) || !_localizations.ContainsKey(_currentLocale))
{
_currentLocale = "en";
}
if (_localizations.ContainsKey(_currentLocale) && _localizations[_currentLocale].TryGetValue(key, out var value))
{
return string.Format(value, args);
}
if (_currentLocale != "en" && _localizations.ContainsKey("en") && _localizations["en"].TryGetValue(key, out var value2))
{
return string.Format(value2, args);
}
if (_localizations.ContainsKey("zh") && _localizations["zh"].TryGetValue(key, out var value3))
{
return string.Format(value3, args);
}
return string.Format(key, args);
}
public string GetLocalizedDays(int days)
{
string key = ((days == 1) ? "common.day_single" : "common.day_plural");
return GetLocalizedText(key, days);
}
public string GetLocalizedDaysWithPrefix(string prefixKey, int days)
{
string localizedText = GetLocalizedText(prefixKey);
string localizedDays = GetLocalizedDays(days);
return localizedText + localizedDays;
}
}
}
namespace BetterMarketPlus.Compatibility
{
public static class BetterDockOrderCompatibility
{
private const string BetterDockOrderGUID = "FateArth.BetterDockOrderPlugin";
private static bool? _cachedResult;
public static bool ShouldShowInventoryHint()
{
if (_cachedResult.HasValue)
{
return _cachedResult.Value;
}
if (!Chainloader.PluginInfos.TryGetValue("FateArth.BetterDockOrderPlugin", out var value))
{
_cachedResult = true;
return true;
}
try
{
BaseUnityPlugin instance = value.Instance;
if (instance != null)
{
BaseUnityPlugin val = instance;
bool value2 = val.Config.Bind<bool>("General", "ShowRepertory", true, (ConfigDescription)null).Value;
_cachedResult = !value2;
if (!_cachedResult.Value)
{
BetterMarketPlus.Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("compatibility.betterorder_enabled"));
}
return _cachedResult.Value;
}
}
catch
{
_cachedResult = false;
return false;
}
_cachedResult = false;
return false;
}
public static void ResetCache()
{
_cachedResult = null;
}
}
}