Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HiredHands v0.12.1
plugins/HiredHands.dll
Decompiled 11 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using VikingsForHire.Board; using VikingsForHire.Commands; using VikingsForHire.Compat; using VikingsForHire.Config; using VikingsForHire.Core; using VikingsForHire.Core.Chores; using VikingsForHire.Core.Data; using VikingsForHire.Core.Diagnostics; using VikingsForHire.Core.Enhancements; using VikingsForHire.Core.Nav; using VikingsForHire.Core.Orders; using VikingsForHire.Core.Testing; using VikingsForHire.Diagnostics; using VikingsForHire.Followers; using VikingsForHire.Hirelings; using VikingsForHire.Hirelings.Combat; using VikingsForHire.Hirelings.Gear; using VikingsForHire.Hirelings.Nav; using VikingsForHire.Hirelings.Work; using VikingsForHire.Hirelings.Work.Chores; using VikingsForHire.Hirelings.Work.Farm; using VikingsForHire.Hirelings.Work.Kitchen; using VikingsForHire.Hirelings.Work.Ranch; using VikingsForHire.Hirelings.Work.Steward; using VikingsForHire.Hirelings.Work.Trees; using VikingsForHire.L10n; using VikingsForHire.Net; using VikingsForHire.Telemetry; using VikingsForHire.Testing; using VikingsForHire.UI; using YamlDotNet.Core; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VikingsForHire { [BepInPlugin("Spronglehump.HiredHands", "HiredHands", "0.12.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Guid = "Spronglehump.HiredHands"; public const string Name = "HiredHands"; public const string Version = "0.12.1"; internal static ManualLogSource Log; internal static Harmony Harmony; internal static Plugin Instance; private void Awake() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; VfhLog.Init(((BaseUnityPlugin)this).Logger); VfhConfig.Bind(((BaseUnityPlugin)this).Config); DataStore.Init(); Strings.Register(); Harmony = new Harmony("Spronglehump.HiredHands"); Harmony.PatchAll(typeof(Plugin).Assembly); CompatPatcher.Apply(Harmony); BoardPiece.Register(); CommandStoneItem.Register(); HiringCharter.Register(); BroomItem.Register(); CultivatorItem.Register(); LadleItem.Register(); ChefHatItem.Register(); TreePatchPiece.Register(); CropCatalog.Register(); FarmState.FreeSpots = PlantChore.FreeSpots; KitchenCatalog.Register(); FollowerServer.Register(); BalanceLog.Register(); ClientLogRelay.Register(); LowFunds.Register(); HirelingMapPins.Register(); BoardRegistry.Register(); MutationService.Register(); BoardServer.Register(); CharterPacking.Register(); HirelingPrefab.Register(); DebugCommands.Register(); BoardCommands.Register(); HirelingCommands.Register(); NavCommands.Register(); RosterCommands.Register(); TestHarness.Register(); Fixtures.Register(); FixturesBoard.Register(); FixturesUpgrade.Register(); FixturesHireling.Register(); FixturesRoster.Register(); FixturesCombat.Register(); FixturesWork.Register(); FixturesMining.Register(); FixturesSmelter.Register(); FixturesFollow.Register(); FixturesTravel.Register(); FixturesNav.Register(); FixturesFarm.Register(); FixturesKitchen.Register(); SessionInfo.LogHeader("plugin load"); Log.LogInfo((object)"HiredHands 0.12.1 loaded"); } private void Update() { PerfCounters.FrameTick(); VfhLog.Guard(LogCat.Data, "data.tick_failed", DataStore.Tick); VfhLog.Guard(LogCat.Board, "upgrade.tick_failed", BoardUpgrade.Tick); VfhLog.Guard(LogCat.Roster, "server.tick_failed", BoardServer.Tick); VfhLog.Guard(LogCat.Follow, "follow.tick_failed", FollowerServer.Tick); VfhLog.Guard(LogCat.Follow, "orphan.tick_failed", OrphanMonitor.Tick); VfhLog.Guard(LogCat.Follow, "ghost.tick_failed", HirelingGhostGuard.Tick); VfhLog.Guard(LogCat.Roster, "reconcile.tick_failed", RosterReconciler.Tick); VfhLog.Guard(LogCat.Core, "balance.tick_failed", BalanceLog.Tick); VfhLog.Guard(LogCat.Core, "clientlog.tick_failed", ClientLogRelay.Tick); StoneInput.Tick(); VfhLog.Guard(LogCat.Follow, "travel.tick_failed", TeleportTravel.Tick); VfhLog.Guard(LogCat.Follow, "claim.tick_failed", TeleportTravel.ClaimFollowers); VfhLog.Guard(LogCat.Follow, "ship.tick_failed", ShipStowage.Tick); VfhLog.Guard(LogCat.UI, "hud.tick_failed", FollowerHud.Tick); VfhLog.Guard(LogCat.Board, "funds.tick_failed", LowFunds.Tick); VfhLog.Guard(LogCat.Follow, "pins.tick_failed", HirelingMapPins.Tick); VfhLog.Guard(LogCat.Hireling, "chatter.tick_failed", HirelingChatter.Tick); VfhLog.Guard(LogCat.Combat, "summons.tick_failed", SummonedAllies.Tick); VfhLog.Guard(LogCat.Smelter, "bonesetter.tick_failed", Bonesetter.Tick); VfhLog.Guard(LogCat.Work, "rancher.tick_failed", RancherTicker.Tick); VfhLog.Guard(LogCat.Hireling, "graves.tick_failed", Graves.Tick); VfhLog.Guard(LogCat.Nav, "navlinks.tick_failed", NavLinkRegistry.Tick); } private void OnDestroy() { ClientLogRelay.Shutdown(); VfhLog.Shutdown(); } } } namespace VikingsForHire.UI { internal sealed class AreaRing : MonoBehaviour { private const float HoldSeconds = 0.3f; private const int Points = 96; private LineRenderer? _line; private float _showUntil; private float _radius = -1f; private float _drawn = -1f; private Vector3 _drawnAt; private Color _color = new Color(0.4f, 1f, 0.4f, 0.8f); public static AreaRing On(Component owner, Color color) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) AreaRing areaRing = owner.GetComponent<AreaRing>(); if ((Object)(object)areaRing == (Object)null) { areaRing = owner.gameObject.AddComponent<AreaRing>(); } areaRing._color = color; return areaRing; } public void Show(float radius) { _radius = radius; _showUntil = Time.time + 0.3f; } private void Update() { //IL_00bb: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_004e: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) if (Time.time >= _showUntil) { if ((Object)(object)_line != (Object)null && ((Renderer)_line).enabled) { ((Renderer)_line).enabled = false; } return; } if ((Object)(object)_line == (Object)null) { GameObject val = new GameObject("VFH_AreaRing"); val.transform.SetParent(((Component)this).transform, false); _line = val.AddComponent<LineRenderer>(); _line.useWorldSpace = true; _line.loop = true; _line.widthMultiplier = 0.08f; ((Renderer)_line).material = new Material(Shader.Find("Sprites/Default")); } LineRenderer? line = _line; Color startColor = (_line.endColor = _color); line.startColor = startColor; ((Renderer)_line).enabled = true; if (Mathf.Abs(_drawn - _radius) <= 0.01f) { Vector3 val2 = ((Component)this).transform.position - _drawnAt; if (((Vector3)(ref val2)).sqrMagnitude < 0.0025f && _line.positionCount > 0 && Time.frameCount % 30 != 0) { return; } } _drawn = _radius; _drawnAt = ((Component)this).transform.position; _line.positionCount = 96; for (int i = 0; i < 96; i++) { float num = (float)i * (float)Math.PI * 2f / 96f; Vector3 val3 = ((Component)this).transform.position + new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * _radius; val3.y = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.GetGroundHeight(val3) : val3.y) + 0.15f; _line.SetPosition(i, val3); } } } internal sealed class BoardPanel : MonoBehaviour { [HarmonyPatch(typeof(Menu), "Update")] private static class MenuPatch { private static bool Prefix() { long timestamp = Stopwatch.GetTimestamp(); try { if (!IsOpen && !HirelingPanel.IsOpen) { return true; } if (ZInput.GetKeyDown((KeyCode)27, true) || ZInput.GetButtonDown("JoyButtonB")) { Close("escape"); return false; } return true; } catch (Exception ex) { VfhLog.PatchFailed("BoardPanel.MenuUpdate", ex); return true; } finally { PerfCounters.Patch("BoardPanel.MenuUpdate", timestamp); } } } private const float OpenRange = 5f; private const float PanelWidth = 1000f; private const float PanelHeight = 720f; private const float TabSpacing = 210f; private const float CloseRange = 6f; private const float RefreshSeconds = 0.5f; private static BoardPanel? _instance; private readonly List<IBoardTab> _tabs = new List<IBoardTab> { new ContractsTab(), new RosterTab(), new OrdersTab(), new UpgradeTab() }; private readonly List<Button> _tabButtons = new List<Button>(); private HiringBoard? _board; private RectTransform _content; private Text _title; private int _tab; private string _shown = ""; private float _nextRefresh; public static bool IsOpen { get { if ((Object)(object)_instance != (Object)null) { return ((Component)_instance).gameObject.activeSelf; } return false; } } public static void Open(HiringBoard board, int tab = 0) { //IL_001d: 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_0040: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !GUIManager.IsHeadless() && !(Vector3.Distance(((Component)localPlayer).transform.position, ((Component)board).transform.position) > 5f) && PrivateArea.CheckAccess(((Component)board).transform.position, 0f, true, false)) { if ((Object)(object)_instance == (Object)null) { _instance = Create(); } _instance._board = board; _instance._tab = tab; _instance._shown = ""; _instance._nextRefresh = 0f; ((Component)_instance).gameObject.SetActive(true); GUIManager.BlockInput(true); VfhLog.D(LogCat.UI, "panel.open", ("board", board.Id), ("tab", tab)); } } public static void Close(string reason) { if (IsOpen) { ((Component)_instance).gameObject.SetActive(false); GUIManager.BlockInput(false); VfhLog.D(LogCat.UI, "panel.close", ("board", ((Object)(object)_instance._board != (Object)null) ? _instance._board.Id : ""), ("reason", reason)); _instance._board = null; } } private static BoardPanel Create() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 1000f, 720f, false); ((Object)val).name = "VFH_BoardPanel"; BoardPanel panel = val.AddComponent<BoardPanel>(); panel._title = PanelUi.Text(val.transform, "$vfh_board", 0f, -40f, 640f, 28, (TextAnchor)4, null, bold: true); for (int i = 0; i < panel._tabs.Count; i++) { int index = i; panel._tabButtons.Add(PanelUi.Button(val.transform, panel._tabs[i].Title, ((float)i - (float)(panel._tabs.Count - 1) / 2f) * 210f, -95f, 190f, 40f, delegate { panel.SelectTab(index); })); } panel._content = PanelUi.Fill(val.transform, "content"); PanelUi.Button(val.transform, "$vfh_close", 410f, -35f, 90f, 36f, delegate { Close("button"); }); val.SetActive(false); PanelUi.Clicked += delegate { if ((Object)(object)_instance != (Object)null) { _instance._nextRefresh = 0f; } }; return panel; } private void SelectTab(int index) { _tab = index; _shown = ""; _nextRefresh = 0f; VfhLog.D(LogCat.UI, "panel.tab", ("tab", _tabs[index].Title)); } private void Update() { //IL_0043: 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) if ((Object)(object)_board == (Object)null || _board.Zdo == null) { Close("board gone"); return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)_board).transform.position) > 6f) { Close("walked away"); return; } _board.ShowArea(); if (Time.unscaledTime < _nextRefresh) { return; } _nextRefresh = Time.unscaledTime + 0.5f; VfhLog.Guard(LogCat.UI, "panel.refresh_failed", delegate { //IL_00ab: 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) IBoardTab boardTab = _tabs[_tab]; string text = _tab + "|" + boardTab.Signature(_board); if (!(text == _shown)) { _shown = text; _title.text = Localization.instance.Localize("$vfh_board — $vfh_level ") + _board.Level; for (int i = 0; i < _tabButtons.Count; i++) { ((Graphic)((Component)_tabButtons[i]).GetComponentInChildren<Text>()).color = ((i == _tab) ? GUIManager.Instance.ValheimOrange : GUIManager.Instance.ValheimBeige); } PanelUi.Clear((Transform)(object)_content); boardTab.Build(_content, _board); } }, ("board", _board.Id)); } private void OnDestroy() { if ((Object)(object)_instance == (Object)(object)this) { if (((Component)this).gameObject.activeSelf) { GUIManager.BlockInput(false); } _instance = null; } } } internal sealed class ContractsTab : IBoardTab { private static readonly JobType[] AllJobs = (JobType[])Enum.GetValues(typeof(JobType)); private static readonly JobType[] WorkerJobs = Array.FindAll(AllJobs, (JobType j) => !j.IsCombat()); private const float RadiusStep = 5f; private int _job; private int _level = 1; private float _radius = 20f; private string _radiusDefaultedFor = ""; private int _stance = -1; private static JobType[] Jobs { get { if (!VfhConfig.CombatHirelings.Value) { return WorkerJobs; } return AllJobs; } } public string Title => "$vfh_tab_contracts"; public string Signature(HiringBoard board) { Clamp(board); Cost cost = ((board.Inventory != null) ? BoardStorage.Totals(board.Inventory) : Cost.Zero); int num = ((board.Zdo != null) ? BoardRosterOps.Read(board.Zdo).Count : 0); return $"{_job}|{_level}|{_radius}|{_stance}|{board.Level}|{cost}|{num}|{DataStore.Hash}|{VfhConfig.CombatHirelings.Value}"; } public void Build(RectTransform root, HiringBoard board) { //IL_03d8: 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_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_0568: Unknown result type (might be due to invalid IL or missing references) //IL_05b1: Unknown result type (might be due to invalid IL or missing references) Clamp(board); JobType job = Jobs[_job]; IReadOnlyList<Stance> stances = StanceRules.Allowed(job); Stance stance = stances[_stance]; LevelRules levelRules = new LevelRules(DataStore.Current); CostCalculator costCalculator = new CostCalculator(DataStore.Current, VfhConfig.RespawnCostFraction.Value); Row(root, -150f, "$vfh_contract_job", "$vfh_job_" + job.ToString().ToLowerInvariant(), delegate { _job = (_job + Jobs.Length - 1) % Jobs.Length; }, delegate { _job = (_job + 1) % Jobs.Length; }); Row(root, -195f, "$vfh_contract_level", _level.ToString(), delegate { _level--; }, delegate { _level++; }); Row(root, -240f, "$vfh_contract_radius", $"{_radius:0} m", delegate { _radius -= 5f; }, delegate { _radius += 5f; }); Row(root, -285f, "$vfh_contract_stance", "$vfh_stance_" + stance.ToString().ToLowerInvariant(), delegate { _stance = (_stance + stances.Count - 1) % stances.Count; }, delegate { _stance = (_stance + 1) % stances.Count; }); Cost c = costCalculator.HireCost(job, _level); Cost c2 = costCalculator.DailyUpkeep(job, _level); Cost available = ((board.Inventory != null) ? BoardStorage.Totals(board.Inventory) : Cost.Zero); Roster roster = ((board.Zdo != null) ? BoardRosterOps.Read(board.Zdo) : new Roster()); OpOutcome opOutcome = roster.CanPost(job, levelRules, board.Level); bool flag = opOutcome == OpOutcome.Ok; int num = roster.KindCount(combat: true); int num2 = roster.KindCount(combat: false); int num3 = levelRules.CombatCap(board.Level); int num4 = levelRules.WorkerCap(board.Level); int num5 = roster.JobCount(job); int num6 = levelRules.MaxPerBoard(job); string text = (VfhConfig.CombatHirelings.Value ? Localization.instance.Localize("$vfh_contract_counts", new string[4] { num.ToString(), num3.ToString(), num2.ToString(), num4.ToString() }) : Localization.instance.Localize("$vfh_contract_counts_workers", new string[2] { num2.ToString(), num4.ToString() })); if (num6 > 0) { text += Localization.instance.Localize("$vfh_contract_job_count", new string[3] { Localization.instance.Localize("$vfh_job_" + job.ToString().ToLowerInvariant()), num5.ToString(), num6.ToString() }); } bool flag2 = (job.IsCombat() ? (num >= num3) : (num2 >= num4)) || (num6 > 0 && num5 >= num6); bool flag3 = c.CoveredBy(available); bool flag4 = levelRules.JobUnlocked(board.Level, job); PanelUi.Text((Transform)(object)root, Localization.instance.Localize("$vfh_contract_fee") + " " + Price(c), 0f, -335f, 600f, 18, (TextAnchor)4, flag3 ? PanelUi.Good : PanelUi.Bad); PanelUi.Text((Transform)(object)root, Localization.instance.Localize("$vfh_contract_upkeep") + " " + Price(c2), 0f, -365f, 600f, 18, (TextAnchor)4); PanelUi.Text((Transform)(object)root, Localization.instance.Localize("$vfh_contract_funds") + " " + string.Format("{0} {1} + {2} {3}", available.FoodPoints, Localization.instance.Localize("$vfh_food_points"), available.Coins, Localization.instance.Localize("$vfh_coins")), 0f, -395f, 600f, 18, (TextAnchor)4, PanelUi.Dim); PanelUi.Text((Transform)(object)root, text, 0f, -425f, 600f, 18, (TextAnchor)4, flag2 ? PanelUi.Bad : PanelUi.Dim); ((Selectable)PanelUi.Button((Transform)(object)root, "$vfh_contract_post", 0f, -475f, 240f, 44f, delegate { BoardContracts.Post(board, job, _level, _radius, stance); })).interactable = flag3 && flag && flag4; if (!flag4) { PanelUi.Text((Transform)(object)root, Localization.instance.Localize("$vfh_contract_job_locked", new string[1] { levelRules.MinBoardLevel(job).ToString() }), 0f, -515f, 600f, 18, (TextAnchor)4, PanelUi.Bad); } else if (!flag) { PanelUi.Text((Transform)(object)root, BoardContracts.Text(BoardRosterOps.RefusalMessage(opOutcome, job, roster, levelRules, board.Level)), 0f, -515f, 600f, 18, (TextAnchor)4, PanelUi.Bad); } } public static string Price(Cost c) { List<string> list = new List<string>(); if (c.FoodPoints > 0) { list.Add(string.Format("{0} {1}", c.FoodPoints, Localization.instance.Localize("$vfh_food_points"))); } if (c.Coins > 0) { list.Add(string.Format("{0} {1}", c.Coins, Localization.instance.Localize("$vfh_coins"))); } if (list.Count <= 0) { return Localization.instance.Localize("$vfh_free"); } return string.Join(" + ", list); } private void Clamp(HiringBoard board) { _job %= Jobs.Length; LevelRules levelRules = new LevelRules(DataStore.Current); _level = Mathf.Clamp(_level, 1, levelRules.MaxHirelingLevel(board.Level)); float num = levelRules.MaxWorkRadius(board.Level, Jobs[_job]); string text = $"{Jobs[_job]}|{board.Level}"; if (text != _radiusDefaultedFor) { _radiusDefaultedFor = text; _radius = num; } _radius = Mathf.Clamp(_radius, 10f, num); int count = StanceRules.Allowed(Jobs[_job]).Count; if (_stance < 0 || _stance >= count) { _stance = IndexOf(StanceRules.Allowed(Jobs[_job]), StanceRules.Default(Jobs[_job])); } } private static int IndexOf(IReadOnlyList<Stance> list, Stance s) { for (int i = 0; i < list.Count; i++) { if (list[i] == s) { return i; } } return 0; } private static void Row(RectTransform root, float y, string label, string value, Action prev, Action next) { PanelUi.Text((Transform)(object)root, label, -200f, y, 180f, 20, (TextAnchor)3); PanelUi.Button((Transform)(object)root, "<", -30f, y, 44f, 36f, prev); PanelUi.Text((Transform)(object)root, value, 90f, y, 180f, 20, (TextAnchor)4, null, bold: true); PanelUi.Button((Transform)(object)root, ">", 210f, y, 44f, 36f, next); } } internal sealed class HirelingPanel : MonoBehaviour { private sealed class RenameReceiver : TextReceiver { private readonly Hireling _h; private readonly string _hid; private readonly string _boardId; public RenameReceiver(Hireling h) { _h = h; _hid = h.Hid; _boardId = h.BoardId; } public string GetText() { if (!((Object)(object)_h != (Object)null)) { return ""; } return _h.DisplayName; } public void SetText(string text) { string text2 = HirelingNames.Clean(text); if (text2.Length != 0) { if (_boardId.Length > 0) { MutationService.SubmitBoard(_boardId, new RosterOp { Type = RosterOpType.Rename, Hid = _hid, Name = text2 }); } else { MutationService.SubmitHireling(_hid, new HirelingOp { Name = text2 }); } VfhLog.I(LogCat.UI, "hireling.rename", ("hid", _hid), ("name", text2)); } } } private const float OpenRange = 6f; private const float CloseRange = 8f; private const float GroupRange = 30f; private static HirelingPanel? _instance; private Hireling? _hireling; private float _nextHold; private RectTransform _content; private RectTransform? _close; private bool _all; private bool _orders; private bool _ordersPicking; private int _ordersPage; private InputField? _search; private string _ordersSearch = ""; private bool _why; private int _whyPage; private bool _enh; private int _pendingLevel; private char _pendingChoice; private string _shown = ""; private float _nextRefresh; private const float MinHeight = 420f; private const float EnhWidth = 760f; private const float EnhRowHeight = 74f; private const float Width = 520f; private const float LimitsWidth = 660f; private const int LimitPicksPerPage = 12; private const int OrderPicksPerPage = 14; private const int WhyRowsPerPage = 10; public static bool IsOpen { get { if ((Object)(object)_instance != (Object)null) { return ((Component)_instance).gameObject.activeSelf; } return false; } } public static void Open(Hireling h) { //IL_001c: 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_0072: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || GUIManager.IsHeadless() || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)h).transform.position) > 6f) { return; } bool flag = h.Mode == HirelingMode.Following; if (flag && h.OwnerId != localPlayer.GetPlayerID()) { ((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize("$vfh_not_your_follower"), 0, (Sprite)null, false); } else if (flag || PrivateArea.CheckAccess(h.Home, 0f, true, false)) { if ((Object)(object)_instance == (Object)null) { _instance = Create(); } _instance._hireling = h; _instance._shown = ""; _instance._orders = false; _instance._ordersPicking = false; _instance._ordersPage = 0; _instance.ClearSearch(); _instance._why = false; _instance._whyPage = 0; _instance._enh = false; _instance._pendingLevel = 0; _instance._nextRefresh = 0f; _instance._nextHold = 0f; ((Component)_instance).gameObject.SetActive(true); GUIManager.BlockInput(true); VfhLog.D(LogCat.UI, "orders.open", ("hid", h.Hid)); } } public static void ShowPage(string page) { if (!((Object)(object)_instance == (Object)null)) { HirelingPanel instance = _instance; bool orders = ((page == "orders" || page == "orders_add") ? true : false); instance._orders = orders; _instance._ordersPicking = page == "orders_add"; _instance._why = page == "why"; _instance._shown = ""; } } public static void Search(string text) { if ((Object)(object)_instance?._search != (Object)null) { _instance._search.text = text; } } private void ClearSearch() { _ordersSearch = ""; if ((Object)(object)_search != (Object)null && _search.text.Length > 0) { _search.text = ""; } } private bool Matches(OrderPicks.Pick p) { string text = _ordersSearch.Trim(); if (text.Length != 0 && OrderPicks.PickLabel(p).IndexOf(text, StringComparison.OrdinalIgnoreCase) < 0) { return p.Item.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0; } return true; } public static void ShowEnhancements() { if (!((Object)(object)_instance == (Object)null)) { _instance._enh = true; _instance._shown = ""; } } public static void Close(string reason) { if (IsOpen) { ((Component)_instance).gameObject.SetActive(false); GUIManager.BlockInput(false); VfhLog.D(LogCat.UI, "orders.close", ("reason", reason)); if ((Object)(object)_instance._hireling != (Object)null) { _instance._hireling.HoldForPanel(hold: false); } _instance._hireling = null; } } private static HirelingPanel Create() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 520f, 420f, false); ((Object)val).name = "VFH_HirelingPanel"; HirelingPanel panel = val.AddComponent<HirelingPanel>(); panel._content = PanelUi.Fill(val.transform, "content"); ref RectTransform? close = ref panel._close; Transform transform = ((Component)PanelUi.Button(val.transform, "$vfh_close", 200f, -30f, 80f, 34f, delegate { Close("button"); })).transform; close = (RectTransform?)(object)((transform is RectTransform) ? transform : null); GameObject val2 = GUIManager.Instance.CreateInputField(val.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -92f), (ContentType)0, Localization.instance.Localize("$vfh_orders_search"), 16, 360f, 32f); panel._search = val2.GetComponent<InputField>(); ((UnityEvent<string>)(object)panel._search.onValueChanged).AddListener((UnityAction<string>)delegate(string v) { panel._ordersSearch = v; panel._ordersPage = 0; panel._nextRefresh = 0f; }); val2.SetActive(false); val.SetActive(false); PanelUi.Clicked += delegate { if ((Object)(object)_instance != (Object)null) { _instance._nextRefresh = 0f; } }; return panel; } private void Update() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) Hireling hireling = _hireling; Player localPlayer = Player.m_localPlayer; if ((Object)(object)hireling == (Object)null || hireling.Zdo == null || (Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)hireling).transform.position) > 8f || ZInput.GetKeyDown((KeyCode)27, true)) { Close(((Object)(object)hireling == (Object)null) ? "gone" : "walked away"); return; } if (Time.unscaledTime >= _nextHold) { _nextHold = Time.unscaledTime + 1f; hireling.HoldForPanel(hold: true); } if (Time.unscaledTime < _nextRefresh) { return; } _nextRefresh = Time.unscaledTime + 0.3f; object obj = hireling.Mode; object obj2 = hireling.FollowMode; object obj3 = hireling.Stance; object obj4 = hireling.HasPost; object obj5 = _all; object displayName = hireling.DisplayName; object obj6 = hireling.Zdo.GetString("vfh_skip_items", ""); object obj7 = hireling.WorksAtHome; object obj8 = hireling.IsParked; object obj9 = hireling.Level; bool flag = ChoreRules.ChoresFor(hireling.Job).Count > 0; if (!flag) { JobType job = hireling.Job; bool flag2 = (uint)job <= 1u; flag = flag2; } string text = string.Format("{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}|{8}|{9}|{10}", obj, obj2, obj3, obj4, obj5, displayName, obj6, obj7, obj8, obj9, flag ? (hireling.Zdo.GetString("vfh_activity", "") + "|" + hireling.Zdo.GetString("vfh_why", "")) : ""); if (_orders) { HiringBoard ob = BoardOrders.BoardOf(hireling.BoardId); if (ob != null) { OrderList orderList = BoardOrders.For(ob); Stock os = BoardOrders.Stock(ob); text = text + $"|orders|{_ordersPicking}|{_ordersPage}|{_ordersSearch}|{orderList.Serialize()}|" + string.Join(",", from o in OrderPicks.For(orderList, hireling.Job) select OrderPicks.Have(ob, os, o)); } } if (_why) { text += string.Format("|why|{0}|{1}", _whyPage, hireling.Zdo.GetString("vfh_why", "")); HiringBoard hiringBoard = BoardOrders.BoardOf(hireling.BoardId); if (hiringBoard != null) { Stock ws = BoardOrders.Stock(hiringBoard); text = text + "|" + string.Join(",", from o in WhyOrders(hireling, hiringBoard) select $"{o.Item}:{o.Target}:{o.Paused}:{ws.Have(o.Item)}"); } } text = ((!_enh) ? (text + "|" + hireling.Zdo.GetString("vfh_enh", "")) : (text + string.Format("|enh|{0}|{1}{2}|{3}", hireling.Zdo.GetString("vfh_enh", ""), _pendingLevel, _pendingChoice, VfhConfig.Enhancements.Value))); if (!(text == _shown)) { _shown = text; Build(hireling); } } private void Build(Hireling h) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0b3e: Unknown result type (might be due to invalid IL or missing references) //IL_0b49: Unknown result type (might be due to invalid IL or missing references) //IL_0d34: Unknown result type (might be due to invalid IL or missing references) //IL_0d51: Unknown result type (might be due to invalid IL or missing references) //IL_07f1: Unknown result type (might be due to invalid IL or missing references) //IL_08c2: Unknown result type (might be due to invalid IL or missing references) //IL_0c9e: Unknown result type (might be due to invalid IL or missing references) //IL_0c92: Unknown result type (might be due to invalid IL or missing references) //IL_0a9a: Unknown result type (might be due to invalid IL or missing references) //IL_0acd: Unknown result type (might be due to invalid IL or missing references) PanelUi.Clear((Transform)(object)_content); Transform content = (Transform)(object)_content; InputField? search = _search; if (search != null) { ((Component)search).gameObject.SetActive(_orders && _ordersPicking); } Transform transform = ((Component)this).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val != null) { val.sizeDelta = new Vector2((_enh || _orders) ? 760f : (_why ? 660f : 520f), val.sizeDelta.y); if ((Object)(object)_close != (Object)null) { _close.anchoredPosition = new Vector2(val.sizeDelta.x / 2f - 60f, _close.anchoredPosition.y); } } if (_enh) { BuildEnhancements(h); return; } if (_orders) { BuildOrders(h); return; } if (_why) { BuildWhy(h); return; } bool flag = h.Mode == HirelingMode.Following; PanelUi.Button(content, "$vfh_orders_rename", -190f, -45f, 90f, 30f, delegate { Rename(h); }); PanelUi.Text(content, $"{h.DisplayName} — $vfh_job_{h.Job.ToString().ToLowerInvariant()} $vfh_level {h.Level}", 15f, -45f, 290f, 22, (TextAnchor)4, null, bold: true); float num = -100f; if (flag) { PanelUi.Text(content, "$vfh_orders_mode", -170f, num, 140f, 18, (TextAnchor)3); FollowMode[] array = new FollowMode[3] { FollowMode.Follow, FollowMode.Stay, FollowMode.GatherHere }; for (int num2 = 0; num2 < array.Length; num2++) { FollowMode m = array[num2]; Highlight(PanelUi.Button(content, "$vfh_mode_" + m.ToString().ToLowerInvariant(), -40f + (float)num2 * 110f, num, 104f, 34f, delegate { SetMode(m); }), h.FollowMode == m); } num -= 50f; } PanelUi.Text(content, "$vfh_orders_stance", -170f, num, 140f, 18, (TextAnchor)3); IReadOnlyList<Stance> readOnlyList = StanceRules.Allowed(h.Job, h.Enh.Has(EnhancementId.Watchman)); for (int num3 = 0; num3 < readOnlyList.Count; num3++) { Stance s = readOnlyList[num3]; Highlight(PanelUi.Button(content, "$vfh_stance_" + s.ToString().ToLowerInvariant(), -40f + (float)num3 * 110f, num, 104f, 34f, delegate { SetStance(s); }), h.Stance == s); } num -= 50f; if (VfhConfig.Enhancements.Value && h.BoardId.Length > 0) { ZDO? zdo = h.Zdo; int count = EnhancementRules.Owed(EnhancementPicks.Parse((zdo != null) ? zdo.GetString("vfh_enh", "") : null), h.Level).Count; Highlight(PanelUi.Button(content, (count > 0) ? Localization.instance.Localize("$vfh_enh_open", new string[1] { count.ToString() }) : "$vfh_enh_open_none", 0f, num, 300f, 32f, delegate { _enh = true; _pendingLevel = 0; _shown = ""; }), count > 0); num -= 50f; } JobType job = h.Job; bool flag2 = (uint)job <= 1u; if (flag2 && DataStore.Current.Jobs.TryGetValue(h.Job, out JobData value) && value.GatherToggles.Count > 0) { PanelUi.Text(content, "$vfh_orders_gather", -170f, num, 140f, 18, (TextAnchor)3); HashSet<string> skipItems = h.SkipItems; for (int num4 = 0; num4 < value.GatherToggles.Count; num4++) { string item = value.GatherToggles[num4]; bool flag3 = !skipItems.Contains(item); string text = Localization.instance.Localize(ItemName(item)) + ": " + Localization.instance.Localize(flag3 ? "$vfh_on" : "$vfh_off"); ShowToggle(PanelUi.Button(content, text, -5f + (float)(num4 % 2) * 170f, num - (float)(num4 / 2) * 40f, 164f, 34f, delegate { ToggleItem(item); }), flag3); } num -= (float)((value.GatherToggles.Count + 1) / 2) * 40f + 10f; ShowToggle(PanelUi.Button(content, h.WorksAtHome ? "$vfh_orders_home_work_on" : "$vfh_orders_home_work_off", 0f, num, 360f, 34f, ToggleHome), h.WorksAtHome); num -= 44f; PanelUi.Button(content, Localization.instance.Localize("$vfh_why_open", new string[1] { WhyLines(h).Count.ToString() }), 0f, num, 300f, 32f, OpenWhy); num -= 50f; } if (ChoreRules.ChoresFor(h.Job).Count > 0 && DataStore.Current.Jobs.TryGetValue(h.Job, out JobData value2)) { PanelUi.Text(content, "$vfh_orders_chores", -170f, num, 140f, 18, (TextAnchor)3); ZDO? zdo2 = h.Zdo; HashSet<ChoreKind> hashSet = ChoreRules.ChoresOff((zdo2 != null) ? zdo2.GetString("vfh_skip_items", "") : null); num -= 30f; foreach (ChoreKind kind in ChoreRules.ChoresFor(h.Job)) { string text2 = Localization.instance.Localize("$vfh_chore_" + ChoreKeys.Key(kind)); string text3 = LockedState(kind, value2, h.Level, h.BoardId); if (text3 != null) { PanelUi.Text(content, text2 + ": " + text3, 0f, num, 400f, 15, (TextAnchor)4, PanelUi.Dim); num -= 30f; continue; } bool flag4 = !hashSet.Contains(kind); ShowToggle(PanelUi.Button(content, text2 + ": " + Localization.instance.Localize(flag4 ? "$vfh_chore_state_on" : "$vfh_chore_state_off"), 0f, num, 400f, 30f, delegate { ToggleChore(kind); }), flag4); num -= 34f; string text4 = StillLocked(kind, value2, h.Level); if (text4.Length > 0) { PanelUi.Text(content, text4, 0f, num + 4f, 400f, 13, (TextAnchor)4, PanelUi.Dim); num -= 22f; } } int count2 = WhyLines(h).Count; if (OrderPicks.TakesOrders(h.Job)) { int count3 = OrderPicks.For(BoardOrders.For(BoardOrders.BoardOf(h.BoardId)?.Zdo), h.Job).Count; PanelUi.Button(content, Localization.instance.Localize("$vfh_orders_open", new string[1] { count3.ToString() }), -105f, num - 6f, 200f, 32f, delegate { _orders = true; _ordersPicking = false; _ordersPage = 0; _shown = ""; }); PanelUi.Button(content, Localization.instance.Localize("$vfh_why_open", new string[1] { count2.ToString() }), 105f, num - 6f, 200f, 32f, OpenWhy); } else { PanelUi.Button(content, Localization.instance.Localize("$vfh_why_open", new string[1] { count2.ToString() }), 0f, num - 6f, 300f, 32f, OpenWhy); } num -= 44f; num -= 10f; ZDO? zdo3 = h.Zdo; string text5 = ActivityText.Show(((zdo3 != null) ? zdo3.GetString("vfh_activity", "") : null) ?? ""); if (text5.Length > 0) { Text obj = PanelUi.Text(content, text5, 0f, num - 8f, 440f, 15, (TextAnchor)4, PanelUi.Dim); obj.horizontalOverflow = (HorizontalWrapMode)0; Transform transform2 = ((Component)obj).transform; RectTransform val2 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null); if (val2 != null) { val2.sizeDelta = new Vector2(440f, 40f); } num -= 52f; } } if (flag) { Highlight(PanelUi.Button(content, _all ? "$vfh_orders_all_on" : "$vfh_orders_all_off", 0f, num, 360f, 34f, delegate { _all = !_all; _shown = ""; }), _all); num -= 55f; if (Utils.DistanceXZ(((Component)h).transform.position, h.Home) <= h.Radius) { PanelUi.Button(content, "$vfh_orders_release", 0f, num, 240f, 38f, delegate { Act(FollowerServer.Kind.Release); }); } else { Inventory? cargoInventory = h.CargoInventory; List<string> list = ((cargoInventory != null) ? (from i in cargoInventory.GetAllItems().Where(HomeReturn.LeavesBehind) select Localization.instance.Localize(i.m_shared.m_name)).Distinct().ToList() : null) ?? new List<string>(); PanelUi.Button(content, (list.Count > 0) ? "$vfh_orders_send_home_drop" : "$vfh_orders_send_home", 0f, num, 300f, 38f, delegate { Act(FollowerServer.Kind.SendHome); }); PanelUi.Text(content, (list.Count > 0) ? Localization.instance.Localize("$vfh_orders_send_home_drop_hint", new string[1] { string.Join(", ", list) }) : "$vfh_orders_send_home_hint", 0f, num - 35f, 440f, 15, (TextAnchor)4, (list.Count > 0) ? GUIManager.Instance.ValheimOrange : PanelUi.Dim); } } else if (h.IsParked) { PanelUi.Button(content, "$vfh_roster_back_to_work", 0f, num, 240f, 38f, delegate { BoardContracts.Park(h.Hid, park: false); }); } else if (h.HasPost) { PanelUi.Button(content, "$vfh_orders_clear_post", 0f, num, 240f, 38f, delegate { Act(FollowerServer.Kind.ClearPost); }); } Transform transform3 = ((Component)this).transform; RectTransform val3 = (RectTransform)(object)((transform3 is RectTransform) ? transform3 : null); if (val3 != null) { val3.sizeDelta = new Vector2(val3.sizeDelta.x, Mathf.Max(420f, 0f - num + 70f)); } } private void BuildEnhancements(Hireling h) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_0130: 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) Transform content = (Transform)(object)_content; PanelUi.Button(content, "$vfh_orders_back", -320f, -45f, 100f, 30f, delegate { _enh = false; _pendingLevel = 0; _shown = ""; }); PanelUi.Text(content, Localization.instance.Localize("$vfh_enh_title", new string[1] { h.DisplayName }), -10f, -45f, 420f, 22, (TextAnchor)4, null, bold: true); float num = -85f; if (!VfhConfig.Enhancements.Value) { PanelUi.Text(content, "$vfh_enh_off", 0f, num, 600f, 16, (TextAnchor)4, PanelUi.Dim); return; } PanelUi.Text(content, "$vfh_enh_hint", 0f, num, 660f, 14, (TextAnchor)4, PanelUi.Dim); num -= 45f; ZDO? zdo = h.Zdo; EnhancementPicks enhancementPicks = EnhancementPicks.Parse((zdo != null) ? zdo.GetString("vfh_enh", "") : null); for (int num2 = 2; num2 <= 8; num2++) { char c = enhancementPicks.Get(num2); Color value = ((num2 > h.Level) ? PanelUi.Dim : ((c == '-') ? GUIManager.Instance.ValheimOrange : GUIManager.Instance.ValheimBeige)); PanelUi.Text(content, Localization.instance.Localize("$vfh_enh_level", new string[1] { num2.ToString() }), -330f, num, 80f, 16, (TextAnchor)3, value, bold: true); var (id, id2) = EnhancementCatalog.Pair(h.Job, num2); Option(h, num2, 'A', id, -125f, num, c); Option(h, num2, 'B', id2, 200f, num, c); num -= 74f; } Transform transform = ((Component)this).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val != null) { val.sizeDelta = new Vector2(val.sizeDelta.x, Mathf.Max(420f, 0f - num + 40f)); } } private void Option(Hireling h, int level, char choice, EnhancementId id, float x, float y, char chosen) { //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) Transform content = (Transform)(object)_content; string text = Localization.instance.Localize(EnhancementText.NameKey(h.Job, id)); string text2 = Localization.instance.Localize(EnhancementText.DescKey(h.Job, id), EnhancementText.Args(DataStore.Current, h.Job, id)); bool flag = level > h.Level; bool flag2 = _pendingLevel == level && _pendingChoice == choice; string text3 = (flag2 ? Localization.instance.Localize("$vfh_enh_confirm", new string[1] { text }) : ((chosen == choice) ? ("✓ " + text) : text)); Button val = PanelUi.Button(content, text3, x, y, 310f, 30f, delegate { ClickOption(h, level, choice); }); if (chosen == choice) { Highlight(val, on: true); } else if (chosen != '-' || flag) { ((Selectable)val).interactable = false; } else if (flag2) { Highlight(val, on: true); } ((Graphic)PanelUi.Text(content, text2, x, y - 33f, 310f, 12, (TextAnchor)1, (chosen == choice) ? GUIManager.Instance.ValheimBeige : PanelUi.Dim)).rectTransform.SetSizeWithCurrentAnchors((Axis)1, 32f); } private void ClickOption(Hireling h, int level, char choice) { if (_pendingLevel == level && _pendingChoice == choice) { _pendingLevel = 0; BoardContracts.ChooseEnhancement(h.BoardId, h.Hid, level, choice); VfhLog.I(LogCat.UI, "enh.choose", ("hid", h.Hid), ("level", level), ("choice", choice)); } else { _pendingLevel = level; _pendingChoice = choice; } _shown = ""; } private void BuildOrders(Hireling h) { //IL_00f5: 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_0355: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0543: Unknown result type (might be due to invalid IL or missing references) //IL_0585: Unknown result type (might be due to invalid IL or missing references) //IL_060c: Unknown result type (might be due to invalid IL or missing references) //IL_0605: Unknown result type (might be due to invalid IL or missing references) //IL_05fe: Unknown result type (might be due to invalid IL or missing references) Transform content = (Transform)(object)_content; PanelUi.Button(content, "$vfh_orders_back", -310f, -45f, 100f, 30f, delegate { if (_ordersPicking) { _ordersPicking = false; } else { _orders = false; } _shown = ""; }); PanelUi.Text(content, Localization.instance.Localize(_ordersPicking ? "$vfh_orders_pick_title" : "$vfh_orders_title", new string[1] { h.DisplayName }), 30f, -45f, 480f, 22, (TextAnchor)4, null, bold: true); float num = -85f; HiringBoard board = BoardOrders.BoardOf(h.BoardId); if ((Object)(object)board == (Object)null) { PanelUi.Text(content, "$vfh_orders_no_board", 0f, num, 600f, 16, (TextAnchor)4, PanelUi.Dim); Fit(0f - num + 60f); return; } bool flag = PrivateArea.CheckAccess(((Component)board).transform.position, 0f, false, false); OrderList list = BoardOrders.For(board); if (_ordersPicking) { num -= 52f; List<OrderPicks.Pick> list2 = (from p in OrderPicks.Picks(h.Job) where list.Find(p.Item) == null && Matches(p) select p).ToList(); int num2 = Mathf.Max(1, (list2.Count + 14 - 1) / 14); _ordersPage = Mathf.Clamp(_ordersPage, 0, num2 - 1); int num3 = 0; foreach (OrderPicks.Pick item2 in list2.Skip(_ordersPage * 14).Take(14)) { float x = ((num3 % 2 == 0) ? (-180f) : 180f); float num4 = num - (float)(num3 / 2) * 48f; bool flag2 = h.Level >= item2.Level; OrderPicks.Pick chosen = item2; ((Selectable)PanelUi.Button(content, OrderPicks.PickLabel(item2), x, num4, 340f, 30f, delegate { BoardOrders.Submit(board, OrderEdit.Add, chosen.Item, chosen.Kind, OrderPicks.StartTarget(chosen.Kind)); _ordersPicking = false; _ordersPage = 0; ClearSearch(); _shown = ""; })).interactable = flag; PanelUi.Text(content, Localization.instance.Localize(flag2 ? "$vfh_orders_level" : "$vfh_orders_needs_level", new string[1] { item2.Level.ToString() }), x, num4 - 20f, 340f, 12, (TextAnchor)4, flag2 ? PanelUi.Dim : PanelUi.Bad); num3++; } if (list2.Count == 0) { PanelUi.Text(content, (_ordersSearch.Trim().Length > 0) ? Localization.instance.Localize("$vfh_orders_search_none", new string[1] { _ordersSearch.Trim() }) : "$vfh_orders_pick_none", 0f, num, 600f, 16, (TextAnchor)4, PanelUi.Dim); } num -= (float)Mathf.Max(1, (num3 + 1) / 2) * 48f + 6f; num = OrdersPager(content, num, num2); Fit(0f - num + 50f); return; } PanelUi.Text(content, "$vfh_orders_hint", 0f, num, 700f, 14, (TextAnchor)4, PanelUi.Dim); num -= 38f; Stock stock = BoardOrders.Stock(board); List<ProductionOrder> list3 = OrderPicks.For(list, h.Job); int num5 = Mathf.Max(1, (list3.Count + 10 - 1) / 10); _ordersPage = Mathf.Clamp(_ordersPage, 0, num5 - 1); if (list3.Count == 0) { PanelUi.Text(content, "$vfh_orders_none", 0f, num, 600f, 16, (TextAnchor)4, PanelUi.Dim); num -= 36f; } List<Container> chests = ((h.Job == JobType.Smelter) ? ChestModes.Stock(ChestFinder.Find(h.WorkCentre, h.Radius)).ToList() : new List<Container>()); foreach (ProductionOrder o in list3.Skip(_ordersPage * 10).Take(10)) { int value; int have = ((o.Kind == OrderKind.Station) ? (StewardLimits.Held(chests, o.Item) + (stock.Piled.TryGetValue(o.Item, out value) ? value : 0)) : OrderPicks.Have(board, stock, o)); bool flag3 = o.Item == "*"; Sprite val = OrderPicks.Icon(o.Item); if (val != null) { PanelUi.Icon(content, val, -345f, num, 32f); } PanelUi.Text(content, OrderPicks.Name(o.Item), -195f, num + 8f, 240f, 16, (TextAnchor)3, o.Paused ? new Color?(PanelUi.Dim) : ((Color?)null)); PanelUi.Text(content, flag3 ? "$vfh_orders_everything_hint" : OrderPicks.KindLabel(o.Kind), -195f, num - 10f, 240f, 12, (TextAnchor)3, PanelUi.Dim); PanelUi.Text(content, o.Paused ? Localization.instance.Localize("$vfh_limits_paused") : OrderPicks.Progress(o, have), 15f, num, 120f, 16, (TextAnchor)4, (o.Paused || o.IsInfinite) ? PanelUi.Dim : (OrderPicks.Met(o, have) ? PanelUi.Good : PanelUi.Bad)); string item = o.Item; List<Button> list4 = new List<Button>(); if (!flag3) { Button obj = PanelUi.Button(content, "-", 68f, num, 30f, 30f, delegate { BoardOrders.Submit(board, OrderEdit.Target, item, OrderKind.Crop, o.Target - OrderStep()); }); Button val2 = PanelUi.Button(content, "+", 102f, num, 30f, 30f, delegate { BoardOrders.Submit(board, OrderEdit.Target, item, OrderKind.Crop, o.Target + OrderStep()); }); bool interactable = (((Selectable)val2).interactable = flag && !o.IsInfinite); ((Selectable)obj).interactable = interactable; int back = ((o.Kind == OrderKind.Station) ? 100 : OrderPicks.StartTarget(o.Kind)); Button val3 = PanelUi.Button(content, "∞", 140f, num, 34f, 30f, delegate { BoardOrders.Submit(board, OrderEdit.Target, item, OrderKind.Crop, o.IsInfinite ? back : int.MaxValue); }); Highlight(val3, o.IsInfinite); list4.Add(val3); list4.Add(PanelUi.Button(content, "^", 180f, num, 30f, 30f, delegate { BoardOrders.Submit(board, OrderEdit.Up, item); })); list4.Add(PanelUi.Button(content, "v", 214f, num, 30f, 30f, delegate { BoardOrders.Submit(board, OrderEdit.Down, item); })); } list4.Add(PanelUi.Button(content, o.Paused ? "$vfh_orders_resume" : "$vfh_orders_pause", 278f, num, 90f, 30f, delegate { BoardOrders.Submit(board, OrderEdit.Pause, item, OrderKind.Crop, 0, !o.Paused); })); list4.Add(PanelUi.Button(content, "X", 345f, num, 30f, 30f, delegate { BoardOrders.Submit(board, OrderEdit.Remove, item); })); foreach (Button item3 in list4) { ((Selectable)item3).interactable = flag; } num -= 44f; } num = OrdersPager(content, num, num5); num -= 6f; ((Selectable)PanelUi.Button(content, "$vfh_orders_add", 0f, num, 260f, 34f, delegate { _ordersPicking = true; _ordersPage = 0; ClearSearch(); _shown = ""; })).interactable = flag; num -= 40f; Fit(0f - num + 50f); } private float OrdersPager(Transform t, float y, int pages) { if (pages <= 1) { return y; } PanelUi.Button(t, "<", -60f, y, 40f, 30f, delegate { _ordersPage = Mathf.Max(0, _ordersPage - 1); _shown = ""; }); PanelUi.Text(t, $"{_ordersPage + 1} / {pages}", 0f, y, 70f, 16, (TextAnchor)4); PanelUi.Button(t, ">", 60f, y, 40f, 30f, delegate { _ordersPage = Mathf.Min(pages - 1, _ordersPage + 1); _shown = ""; }); return y - 40f; } private static int OrderStep() { if (!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303)) { return 5; } return 1; } private void OpenWhy() { _why = true; _whyPage = 0; _shown = ""; } private static List<(string Item, string Why)> WhyLines(Hireling h) { ZDO? zdo = h.Zdo; return (from l in (((zdo != null) ? zdo.GetString("vfh_why", "") : null) ?? "").Split(new char[1] { '\n' }) where l.Length > 0 select l).Select(delegate(string l) { int num = l.IndexOf('\t'); return (num >= 0) ? (l.Substring(0, num), l.Substring(num + 1)) : ("", l); }).ToList(); } private static List<ProductionOrder> WhyOrders(Hireling h, HiringBoard board) { return OrderPicks.For(BoardOrders.For(board), h.Job); } private void BuildWhy(Hireling h) { //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0548: Unknown result type (might be due to invalid IL or missing references) //IL_0589: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0351: 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_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) Transform content = (Transform)(object)_content; PanelUi.Button(content, "$vfh_orders_back", -250f, -45f, 100f, 30f, delegate { _why = false; _shown = ""; }); PanelUi.Text(content, Localization.instance.Localize("$vfh_why_title", new string[1] { h.DisplayName }), 20f, -45f, 380f, 22, (TextAnchor)4, null, bold: true); float num = -90f; List<(string, string)> source = WhyLines(h); Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (var item3 in source.Where<(string, string)>(((string Item, string Why) l) => l.Item.Length > 0)) { string item = item3.Item1; string item2 = item3.Item2; dictionary[item] = item2; } HiringBoard hiringBoard = BoardOrders.BoardOf(h.BoardId); if (OrderPicks.TakesOrders(h.Job)) { PanelUi.Text(content, "$vfh_why_orders", 0f, num, 560f, 17, (TextAnchor)4, null, bold: true); num -= 34f; List<ProductionOrder> list = (((Object)(object)hiringBoard != (Object)null) ? WhyOrders(h, hiringBoard) : new List<ProductionOrder>()); if (list.Count == 0) { PanelUi.Text(content, ((Object)(object)hiringBoard == (Object)null) ? "$vfh_limits_no_board" : "$vfh_why_no_orders", 0f, num, 560f, 15, (TextAnchor)4, PanelUi.Dim); num -= 32f; } int pages = Mathf.Max(1, (list.Count + 10 - 1) / 10); _whyPage = Mathf.Clamp(_whyPage, 0, pages - 1); Stock stock = (((Object)(object)hiringBoard != (Object)null) ? BoardOrders.Stock(hiringBoard) : null); foreach (ProductionOrder item4 in list.Skip(_whyPage * 10).Take(10)) { int value; int have = ((item4.Kind != OrderKind.Herd) ? stock.Have(item4.Item) : (RanchState.For(hiringBoard).Adults.TryGetValue(item4.Item, out value) ? value : 0)); Sprite val = OrderPicks.Icon(item4.Item); if (val != null) { PanelUi.Icon(content, val, -295f, num, 28f); } PanelUi.Text(content, OrderPicks.Name(item4.Item), -195f, num, 170f, 15, (TextAnchor)3, item4.Paused ? new Color?(PanelUi.Dim) : ((Color?)null)); PanelUi.Text(content, OrderPicks.Progress(item4, have), -75f, num, 80f, 15, (TextAnchor)4, OrderPicks.Met(item4, have) ? PanelUi.Good : PanelUi.Dim); Color value3; string text2; if (!item4.Paused) { if (!OrderPicks.Met(item4, have)) { if (!dictionary.TryGetValue(item4.Item, out var value2)) { string text = Localization.instance.Localize("$vfh_why_on_it"); Color good = PanelUi.Good; value3 = good; text2 = text; } else { string text3 = ActivityText.Show(value2); Color good = PanelUi.Bad; value3 = good; text2 = text3; } } else { string text4 = Localization.instance.Localize("$vfh_why_done"); Color good = PanelUi.Good; value3 = good; text2 = text4; } } else { string text5 = Localization.instance.Localize("$vfh_limits_paused"); Color good = PanelUi.Dim; value3 = good; text2 = text5; } PanelUi.Text(content, text2, 155f, num, 340f, 13, (TextAnchor)3, value3); num -= 34f; } if (pages > 1) { PanelUi.Button(content, "<", -60f, num, 40f, 30f, delegate { _whyPage = Mathf.Max(0, _whyPage - 1); _shown = ""; }); PanelUi.Text(content, $"{_whyPage + 1} / {pages}", 0f, num, 70f, 16, (TextAnchor)4); PanelUi.Button(content, ">", 60f, num, 40f, 30f, delegate { _whyPage = Mathf.Min(pages - 1, _whyPage + 1); _shown = ""; }); num -= 40f; } num -= 10f; } Transform parent = content; JobType job = h.Job; bool flag = (uint)job <= 1u; PanelUi.Text(parent, flag ? "$vfh_why_found" : "$vfh_why_other", 0f, num, 560f, 17, (TextAnchor)4, null, bold: true); num -= 32f; List<string> list2 = (from l in source where l.Item.Length == 0 select l.Why).ToList(); if (list2.Count == 0) { PanelUi.Text(content, "$vfh_why_none", 0f, num, 560f, 15, (TextAnchor)4, PanelUi.Dim); num -= 30f; } foreach (string item5 in list2) { PanelUi.Text(content, ActivityText.Show(item5), 0f, num, 600f, 14, (TextAnchor)4, PanelUi.Bad); num -= 28f; } Fit(0f - num + 50f); } private void Fit(float height) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)this).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val != null) { val.sizeDelta = new Vector2(val.sizeDelta.x, Mathf.Max(420f, height)); } } private static string ItemName(string prefab) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 != (Object)null) { return val2.m_itemData.m_shared.m_name; } ZNetScene instance = ZNetScene.instance; object obj; if (instance == null) { obj = null; } else { GameObject prefab2 = instance.GetPrefab(prefab); obj = ((prefab2 != null) ? prefab2.GetComponent<Character>() : null); } Character val3 = (Character)obj; if (val3 == null) { return prefab; } return val3.m_name; } private void ToggleItem(string item) { Hireling h = _hireling; bool flag = !h.SkipItems.Contains(item); foreach (Hireling item2 in from f in Targets() where f.Job == h.Job select f) { HashSet<string> hashSet = new HashSet<string>(item2.SkipItems); if (flag) { hashSet.Add(item); } else { hashSet.Remove(item); } SubmitGather(item2, hashSet, !item2.WorksAtHome); } } private static string? LockedState(ChoreKind kind, JobData steward, int level, string boardId) { if (!ChoreLoop.ServerAllows(kind)) { return Localization.instance.Localize("$vfh_chore_state_disabled"); } if (kind == ChoreKind.Animals && ChoreLoop.RancherOnBoard(boardId)) { return Localization.instance.Localize("$vfh_chore_state_rancher"); } string text = StewardCompat.HandledBy(kind); if (text != null) { return Localization.instance.Localize("$vfh_chore_state_handled", new string[1] { text }); } int num = ChoreRules.FirstUnlock(steward, kind); if (num == int.MaxValue) { return Localization.instance.Localize("$vfh_chore_state_disabled"); } if (level >= num) { return null; } return Localization.instance.Localize("$vfh_chore_state_locked", new string[1] { num.ToString() }); } private static string StillLocked(ChoreKind kind, JobData steward, int level) { if ((uint)(kind - 2) > 2u) { return ""; } return string.Join(", ", from k in ChoreRules.GateKeys(steward, kind) where ChoreRules.MinLevel(steward, k) > level select StationName(k) + ": " + Localization.instance.Localize("$vfh_chore_state_locked", new string[1] { ChoreRules.MinLevel(steward, k).ToString() })); } private static string StationName(string prefab) { object obj; if (!((Object)(object)ZNetScene.instance != (Object)null)) { obj = null; } else { GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); obj = ((prefab2 != null) ? prefab2.GetComponent<Piece>() : null); } Piece val = (Piece)obj; if (!((Object)(object)val != (Object)null)) { return prefab; } return Localization.instance.Localize(val.m_name); } private void ToggleChore(ChoreKind kind) { Hireling h = _hireling; ZDO? zdo = h.Zdo; bool flag = ChoreRules.ChoresOff((zdo != null) ? zdo.GetString("vfh_skip_items", "") : null).Contains(kind); foreach (Hireling item in from f in Targets() where f.Job == h.Job select f) { ZDO? zdo2 = item.Zdo; string skip = ChoreRules.WithChore((zdo2 != null) ? zdo2.GetString("vfh_skip_items", "") : null, kind, flag); SubmitGather(item, GatherRules.ParseSkip(skip), !item.WorksAtHome); } _shown = ""; } private void ToggleHome() { Hireling h = _hireling; bool worksAtHome = h.WorksAtHome; foreach (Hireling item in from f in Targets() where f.Job == h.Job select f) { SubmitGather(item, item.SkipItems, worksAtHome); } } private static void SubmitGather(Hireling f, HashSet<string> skip, bool noHomeWork) { string text = GatherRules.FormatSkip(skip); if (f.BoardId.Length > 0) { MutationService.SubmitBoard(f.BoardId, new RosterOp { Type = RosterOpType.SetGather, Hid = f.Hid, SkipItems = text, NoHomeWork = noHomeWork }); } else { MutationService.SubmitHireling(f.Hid, new HirelingOp { SkipItems = text, NoHomeWork = noHomeWork }); } VfhLog.I(LogCat.UI, "hireling.gather_set", ("hid", f.Hid), ("skip", text), ("noHomeWork", noHomeWork)); } private static void ShowToggle(Button b, bool on) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) Text componentInChildren = ((Component)b).GetComponentInChildren<Text>(); if ((Object)(object)componentInChildren != (Object)null) { ((Graphic)componentInChildren).color = (Color)(on ? GUIManager.Instance.ValheimOrange : new Color(0.55f, 0.55f, 0.55f)); } Graphic targetGraphic = ((Selectable)b).targetGraphic; Image val = (Image)(object)((targetGraphic is Image) ? targetGraphic : null); if (val != null) { ((Graphic)val).color = (Color)(on ? Color.white : new Color(0.45f, 0.45f, 0.45f, 0.8f)); } } private static void Highlight(Button b, bool on) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Text componentInChildren = ((Component)b).GetComponentInChildren<Text>(); if ((Object)(object)componentInChildren != (Object)null) { ((Graphic)componentInChildren).color = (on ? GUIManager.Instance.ValheimOrange : GUIManager.Instance.ValheimBeige); } } private IEnumerable<Hireling> Targets() { Hireling hireling = _hireling; if (!_all || hireling.Mode != HirelingMode.Following) { return new Hireling[1] { hireling }; } return StoneInput.MyFollowers(Player.m_localPlayer, 30f).Append(hireling).Distinct(); } private void SetMode(FollowMode mode) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) foreach (Hireling item in Targets()) { Vector3 position = ((Component)item).transform.position; item.Ai.Order = null; MutationService.SubmitHireling(item.Hid, (mode == FollowMode.Follow) ? new HirelingOp { FollowMode = mode } : new HirelingOp { FollowMode = mode, StayPos = (position.x, position.y, position.z) }); VfhLog.I(LogCat.Follow, "follow.mode", ("hid", item.Hid), ("mode", mode), ("via", "panel")); } } private void SetStance(Stance stance) { foreach (Hireling item in Targets()) { if (StanceRules.IsAllowed(item.Job, stance, item.Enh.Has(EnhancementId.Watchman)) && item.BoardId.Length != 0) { MutationService.SubmitBoard(item.BoardId, new RosterOp { Type = RosterOpType.Edit, Hid = item.Hid, Radius = item.ContractRadius, Stance = stance }); VfhLog.I(LogCat.Follow, "follow.stance", ("hid", item.Hid), ("stance", stance), ("via", "panel")); } } } private void Rename(Hireling h) { Close("rename"); TextInput.instance.RequestText((TextReceiver)(object)new RenameReceiver(h), "$vfh_rename_topic", 24); } private void Act(FollowerServer.Kind kind) { Hireling hireling = _hireling; int quality = (from i in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems().Where(CommandStoneItem.IsStone) select i.m_quality).DefaultIfEmpty(0).Max(); FollowerServer.Send(kind, hireling.Hid, quality); Close("action"); } } internal interface IBoardTab { string Title { get; } string Signature(HiringBoard board); void Build(RectTransform root, HiringBoard board); } internal static class OrderPicks { public sealed class Pick { public string Item = ""; public OrderKind Kind; public int Level; } public static readonly JobType[] Jobs = new JobType[4] { JobType.Farmer, JobType.Cook, JobType.Rancher, JobType.Smelter }; public static bool TakesOrders(JobType job) { switch (job) { case JobType.Smelter: case JobType.Farmer: case JobType.Cook: case JobType.Rancher: return true; default: return false; } } public static List<ProductionOrder> For(OrderList list, JobType job) { return job switch { JobType.Farmer => list.Orders.Where((ProductionOrder o) => o.Kind == OrderKind.Seed).Concat(list.Orders.Where((ProductionOrder o) => o.Kind == OrderKind.Crop)).ToList(), JobType.Cook => list.Orders.Where((ProductionOrder o) => o.Kind == OrderKind.Kitchen).ToList(), JobType.Rancher => list.Orders.Where((ProductionOrder o) => o.IsRanch).ToList(), JobType.Smelter => list.Orders.Where((ProductionOrder o) => o.Kind == OrderKind.Station && o.Item != "*").Concat(list.Orders.Where((ProductionOrder o) => o.Kind == OrderKind.Station && o.Item == "*")).ToList(), _ => new List<ProductionOrder>(), }; } public static int Have(HiringBoard board, Stock stock, ProductionOrder o) { if (o.Kind != OrderKind.Herd) { return stock.Have(o.Item); } return HerdHave(board, o.Item); } private static int HerdHave(HiringBoard board, string kind) { if (!RanchState.For(board).Adults.TryGetValue(kind, out var value)) { return 0; } return value; } public static string KindLabel(OrderKind kind) { return kind switch { OrderKind.Seed => "$vfh_orders_kind_seed", OrderKind.Crop => "$vfh_orders_kind_farm", OrderKind.Meat => "$vfh_orders_kind_meat", OrderKind.Egg => "$vfh_orders_kind_egg", OrderKind.Herd => "$vfh_orders_kind_herd", OrderKind.Station => "$vfh_orders_kind_steward", _ => "$vfh_orders_kind_kitchen", }; } public static int StartTarget(OrderKind kind) { return kind switch { OrderKind.Seed => 10, OrderKind.Meat => 40, OrderKind.Herd => 4, OrderKind.Station => int.MaxValue, _ => 20, }; } public static string TargetText(int target) { if (target != int.MaxValue) { return target.ToString(); } return "∞"; } public static string Progress(ProductionOrder o, int have) { if (!(o.Item == "*")) { return $"{have} / {TargetText(o.Target)}"; } return "∞"; } public static bool Met(ProductionOrder o, int have) { if (!o.IsInfinite) { return have >= o.Target; } return false; } public static List<Pick> Picks(JobType job) { switch (job) { case JobType.Smelter: { JobData value; JobData steward = (DataStore.Current.Jobs.TryGetValue(JobType.Smelter, out value) ? value : new JobData()); List<Pick> list2 = new List<Pick>(); list2.Add(new Pick { Item = "*", Kind = OrderKind.Station, Level = 1 }); list2.AddRange(from p in StewardLimits.Products() select new Pick { Item = p.Item, Kind = OrderKind.Station, Level = ChoreRules.MinLevel(steward, p.Gate) }); return list2; } case JobType.Rancher: { List<Pick> ranch = new List<Pick>(); foreach (AnimalKind k in AnimalCatalog.Kinds) { ranch.Add(new Pick { Item = k.Prefab, Kind = OrderKind.Herd, Level = 1 }); foreach (string item in k.Meats.Keys.Where((string m) => ranch.All((Pick p) => p.Item != m))) { ranch.Add(new Pick { Item = item, Kind = OrderKind.Meat, Level = 1 }); } if (k.EggItem.Length > 0 && ranch.All((Pick p) => p.Item != k.EggItem)) { ranch.Add(new Pick { Item = k.EggItem, Kind = OrderKind.Egg, Level = 1 }); } } return (from p in ranch orderby p.Kind, Name(p.Item) select p).ToList(); } case JobType.Cook: return (from kitchenInfo in KitchenCatalog.All group kitchenInfo by kitchenInfo.Output into g select new Pick { Item = g.Key, Kind = OrderKind.Kitchen, Level = g.Min((KitchenInfo kitchenInfo) => kitchenInfo.Level) } into p orderby p.Level, Name(p.Item) select p).ToList(); default: { List<CropInfo> list = CropCatalog.Infos.ToList(); Dictionary<string, Pick> dictionary = new Dictionary<string, Pick>(); foreach (CropInfo item2 in list) { AddPick(dictionary, item2.Yields, item2.Level, list); if (!item2.Regrowing) { AddPick(dictionary, item2.Consumes, item2.Level, list); } } return (from p in dictionary.Values orderby p.Level, p.Kind, Name(p.Item) select p).ToList(); } } } private static void AddPick(Dictionary<string, Pick> picks, string item, int level, List<CropInfo> crops) { if (string.IsNullOrEmpty(item)) { return; } bool flag = CropInfo.IsSeedItem(item, crops, delegate(string i) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(i); return (itemPrefab != null && CropCatalog.IsFood(itemPrefab)) || KitchenCatalog.All.Any((KitchenInfo k) => k.Inputs.ContainsKey(i)); }); if (picks.TryGetValue(item, out Pick value)) { value.Level = Mathf.Min(value.Level, level); return; } picks[item] = new Pick { Item = item, Kind = ((!flag) ? OrderKind.Crop : OrderKind.Seed), Level = level }; } public static string PickLabel(Pick p) { if (p.Kind != OrderKind.Herd) { return Name(p.Item) + ((p.Kind == OrderKind.Seed) ? (" (" + Localization.instance.Localize("$vfh_orders_kind_seed") + ")") : ""); } return Localization.instance.Localize("$vfh_orders_pick_herd", new string[1] { Name(p.Item) }); } public static string Name(string item) { if (!(item == "*")) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item); ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); if (val == null) { ZNetScene instance = ZNetScene.instance; object obj; if (instance == null) { obj = null; } else { GameObject prefab = instance.GetPrefab(item); obj = ((prefab != null) ? prefab.GetComponent<Character>() : null); } Character val2 = (Character)obj; if (val2 == null) { return item; } return Localization.instance.Localize(val2.m_name); } return Localization.instance.Localize(val.m_itemData.m_shared.m_name); } return Localization.instance.Localize("$vfh_orders_everything"); } public static Sprite? Icon(string item) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item); if (itemPrefab == null) { return null; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if (component == null) { return null; } return component.m_itemData.GetIcon(); } } internal sealed class OrdersTab : IBoardTab { private const float RowStep = 26f; private const float Top = -150f; private const float Bottom = -640f; private int _page; public string Title => "$vfh_tab_orders"; public string Signature(HiringBoard board) { OrderList orderList = BoardOrders.For(board); Stock stock = BoardOrders.Stock(board); return $"{_page}|{orderList.Serialize()}|" + string.Join(",", orderList.Orders.Select((ProductionOrder o) => OrderPicks.Have(board, stock, o))) + "|" + string.Join(",", OrderPicks.Jobs.Select((JobType j) => Worker(board, j)?.Name ?? "-")); } private static ContractEntry? Worker(HiringBoard board, JobType job) { if (board.Zdo != null) { return BoardRosterOps.Read(board.Zdo).Entries.FirstOrDefault((ContractEntry e) => e.Job == job && e.State != ContractState.Leaving); } return null; } public void Build(RectTransform root, HiringBoard board) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) PanelUi.Text((Transform)(object)root, "$vfh_orders_overview_hint", 0f, -125f, 800f, 15, (TextAnchor)4, PanelUi.Dim); OrderList list = BoardOrders.For(board); Stock stock = BoardOrders.Stock(board); List<(JobType, ContractEntry, ProductionOrder)> list2 = new List<(JobType, ContractEntry, ProductionOrder)>(); JobType[] jobs = OrderPicks.Jobs; foreach (JobType jobType in jobs) { List<ProductionOrder> list3 = OrderPicks.For(list, jobType); ContractEntry contractEntry = Worker(board, jobType); if (list3.Count == 0 && contractEntry == null) { continue; } list2.Add((jobType, contractEntry, null)); if (list3.Count == 0) { list2.Add((jobType, contractEntry, new ProductionOrder { Item = "" })); } foreach (ProductionOrder item in list3) { list2.Add((jobType, contractEntry, item)); } } if (list2.Count == 0) { PanelUi.Text((Transform)(object)root, "$vfh_orders_empty", 0f, -230f, 760f, 17, (TextAnchor)4, PanelUi.Dim); return; } int num = 18; int num2 = (list2.Count + num - 1) / num; _page = Mathf.Clamp(_page, 0, num2 - 1); float num3 = -170f; foreach (var (jobType2, contractEntry2, productionOrder) in list2.Skip(_page * num).Take(num)) { if (productionOrder == null) { string text = ((contractEntry2 != null) ? Localization.instance.Localize("$vfh_orders_overview_worker", new string[3] { "$vfh_job_" + jobType2.ToString().ToLowerInvariant(), contractEntry2.Name, contractEntry2.Level.ToString() }) : Localization.instance.Localize("$vfh_orders_overview_none", new string[1] { "$vfh_job_" + jobType2.ToString().ToLowerInvariant() })); PanelUi.Text((Transform)(object)root, text, 0f, num3 - 4f, 760f, 17, (TextAnchor)3, null, bold: true); } else if (productionOrder.Item.Length == 0) { PanelUi.Text((Transform)(object)root, "$vfh_orders_overview_no_orders", 20f, num3, 720f, 14, (TextAnchor)3, PanelUi.Dim); } else { int have = OrderPicks.Have(board, stock, productionOrder); Sprite val = OrderPicks.Icon(productionOrder.Item); if (val != null) { PanelUi.Icon((Transform)(object)root, val, -360f, num3, 22f); } PanelUi.Text((Transform)(object)root, OrderPicks.Name(productionOrder.Item), -200f, num3, 280f, 15, (TextAnchor)3, productionOrder.Paused ? new Color?(PanelUi.Dim) : ((Color?)null)); PanelUi.Text((Transform)(object)root, OrderPicks.KindLabel(productionOrder.Kind), 100f, num3, 300f, 13, (TextAnchor)3, PanelUi.Dim); PanelUi.Text((Transform)(object)root, productionOrder.Paused ? Localization.instance.Localize("$vfh_limits_paused") : OrderPicks.Progress(productionOrder, have), 320f, num3, 120f, 15, (TextAnchor)4, (productionOrder.Paused || productionOrder.IsInfinite) ? PanelUi.Dim : (OrderPicks.Met(productionOrder, have) ? PanelUi.Good : PanelUi.Bad)); } num3 -= 26f; } Pager(root, _page, num2, delegate(int p) { _page = p; }); } internal static void Pager(RectTransform root, int page, int pages, Action<int> go) { if (pages > 1) { PanelUi.Button((Transform)(object)root, "<", -70f, -665f, 46f, 32f, delegate { go(Mathf.Max(0, page - 1)); }); PanelUi.Text((Transform)(object)root, $"{page + 1} / {pages}", 0f, -665f, 80f, 17, (TextAnchor)4); PanelUi.Button((Transform)(object)root, ">", 70f, -665f, 46f, 32f, delegate { go(Mathf.Min(pages - 1, page + 1)); }); } } } internal static class PanelUi { public static readonly Color Good = new Color(0.6f, 1f, 0.6f); public static readonly Color Bad = new Color(1f, 0.45f, 0.45f); public static readonly Color Dim = new Color(0.75f, 0.75f, 0.75f); private static readonly Vector2 TopCenter = new Vector2(0.5f, 1f); private const float ClickDebounceSeconds = 0.25f; private static float _lastClick = -1f; public static event Action? Clicked; public static Text Text(Transform parent, string text, float x, float y, float width, int size = 18, TextAnchor align = (TextAnchor)4, Color? color = null, bool bold = false) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) Text component = GUIManager.Instance.CreateText(Localization.instance.Localize(text), parent, TopCenter, TopCenter, new Vector2(x, y), bold ? GUIManager.Instance.AveriaSerifBold : GUIManager.Instance.AveriaSerif, size, (Color)(((??)color) ?? GUIManager.Instance.ValheimBeige), true, Color.black, width, (float)(size + 12), false).GetComponent<Text>(); component.alignment = align; return component; } public static Button Button(Transform parent, string text, float x, float y, float width, float height, Action onClick) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown GameObject obj = GUIManager.Instance.CreateButton(Localization.instance.Localize(text), parent, TopCenter, TopCenter, new Vector2(x, y), width, height); ButtonSfx component = obj.GetComponent<ButtonSfx>(); if ((Object)(object)component != (Object)null) { component.m_enterSfxPrefab = null; component.m_enterSfxPrefabVibrationOnly = null; component.m_selectSfxPrefab = null; component.m_selectSfxPrefabVibrationOnly = null; } Button component2 = obj.GetComponent<Button>(); ((UnityEvent)component2.onClick).AddListener((UnityAction)delegate { if (!(Time.unscaledTime - _lastClick < 0.25f)) { _lastClick = Time.unscaledTime; onClick(); PanelUi.Clicked?.Invoke(); } }); return component2; } public static Image Icon(Transform parent, Sprite? sprite, float x, float y, float size) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_004a: 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_0056: 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_0067: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("icon", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; Vector2 anchorMin = (val2.anchorMax = TopCenter); val2.anchorMin = anchorMin; val2.anchoredPosition = new Vector2(x, y); val2.sizeDelta = new Vector2(size, size); Image component = val.GetComponent<Image>(); component.sprite = sprite; component.preserveAspect = true; return component; } public static RectTransform Fill(Transform parent, string name) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0030: 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_003b: 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_0046: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; Vector2 offsetMin = (val2.offsetMax = Vector2.zero); val2.offsetMin = offsetMin; return val2; } public static void Clear(Transform t) { for (int num = t.childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)t.GetChild(num)).gameObject); } } } internal sealed class RosterTab : IBoardTab { private const float RadiusStep = 5f; private string _selected = ""; private string _confirmDismiss = ""; private string _confirmRespec = ""; public string Title => "$vfh_tab_roster"; public string Signature(HiringBoard board) { if (board.Zdo == null) { return "none"; } int num = board.Zdo.GetByteArray("vfh_roster", (byte[])null)?.Aggregate(17, (int h, byte b) => h * 31 + b) ?? 0; Cost cost = ((board.Inventory != null) ? BoardStorage.Totals(board.Inventory) : Cost.Zero); long num2 = (long)(ZNet.instance.GetTimeSeconds() / 5.0); string text = string.Join(",", from h in Hireling.Loaded where (Object)(object)h != (Object)null && h.BoardId == board.Id && h.IsParked select h.Hid); return $"{num}|{_selected}|{_confirmDismiss}|{_confirmRespec}|{cost}|{num2}|{board.Level}|{text}|{VfhConfig.Enhancements.Value}"; } public void Build(RectTransform root, HiringBoard board) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) Roster roster = BoardRosterOps.Read(board.Zdo); if (roster.Count == 0) { PanelUi.Text((Transform)(object)root, "$vfh_tab_roster_empty", 0f, -220f, 560f, 18, (TextAnchor)4, PanelUi.Dim); return; } if (roster.Entries.All((ContractEntry e) => e.ContractId != _selected)) { _selected = roster.Entries[0].ContractId; } float num = -150f; foreach (ContractEntry item in roster.Entries.Take(12)) { ContractEntry entry = item; string text = $"{item.Name} — $vfh_job_{item.Job.ToString().ToLowerInvariant()} {item.Level}"; int num2 = ((VfhConfig.Enhancements.Value && item.State == ContractState.Active) ? EnhancementRules.Owed(EnhancementPicks.Parse(item.Enhancements), item.Level).Count : 0); if (num2 > 0) { text = text + " (" + Localization.instance.Localize("$vfh_enh_owed", new string[1] { num2.ToString() }) + ")"; } ((Graphic)((Component)PanelUi.Button((Transform)(object)root, text, -175f, num, 320f, 28f, delegate { _selected = entry.ContractId; _confirmDismiss = ""; })).GetComponentInChildren<Text>()).color = ((item.ContractId == _selected) ? Color.yellow : StateColor(item)); num -= 31f; } Details(root, board, roster, roster.Entries.First((ContractEntry e) => e.ContractId == _selected)); } private void Details(RectTransform root, HiringBoard board, Roster roster, ContractEntry e) { //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0570: Unknown result type (might be due to invalid IL or missing references) //IL_050e: Unknown result type (might be due to invalid IL or missing references) //IL_0507: Unknown result type (might be due to invalid IL or missing references) LevelRules levelRules = new LevelRules(DataStore.Current); CostCalculator costCalculator = new CostCalculator(DataStore.Current, VfhConfig.RespawnCostFraction.Value); Hireling hireling = Hireling.Loaded.FirstOrDefault((Hireling h) => (Object)(object)h != (Object)null && e.Hid.Length > 0 && h.Hid == e.Hid); PanelUi.Text((Transform)(object)root, e.Name, 185f, -150f, 320f, 22, (TextAnchor)4, null, bold: true); PanelUi.Text((Transform)(object)root, $"$vfh_job_{e.Job.ToString().ToLowerInvariant()} — $vfh_level {e.Level}", 185f, -180f, 320f, 18, (TextAnchor)4); PanelUi.Text((Transform)(object)root, Status(e, hireling), 185f, -208f, 320f, 16, (TextAnchor)4, StateColor(e)); if ((Object)(object)hireling != (Object)null) { PanelUi.Text((Transform)(object)root, $"$vfh_health {Mathf.CeilToInt(((Character)hireling.Humanoid).GetHealth())}/{Mathf.CeilToInt(((Character)hireling.Humanoid).GetMaxHealth())}", 185f, -234f, 320f, 16, (TextAnchor)4, PanelUi.Dim); } PanelUi.Text((Transform)(object)root, Localization.instance.Localize("$vfh_contract_upkeep") + " " + ContractsTab.Price(costCalculator.DailyUpkeep(e.Job, e.Level)), 185f, -260f, 320f, 15, (TextAnchor)4, PanelUi.Dim); EnhancementPicks enhancementPicks = EnhancementPicks.Parse(e.Enhancements); if (VfhConfig.Enhancements.Value && enhancementPicks.Any) { PanelUi.Text((Transform)(object)root, Localization.instance.Localize("$vfh_enh_roster", new string[1] { string.Join(", ", from id in enhancementPicks.Ids(e.Job) select Localization.instance.Localize(EnhancementText.NameKey(e.Job, id))) }), 185f, -279f, 340f, 12, (TextAnchor)4, PanelUi.Dim); } if (e.State == ContractState.Pending) { PanelUi.Button((Transform)(object)root, e.RespawnPending ? "$vfh_roster_cancel_dead" : "$vfh_roster_cancel", 185f, -320f, 240f, 38f, delegate { BoardContracts.Cancel(board, e.ContractId); }); } else { if (e.State != ContractState.Active) { return; } IReadOnlyList<Stance> stances = StanceRules.Allowed(e.Job, EnhancementPicks.Parse(e.Enhancements).Has(e.Job, EnhancementId.Watchman)); int si = Mathf.Max(0, stances.ToList().IndexOf(e.Stance)); PanelUi.Button((Transform)(object)root, "$vfh_contract_stance $vfh_stance_" + e.Stance.ToString().ToLowerInvariant(), 185f, -300f, 280f, 34f, delegate { BoardContracts.Edit(board, e.Hid, e.Radius, stances[(si + 1) % stances.Count]); }); PanelUi.Button((Transform)(object)root, "-", 85f, -342f, 44f, 34f, delegate { BoardContracts.Edit(board, e.Hid, e.Radius - 5f, e.Stance); }); PanelUi.Text((Transform)(object)root, $"$vfh_contract_radius {e.Radius:0} m", 185f, -342f, 160f, 16, (TextAnchor)4); PanelUi.Button((Transform)(object)root, "+", 285f, -342f, 44f, 34f, delegate { BoardContracts.Edit(board, e.Hid, e.Radius + 5f, e.Stance); }); int num = levelRules.MaxHirelingLevel(board.Level); if (e.Level < num) { Cost c = costCalculator.PromotionCost(e.Job, e.Level, e.Level + 1); Cost available = ((board.Inventory != null) ? BoardStorage.Totals(board.Inventory) : Cost.Zero); ((Selectable)PanelUi.Button((Transform)(object)root, Localization.instance.Localize("$vfh_roster_promote", new string[1] { (e.Level + 1).ToString() }), 185f, -390f, 280f, 34f, delegate { BoardContracts.Promote(board, e.Hid, e.Level + 1); })).interactable = c.CoveredBy(available); PanelUi.Text((Transform)(object)root, ContractsTab.Price(c), 185f, -420f, 300f, 15, (TextAnchor)4, c.CoveredBy(available) ? PanelUi.Good : PanelUi.Bad); } if (_confirmDismiss == e.ContractId) { PanelUi.Text((Transform)(object)root, Localization.instance.Localize("$vfh_confirm_dismiss_short", new string[1] { e.Name }), 185f, -448f, 330f, 15, (TextAnchor)4, PanelUi.Bad); PanelUi.Button((Transform)(object)root, "$vfh_yes", 125f, -480f, 100f, 32f, delegate { _confirmDismiss = ""; BoardContracts.Dismiss(board.Id, e.Hid); }); PanelUi.Button((Transform)(object)root, "$vfh_no", 245f, -480f, 100f, 32f, delegate { _confirmDismiss = ""; }); return; } PanelUi.Button((Transform)(object)root, "$vfh_roster_dismiss", 100f, -465f, 150f, 34f, delegate { _confirmDismiss = e.ContractId; }); if ((Object)(object)hireling == (Object)null || hireling.Mode == HirelingMode.Working) { bool parked = (Object)(object)hireling != (Object)null && hireling.IsParked; PanelUi.Button((Transform)(object)root, parked ? "$vfh_roster_back_to_work" : "$vfh_roster_call", 270f, -465f, 160f, 34f, delegate { BoardContracts.Park(e.Hid, !parked); }); } float num2 = -505f; if (VfhConfig.Enhancements.Value && enhancementPicks.Any) { Cost c2 = EnhancementRules.RespecCost(costCalculator, e.Job, e.Level, DataStore.Current.EnhancementSettings.RespecCostFraction); Cost available2 = ((board.Inventory != null) ? BoardStorage.Totals(board.Inventory) : Cost.Zero); bool flag = _confirmRespec == e.ContractId; ((Selectable)PanelUi.Button((Transform)(object)root, Localization.instance.Localize(flag ? "$vfh_enh_respec_confirm" : "$vfh_enh_respec", new string[1] { ContractsTab.Price(c2) }), 185f, num2, 280f, 34f, delegate { if (_confirmRespec == e.ContractId) { _confirmRespec = ""; BoardContracts.Respec(board.Id, e.Hid); } else { _confirmRespec = e.ContractId; } })).interactable = c2.CoveredBy(available2); num2 -= 40f; } if (e.Post != null) { PanelUi.Button((Transform)(object)root, "$vfh_orders_clear_post", 185f, num2, 280f, 34f, delegate { BoardContracts.ClearPost(board, e.Hid); }); } } } private static string WaitText(double seconds) { if (seconds <= 3600.0) { return $"{Mathf.CeilToInt((float)seconds)}s"; } double num = (((Object)(object)EnvMan.instance != (Object)null) ? ((double)EnvMan.instance.m_dayLengthSec) : 1800.0); return Localization.instance.Localize("$vfh_status_days", new string[1] { (seconds / num).ToString("0.0", CultureInfo.InvariantCulture) }); } private static string Status(ContractEntry e, Hireling? live) { switch (e.State) { case ContractState.Pending: { double num2 = e.ArriveAt - ZNet.instance.GetTimeSeconds(); string text3 = (e.RespawnPending ? "$vfh_status_returning" : "$vfh_status_arriving"); if (num2 > 0.0) { return Localization.instance.Localize(text3) + " (" + WaitText(num2) + ")"; } return Localization.instance.Localize((e.RespawnPending && DeathRules.Pays(VfhConfig.DeathMode.Value)) ? "$vfh_status_awaiting_payment" : text3); } case ContractState.Leaving: return "$vfh_status_leaving"; default: { if ((Object)(object)live != (Object)null && live.Mode == HirelingMode.Working && live.IsParked) { return "$vfh_roster_parked"; } if (e.Post != null) { object obj; if (live == null) { obj = null; } else { Z