using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using ATS_API;
using BepInEx;
using BepInEx.Configuration;
using Eremite;
using Eremite.Buildings;
using Eremite.Buildings.UI;
using Eremite.Buildings.UI.Trade;
using Eremite.Characters;
using Eremite.Characters.Villagers;
using Eremite.Controller;
using Eremite.Controller.Generator;
using Eremite.MapObjects;
using Eremite.Model;
using Eremite.Model.State;
using Eremite.Services;
using Eremite.Services.Monitors;
using Eremite.View;
using Eremite.View.Cameras;
using Eremite.View.HUD;
using Eremite.View.HUD.Construction;
using Eremite.View.HUD.Woodcutters;
using Eremite.View.Popups.GameMenu;
using Eremite.View.Popups.Recipes;
using Eremite.View.Utils;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Stormwalker;
using TMPro;
using UniRx;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Stormwalker")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("An Against the Storm Tweakpack")]
[assembly: AssemblyFileVersion("0.8.0.0")]
[assembly: AssemblyInformationalVersion("0.8.0+2e49d70c427d417ebc7fe92b9c3459d6a53dda2a")]
[assembly: AssemblyProduct("Stormwalker")]
[assembly: AssemblyTitle("Stormwalker")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.8.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 ATS_API
{
[HarmonyPatch]
public static class Hotkeys
{
public class Hotkey
{
public string keyName;
public string displayName;
public List<string> codes;
public Action<CallbackContext> onCallback;
}
[Serializable]
private class SavedInputMap
{
public string modName;
public string actionMap;
public string bindings;
}
public static InputActionAsset MasterInputAsset;
private static Dictionary<string, List<Hotkey>> pendingHotkeys = new Dictionary<string, List<Hotkey>>();
private static Dictionary<string, InputActionMap> modNameToActionMaps = new Dictionary<string, InputActionMap>();
private static Dictionary<string, Hotkey> modNameActionNameToAddedHotkey = new Dictionary<string, Hotkey>();
private static HashSet<InputAction> activeActions = new HashSet<InputAction>();
private static HashSet<string> activeActionMaps = new HashSet<string>();
private static readonly Dictionary<KeyCode, string> KeyCodeToPathMap = new Dictionary<KeyCode, string>
{
{
(KeyCode)32,
"<Keyboard>/space"
},
{
(KeyCode)306,
"<Keyboard>/leftCtrl"
},
{
(KeyCode)305,
"<Keyboard>/rightCtrl"
},
{
(KeyCode)304,
"<Keyboard>/leftShift"
},
{
(KeyCode)303,
"<Keyboard>/rightShift"
},
{
(KeyCode)97,
"<Keyboard>/a"
},
{
(KeyCode)98,
"<Keyboard>/b"
},
{
(KeyCode)99,
"<Keyboard>/c"
},
{
(KeyCode)100,
"<Keyboard>/d"
},
{
(KeyCode)101,
"<Keyboard>/e"
},
{
(KeyCode)102,
"<Keyboard>/f"
},
{
(KeyCode)103,
"<Keyboard>/g"
},
{
(KeyCode)104,
"<Keyboard>/h"
},
{
(KeyCode)105,
"<Keyboard>/i"
},
{
(KeyCode)106,
"<Keyboard>/j"
},
{
(KeyCode)107,
"<Keyboard>/k"
},
{
(KeyCode)108,
"<Keyboard>/l"
},
{
(KeyCode)109,
"<Keyboard>/m"
},
{
(KeyCode)110,
"<Keyboard>/n"
},
{
(KeyCode)111,
"<Keyboard>/o"
},
{
(KeyCode)112,
"<Keyboard>/p"
},
{
(KeyCode)113,
"<Keyboard>/q"
},
{
(KeyCode)114,
"<Keyboard>/r"
},
{
(KeyCode)115,
"<Keyboard>/s"
},
{
(KeyCode)116,
"<Keyboard>/t"
},
{
(KeyCode)117,
"<Keyboard>/u"
},
{
(KeyCode)118,
"<Keyboard>/v"
},
{
(KeyCode)119,
"<Keyboard>/w"
},
{
(KeyCode)120,
"<Keyboard>/x"
},
{
(KeyCode)121,
"<Keyboard>/y"
},
{
(KeyCode)122,
"<Keyboard>/z"
},
{
(KeyCode)27,
"<Keyboard>/escape"
},
{
(KeyCode)13,
"<Keyboard>/enter"
},
{
(KeyCode)8,
"<Keyboard>/backspace"
},
{
(KeyCode)9,
"<Keyboard>/tab"
},
{
(KeyCode)127,
"<Keyboard>/delete"
},
{
(KeyCode)273,
"<Keyboard>/upArrow"
},
{
(KeyCode)274,
"<Keyboard>/downArrow"
},
{
(KeyCode)276,
"<Keyboard>/leftArrow"
},
{
(KeyCode)275,
"<Keyboard>/rightArrow"
},
{
(KeyCode)308,
"<Keyboard>/leftAlt"
},
{
(KeyCode)307,
"<Keyboard>/rightAlt"
},
{
(KeyCode)277,
"<Keyboard>/insert"
},
{
(KeyCode)278,
"<Keyboard>/home"
},
{
(KeyCode)279,
"<Keyboard>/end"
},
{
(KeyCode)280,
"<Keyboard>/pageUp"
},
{
(KeyCode)281,
"<Keyboard>/pageDown"
},
{
(KeyCode)300,
"<Keyboard>/numLock"
},
{
(KeyCode)301,
"<Keyboard>/capsLock"
},
{
(KeyCode)302,
"<Keyboard>/scrollLock"
},
{
(KeyCode)282,
"<Keyboard>/f1"
},
{
(KeyCode)283,
"<Keyboard>/f2"
},
{
(KeyCode)284,
"<Keyboard>/f3"
},
{
(KeyCode)285,
"<Keyboard>/f4"
},
{
(KeyCode)286,
"<Keyboard>/f5"
},
{
(KeyCode)287,
"<Keyboard>/f6"
},
{
(KeyCode)288,
"<Keyboard>/f7"
},
{
(KeyCode)289,
"<Keyboard>/f8"
},
{
(KeyCode)290,
"<Keyboard>/f9"
},
{
(KeyCode)291,
"<Keyboard>/f10"
},
{
(KeyCode)292,
"<Keyboard>/f11"
},
{
(KeyCode)293,
"<Keyboard>/f12"
},
{
(KeyCode)19,
"<Keyboard>/pause"
},
{
(KeyCode)316,
"<Keyboard>/printScreen"
},
{
(KeyCode)256,
"<Keyboard>/numpad0"
},
{
(KeyCode)257,
"<Keyboard>/numpad1"
},
{
(KeyCode)258,
"<Keyboard>/numpad2"
},
{
(KeyCode)259,
"<Keyboard>/numpad3"
},
{
(KeyCode)260,
"<Keyboard>/numpad4"
},
{
(KeyCode)261,
"<Keyboard>/numpad5"
},
{
(KeyCode)262,
"<Keyboard>/numpad6"
},
{
(KeyCode)263,
"<Keyboard>/numpad7"
},
{
(KeyCode)264,
"<Keyboard>/numpad8"
},
{
(KeyCode)265,
"<Keyboard>/numpad9"
},
{
(KeyCode)271,
"<Keyboard>/numpadEnter"
},
{
(KeyCode)270,
"<Keyboard>/numpadPlus"
},
{
(KeyCode)269,
"<Keyboard>/numpadMinus"
},
{
(KeyCode)268,
"<Keyboard>/numpadMultiply"
},
{
(KeyCode)267,
"<Keyboard>/numpadDivide"
},
{
(KeyCode)266,
"<Keyboard>/numpadPeriod"
},
{
(KeyCode)272,
"<Keyboard>/numpadEquals"
},
{
(KeyCode)126,
"<Keyboard>/backquote"
},
{
(KeyCode)45,
"<Keyboard>/minus"
},
{
(KeyCode)61,
"<Keyboard>/equals"
},
{
(KeyCode)91,
"<Keyboard>/leftBracket"
},
{
(KeyCode)93,
"<Keyboard>/rightBracket"
},
{
(KeyCode)59,
"<Keyboard>/semicolon"
},
{
(KeyCode)39,
"<Keyboard>/quote"
},
{
(KeyCode)44,
"<Keyboard>/comma"
},
{
(KeyCode)46,
"<Keyboard>/period"
},
{
(KeyCode)47,
"<Keyboard>/slash"
},
{
(KeyCode)92,
"<Keyboard>/backslash"
},
{
(KeyCode)49,
"<Keyboard>/1"
},
{
(KeyCode)50,
"<Keyboard>/2"
},
{
(KeyCode)51,
"<Keyboard>/3"
},
{
(KeyCode)52,
"<Keyboard>/4"
},
{
(KeyCode)53,
"<Keyboard>/5"
},
{
(KeyCode)54,
"<Keyboard>/6"
},
{
(KeyCode)55,
"<Keyboard>/7"
},
{
(KeyCode)56,
"<Keyboard>/8"
},
{
(KeyCode)57,
"<Keyboard>/9"
},
{
(KeyCode)48,
"<Keyboard>/0"
}
};
private static string CustomBindingsPath => Path.Combine(Application.persistentDataPath, "API");
public static void Update()
{
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Expected O, but got Unknown
if ((Object)(object)MasterInputAsset == (Object)null || pendingHotkeys.Count == 0)
{
return;
}
MasterInputAsset.Disable();
foreach (KeyValuePair<string, List<Hotkey>> pendingHotkey in pendingHotkeys)
{
activeActionMaps.Add(pendingHotkey.Key);
InputActionMap val = MasterInputAsset.FindActionMap(pendingHotkey.Key, false);
if (val == null)
{
val = new InputActionMap(pendingHotkey.Key);
InputActionSetupExtensions.AddActionMap(MasterInputAsset, val);
}
modNameToActionMaps[pendingHotkey.Key] = val;
LogInfo($"Adding action map {pendingHotkey.Key} with {pendingHotkey.Value.Count} hotkeys.");
foreach (Hotkey item in pendingHotkey.Value)
{
AddHotkey(pendingHotkey.Key, val, item);
}
}
pendingHotkeys.Clear();
MasterInputAsset.Enable();
}
public static void RegisterKey(string modName, Hotkey hotkey)
{
LogInfo("Registering key " + hotkey.keyName + " with code " + string.Join(",", hotkey.codes));
if (!pendingHotkeys.TryGetValue(modName, out var value))
{
value = new List<Hotkey>();
pendingHotkeys.Add(modName, value);
}
value.Add(hotkey);
}
public static void RegisterKey(string modName, string keyName, string displayName, List<KeyCode> codes, Action onPress = null, Action onRelease = null)
{
Action<CallbackContext> onCallback = null;
if (onPress != null || onRelease != null)
{
onCallback = delegate(CallbackContext ctx)
{
if (((CallbackContext)(ref ctx)).performed)
{
onPress?.Invoke();
}
else if (((CallbackContext)(ref ctx)).canceled)
{
onRelease?.Invoke();
}
};
}
Hotkey hotkey = new Hotkey();
hotkey.keyName = keyName;
hotkey.displayName = displayName;
hotkey.codes = KeyCodesToString(codes);
hotkey.onCallback = onCallback;
RegisterKey(modName, hotkey);
}
public static void RegisterKey(string modName, string keyName, string displayName, List<KeyCode> codes, Action<CallbackContext> callback = null)
{
Hotkey hotkey = new Hotkey();
hotkey.keyName = keyName;
hotkey.displayName = displayName;
hotkey.codes = KeyCodesToString(codes);
hotkey.onCallback = callback;
RegisterKey(modName, hotkey);
}
private static void AddHotkey(string modName, InputActionMap actionMap, Hotkey hotkey)
{
//IL_006c: 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_017a: Unknown result type (might be due to invalid IL or missing references)
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
LogInfo("Adding hotkey " + hotkey.keyName + " with code " + string.Join(",", hotkey.codes));
List<string> codes = hotkey.codes;
string keyName = hotkey.keyName;
Action<CallbackContext> onCallback = hotkey.onCallback;
string key = modName + "_" + keyName;
modNameActionNameToAddedHotkey[key] = hotkey;
InputAction val = ((IEnumerable<InputAction>)(object)actionMap.actions).FirstOrDefault((Func<InputAction, bool>)((InputAction a) => a.name == keyName));
if (val == null)
{
CompositeSyntax val2;
if (codes.Count == 1)
{
val = InputActionSetupExtensions.AddAction(actionMap, keyName, (InputActionType)0, codes[0] ?? "", (string)null, (string)null, (string)null, (string)null);
}
else if (codes.Count == 2)
{
val = InputActionSetupExtensions.AddAction(actionMap, keyName, (InputActionType)0, (string)null, (string)null, (string)null, (string)null, (string)null);
val2 = InputActionSetupExtensions.AddCompositeBinding(val, "OneModifier", (string)null, (string)null);
val2 = ((CompositeSyntax)(ref val2)).With("Modifier", codes[0] ?? "", (string)null, (string)null);
((CompositeSyntax)(ref val2)).With("Binding", codes[1] ?? "", (string)null, (string)null);
}
else
{
if (codes.Count != 3)
{
LogError("More than 3 key codes are not supported.");
return;
}
val = InputActionSetupExtensions.AddAction(actionMap, keyName, (InputActionType)0, (string)null, (string)null, (string)null, (string)null, (string)null);
val2 = InputActionSetupExtensions.AddCompositeBinding(val, "TwoModifiers", (string)null, (string)null);
val2 = ((CompositeSyntax)(ref val2)).With("Modifier1", codes[0] ?? "", (string)null, (string)null);
val2 = ((CompositeSyntax)(ref val2)).With("Modifier2", codes[1] ?? "", (string)null, (string)null);
((CompositeSyntax)(ref val2)).With("Binding", codes[2] ?? "", (string)null, (string)null);
}
}
if (onCallback != null)
{
CallbackAction(val, keyName, onCallback);
}
activeActions.Add(val);
}
private static void CallbackAction(InputAction action, string keyName, Action<CallbackContext> callback)
{
action.performed += delegate(CallbackContext ctx)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
LogInfo(keyName + " action performed!");
callback(ctx);
};
action.canceled += delegate(CallbackContext ctx)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
LogInfo(keyName + " action canceled!");
callback(ctx);
};
action.started += delegate(CallbackContext ctx)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
LogInfo(keyName + " action started!");
callback(ctx);
};
}
private static List<string> KeyCodesToString(List<KeyCode> codes)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
List<string> list = new List<string>();
foreach (KeyCode code in codes)
{
KeyCode current = code;
if (KeyCodeToPathMap.TryGetValue(current, out var value))
{
list.Add(value);
}
else
{
list.Add(((object)(KeyCode)(ref current)).ToString());
}
}
return list;
}
public static bool IsActionActive(InputAction action)
{
return activeActions.Contains(action);
}
private static void LogError(string message)
{
Plugin.Error(message);
}
private static void LogInfo(string message)
{
Plugin.Log(message);
}
private static void LogWarning(string message)
{
Plugin.Warning(message);
}
[HarmonyPatch(typeof(KeyBindingsPanel), "OnEnable")]
[HarmonyPrefix]
public static void KeyBindingsPanel_Start_Postfix(KeyBindingsPanel __instance)
{
//IL_006d: 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)
//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)
ModdedKeyboardSlots[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<ModdedKeyboardSlots>(true);
foreach (KeyValuePair<string, InputActionMap> pair in modNameToActionMaps)
{
if (!activeActionMaps.Contains(pair.Key))
{
continue;
}
InputActionMap val = MasterInputAsset.FindActionMap(pair.Key, false);
if (val == null || val.actions.Count == 0)
{
LogInfo("Action map is null for modName " + pair.Key + ", skipping.");
continue;
}
ModdedKeyboardSlots moddedKeyboardSlots = componentsInChildren.FirstOrDefault((ModdedKeyboardSlots a) => a.ModName == pair.Key);
if ((Object)(object)moddedKeyboardSlots == (Object)null)
{
LogInfo("Slots are null for " + val.name + ", creating new slots.");
Transform parent = ((Component)__instance.slots[0]).transform.parent;
Transform val2 = Object.Instantiate<Transform>(parent, parent.parent);
((Object)((Component)val2).gameObject).name = "Modded";
moddedKeyboardSlots = ((Component)val2).gameObject.AddComponent<ModdedKeyboardSlots>();
moddedKeyboardSlots.Initialize(pair.Key, val2);
Transform val3 = val2.Find("Header");
TMP_Text component = ((Component)val3).GetComponent<TMP_Text>();
Object.Destroy((Object)(object)((Component)val3).GetComponent<LocalizationText>());
Object.Destroy((Object)(object)((Component)val3).GetComponent<TextFontFeaturesHelper>());
component.text = pair.Key;
LogInfo($"Slots created for {pair.Key} with {val.actions.Count} actions.");
}
else
{
LogInfo("Slots are already set up.");
}
}
}
[HarmonyPatch(typeof(KeyBindingsPanel), "SetUpSlots")]
[HarmonyPostfix]
public static void KeyBindingsPanel_SetUpSlots_Postfix(KeyBindingsPanel __instance)
{
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
LogInfo("Setting up slots.");
ModdedKeyboardSlots[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<ModdedKeyboardSlots>(true);
foreach (KeyValuePair<string, InputActionMap> pair in modNameToActionMaps)
{
InputActionMap val = MasterInputAsset.FindActionMap(pair.Key, false);
if (val == null)
{
LogInfo("Action map is null for mod " + pair.Key + ", skipping.");
continue;
}
ModdedKeyboardSlots moddedKeyboardSlots = componentsInChildren.FirstOrDefault((ModdedKeyboardSlots a) => a.ModName == pair.Key);
if ((Object)(object)moddedKeyboardSlots == (Object)null)
{
LogInfo("Modded keyboard is null for " + pair.Key + ", returning.");
continue;
}
LogInfo($"Setting up keyboard slots for {pair.Key} with {val.actions.Count} actions.");
moddedKeyboardSlots.SetupKeyboardSlots(val, __instance);
}
}
[HarmonyPatch(typeof(KeyBindingsPanel), "ResetCounter")]
[HarmonyPostfix]
private static void KeyBindingsPanel_ResetCounter(KeyBindingsPanel __instance)
{
LogInfo("Reset counter.");
ModdedKeyboardSlots[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<ModdedKeyboardSlots>(true);
if (componentsInChildren != null)
{
ModdedKeyboardSlots[] array = componentsInChildren;
foreach (ModdedKeyboardSlots moddedKeyboardSlots in array)
{
moddedKeyboardSlots.ResetCounter();
}
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
[HarmonyPostfix]
private static void HookMainControllerSetup(InputConfig __instance)
{
LogInfo("Setting up custom action map.");
MasterInputAsset = __instance.asset;
}
[HarmonyPatch(typeof(KeyBindingsPanel), "EnableInput")]
[HarmonyPostfix]
private static void KeyBindingsPanel_EnableInput()
{
foreach (InputActionMap value in modNameToActionMaps.Values)
{
value.Enable();
}
}
[HarmonyPatch(typeof(KeyBindingsPanel), "DisableInput")]
[HarmonyPostfix]
private static void KeyBindingsPanel_DisableInput()
{
foreach (InputActionMap value in modNameToActionMaps.Values)
{
value.Disable();
}
}
[HarmonyPatch(typeof(InputService), "GetShortcutLabel")]
[HarmonyPrefix]
private static bool InputService_GetShortcutLabel(InputAction action, ref string __result)
{
string key = action.actionMap.name + "_" + action.name;
if (modNameActionNameToAddedHotkey.TryGetValue(key, out var value))
{
__result = value.displayName;
return false;
}
return true;
}
[HarmonyPatch(typeof(ClientPrefsService), "Reset")]
[HarmonyPrefix]
private static void ClientPrefsService_Reset()
{
foreach (InputActionMap value in modNameToActionMaps.Values)
{
LogInfo("Resetting input config for " + value.name);
InputActionRebindingExtensions.RemoveAllBindingOverrides((IInputActionCollection2)(object)value);
}
}
[HarmonyPatch(typeof(ClientPrefsService), "SaveInputConfig")]
[HarmonyPostfix]
private static void ClientPrefsService_SaveInputConfig()
{
if (!Directory.Exists(CustomBindingsPath))
{
Directory.CreateDirectory(CustomBindingsPath);
}
foreach (KeyValuePair<string, InputActionMap> modNameToActionMap in modNameToActionMaps)
{
string text = InputActionRebindingExtensions.SaveBindingOverridesAsJson((IInputActionCollection2)(object)modNameToActionMap.Value);
LogInfo("Saving input config for " + modNameToActionMap.Key + " with value " + text);
SavedInputMap savedInputMap = new SavedInputMap
{
modName = modNameToActionMap.Key,
actionMap = modNameToActionMap.Value.ToJson(),
bindings = text
};
string text2 = Path.Combine(CustomBindingsPath, modNameToActionMap.Key + ".custombindings");
LogInfo("Saving keybinds for " + modNameToActionMap.Key + " to " + text2);
JsonIO.SaveToFile((object)savedInputMap, text2, 3);
}
}
[HarmonyPatch(typeof(ClientPrefsService), "LoadInputConfig")]
[HarmonyPostfix]
private static void ClientPrefsService_LoadInputConfig()
{
//IL_01be: 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_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_021f: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_0228: Unknown result type (might be due to invalid IL or missing references)
//IL_022d: Unknown result type (might be due to invalid IL or missing references)
//IL_0233: Unknown result type (might be due to invalid IL or missing references)
//IL_0238: Unknown result type (might be due to invalid IL or missing references)
if (Serviceable.CommandLineArgsService.HasKey("-resetkeybinds"))
{
LogError("Clearing keybinds!");
return;
}
if (!Directory.Exists(CustomBindingsPath))
{
LogInfo("No custombindings folder found.");
return;
}
string[] files = Directory.GetFiles(CustomBindingsPath, "*.custombindings");
if (files.Length == 0)
{
LogInfo("No saved custombindings files found.");
return;
}
MasterInputAsset.Disable();
string[] array = files;
foreach (string text in array)
{
if (!File.Exists(text))
{
LogError("No saved inputs found.");
continue;
}
SavedInputMap fromFile = JsonIO.GetFromFile<SavedInputMap>(text, 3);
if (fromFile == null)
{
LogError("Couldn't load custom input json at path " + text);
continue;
}
LogInfo("Loading keybinds for " + fromFile.modName + " with value " + fromFile.bindings);
string actionMap = fromFile.actionMap;
InputActionMap[] array2 = InputActionMap.FromJson(actionMap);
if (array2.Length == 0)
{
LogError("Failed to load " + fromFile.modName + " action map from json: " + actionMap);
continue;
}
if (array2.Length > 1)
{
LogWarning($"Loaded {array2.Length} action maps for {fromFile.modName}, using the first one.");
}
InputActionMap val = array2[0];
if (MasterInputAsset.FindActionMap(val.name, false) == null)
{
LogInfo("Added action map " + val.name);
InputActionSetupExtensions.AddActionMap(MasterInputAsset, val);
Enumerator<InputAction> enumerator = val.actions.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
InputAction current = enumerator.Current;
LogInfo("\tAdded action " + current.name);
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
InputActionRebindingExtensions.LoadBindingOverridesFromJson((IInputActionCollection2)(object)val, fromFile.bindings, true);
Enumerator<InputBinding> enumerator2 = val.bindings.GetEnumerator();
try
{
while (enumerator2.MoveNext())
{
InputBinding current2 = enumerator2.Current;
LogInfo("\tAdded binding " + ((InputBinding)(ref current2)).path);
}
}
finally
{
((IDisposable)enumerator2).Dispose();
}
}
else
{
LogWarning("Action map " + val.name + " already exists. Likely another mod already loaded this so your hotkeys may differ!");
}
modNameToActionMaps[fromFile.modName] = val;
}
MasterInputAsset.Enable();
}
}
[HarmonyPatch]
public class ModdedKeyboardSlots : MonoBehaviour
{
public string ModName = "Hotkey";
public List<KeyBindingSlot> slots = new List<KeyBindingSlot>();
public int usedSlots = 0;
public void Initialize(string hotkeyName, Transform clone)
{
ModName = hotkeyName;
slots.AddRange(((Component)clone).GetComponentsInChildren<KeyBindingSlot>(true));
}
public void ResetCounter()
{
usedSlots = 0;
}
public void SetupKeyboardSlots(InputActionMap actionMap, KeyBindingsPanel panel)
{
//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_0026: 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)
Plugin.Log("Setting up keyboard slots for " + ModName + ".");
Enumerator<InputAction> enumerator = actionMap.actions.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
InputAction current = enumerator.Current;
if (!Hotkeys.IsActionActive(current))
{
Plugin.Log("Skipping action " + current.name + " because it's not active.");
continue;
}
Plugin.Log("Setting up action " + current.name + " for " + ModName + ".");
KeyBindingSlot orCreate = ((BaseMB)panel).GetOrCreate<KeyBindingSlot>(slots, usedSlots++);
orCreate.SetUp(current, (Action<InputAction>)panel.OnChangeRequested);
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
}
}
}
namespace Stormwalker
{
[BepInPlugin("Stormwalker", "Stormwalker", "0.8.0")]
public class Plugin : BaseUnityPlugin
{
public static readonly float SUPER_SPEED_SCALE = 5f;
public static Plugin Instance;
public static BuildingsPanel buildingPanel = null;
private Harmony harmony;
private Vector2? zoomLimit = null;
public static PluginState State { get; private set; } = new PluginState();
public static void Log(object obj)
{
((BaseUnityPlugin)Instance).Logger.LogInfo(obj);
}
public static void Warning(object obj)
{
((BaseUnityPlugin)Instance).Logger.LogWarning(obj);
}
public static void Error(object obj)
{
((BaseUnityPlugin)Instance).Logger.LogError(obj);
}
private void Awake()
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading Plugin Stormwalker...");
Instance = this;
harmony = Harmony.CreateAndPatchAll(typeof(Patches).Assembly, "Stormwalker");
Configs.Initialize();
Hotkeys.RegisterKey("Stormwalker", "zoom", "Zoom Overview", new List<KeyCode>(1) { (KeyCode)8 }, ZoomToggled);
Hotkeys.RegisterKey("Stormwalker", "5X", "5X Speed", new List<KeyCode>(1) { (KeyCode)53 }, SuperSpeedToggled);
((Component)this).gameObject.AddComponent<Woodcutters>();
((Component)this).gameObject.AddComponent<BuildingCopier>();
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Stormwalker is loaded!");
}
private void Update()
{
Hotkeys.Update();
}
public static void SetupState(bool noGameState)
{
if (noGameState || MB.GameSaveService.IsNewGame())
{
State = new PluginState();
}
else
{
State = Load();
}
ObservableExtensions.Subscribe<bool>(Observable.Where<bool>((IObservable<bool>)MB.GameSaveService.IsSaving, (Func<bool, bool>)((bool isStarting) => !isStarting)), (Action<bool>)delegate
{
Save();
});
}
private static void Save()
{
string text = Path.Combine(Application.persistentDataPath, "Stormwalker.save");
Log("Saving state to " + text);
JsonIO.SaveToFile((object)State, text, 3);
}
private static PluginState Load()
{
string text = Path.Combine(Application.persistentDataPath, "Stormwalker.save");
if (!File.Exists(text))
{
Log("No save state found, creating new one!");
return new PluginState();
}
try
{
PluginState fromFile = JsonIO.GetFromFile<PluginState>(text, 3);
Log("Loaded state from " + text);
return fromFile;
}
catch
{
Error("Error while trying to load save state from " + text);
return new PluginState();
}
}
private static void SuperSpeedToggled(CallbackContext context)
{
if (((CallbackContext)(ref context)).performed)
{
GameMB.TimeScaleService.Change(SUPER_SPEED_SCALE, true, false);
}
}
private void ZoomToggled(CallbackContext context)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
if (((CallbackContext)(ref context)).performed)
{
if (!zoomLimit.HasValue)
{
zoomLimit = GameController.Instance.CameraController.zoomLimit;
}
int num = Configs.ZoomLimit;
CameraController cameraController = GameController.Instance.CameraController;
if (cameraController.zoomLimit.x == (float)num && cameraController.zoomLimit.y == (float)num)
{
cameraController.zoomLimit = zoomLimit.Value;
return;
}
zoomLimit = cameraController.zoomLimit;
cameraController.zoomLimit = new Vector2((float)num, (float)num);
}
}
private void OnDestroy()
{
harmony.UnpatchSelf();
}
}
public class BuildingCopier : GameMB
{
private void Update()
{
//IL_0026: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
if (!GameController.IsGameActive || ShouldIgnoreInput())
{
return;
}
IInputService inputService = MB.InputService;
DefaultActions inputConfig = MB.InputConfig;
if (!inputService.WasTriggered(((DefaultActions)(ref inputConfig)).CopyBuilding, false))
{
return;
}
IMapObject value = GameMB.GameInputService.MouseoverObject.Value;
Plugin.Log(((object)value).ToString() + " [" + ((object)value).GetType().Name + "]");
IMapObject val = value;
IMapObject val2 = val;
ResourceDeposit val3 = (ResourceDeposit)(object)((val2 is ResourceDeposit) ? val2 : null);
if (val3 == null)
{
NaturalResource val4 = (NaturalResource)(object)((val2 is NaturalResource) ? val2 : null);
if (val4 == null)
{
Spring val5 = (Spring)(object)((val2 is Spring) ? val2 : null);
if (val5 == null)
{
Field val6 = (Field)(object)((val2 is Field) ? val2 : null);
if (val6 == null)
{
Lake val7 = (Lake)(object)((val2 is Lake) ? val2 : null);
if (val7 == null)
{
Ore val8 = (Ore)(object)((val2 is Ore) ? val2 : null);
if (val8 != null)
{
BuildConditional(MB.Settings.GetBuilding("Mine"));
}
}
else if (val7.State.isAvailable)
{
BuildConditional(MB.Settings.GetBuilding("Fishing Hut"));
}
}
else
{
if (!GameMB.OreService.HasAvailableOre(val6.Pos))
{
return;
}
Ore ore = GameMB.OreService.GetOre(val6.Pos);
foreach (MineModel item in GameMB.OreService.MinesMatrix[ore.Model.refGood.Name])
{
if (BuildConditional((BuildingModel)(object)item))
{
break;
}
}
}
}
else if (val5.State.isAvailable)
{
BuildConditional((BuildingModel)(object)MB.Settings.rainpunkConfig.extractor);
}
}
else if (val4.State.isAvailable)
{
BuildConditional(MB.Settings.GetBuilding("Woodcutters Camp"));
}
}
else
{
if (!val3.State.isAvailable || !GameMB.DepositsService.HutsMatrix.ContainsKey(val3.Model))
{
return;
}
foreach (GathererHutModel item2 in GameMB.DepositsService.HutsMatrix[val3.Model])
{
if (BuildConditional((BuildingModel)(object)item2))
{
break;
}
}
}
}
private bool ShouldIgnoreInput()
{
return (Object)(object)BuildingPanel.currentBuilding != (Object)null || !GameMB.ModeService.Idle.Value || MB.InputService.IsOverUI();
}
private bool BuildConditional(BuildingModel building)
{
if (GameMB.GameContentService.IsUnlocked(building) && GameMB.ConstructionService.CanConstruct(building))
{
GameMB.GameBlackboardService.BuildingConstructionRequested.OnNext(building);
return true;
}
return false;
}
}
public static class Configs
{
private static ConfigEntry<int> m_zoomLimit = Bind("Zoom", "Zoom Height", -60, "The zoom heights the hotkey will move the camera to.", -100, -8);
public static int ZoomLimit => m_zoomLimit.Value;
public static void Initialize()
{
}
private static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
return ((BaseUnityPlugin)Plugin.Instance).Config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
}
private static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description, T min, T max) where T : IComparable
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
return ((BaseUnityPlugin)Plugin.Instance).Config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<T>(min, max), Array.Empty<object>()));
}
}
public static class HousePatches
{
private static GameObject residentSlider;
public static HouseLimiter houseLimiter;
public static void PatchPanel(HousePanel panel)
{
GameObject val = ((BaseMB)panel).FindChild("Content/ResidentsPanel");
residentSlider = CreateResidentSlider(val);
houseLimiter = residentSlider.AddComponent<HouseLimiter>();
houseLimiter.SetUp();
val.GetComponent<SimpleVerticalResizer>().minHeight = 200f;
}
private static GameObject CreateResidentSlider(GameObject parent)
{
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
GameObject val = Utils.MakeGameObject(parent, "StormwalkerSlots");
GameObject original = GameObject.Find("/HUD/WorkshopPanel/Content/RecipesPanel/Slots/RecipeSlot/Prio");
Copy(original, val, "Plus");
Copy(original, val, "Minus");
Transform val2 = Copy(original, val, "Counter");
SimpleTooltipTrigger component = ((Component)val2).GetComponent<SimpleTooltipTrigger>();
component.headerKey = Utils.Text("Allowed Residents", "Stormwalker_residents_tooltip_head").key;
component.descKey = Utils.Text("Use the buttons to limit the amount of villagers that may live in this house", "Stormwalker_residents_tooltip_desc").key;
val.transform.localPosition = new Vector3(-200f, -125f, 0f);
return val;
}
public static void Show(House house)
{
houseLimiter.Show(house);
}
private static Transform Copy(GameObject original, GameObject target, string name)
{
Transform val = Object.Instantiate<Transform>(original.transform.Find(name), target.transform);
((Object)val).name = name;
return val;
}
}
public class HouseLimiter : GameMB
{
public HouseLimitState state = new HouseLimitState();
private Button plusButton;
private Button minusButton;
private TextMeshProUGUI counter;
private House house;
private int Count => state.GetAllowedResidents(house);
public void SetUp()
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Expected O, but got Unknown
((BaseMB)this).EnsureComponent<TextMeshProUGUI>(counter, ref counter, "Counter/Text", 0);
((BaseMB)this).EnsureComponent<Button>(plusButton, ref plusButton, "Plus", 0);
((BaseMB)this).EnsureComponent<Button>(minusButton, ref minusButton, "Minus", 0);
ButtonExtensions.AddCallback(plusButton, new UnityAction(OnPlusClicked));
ButtonExtensions.AddCallback(minusButton, new UnityAction(OnMinusClicked));
}
private void PrepareForEvents()
{
DisposableExtensions.AddTo<IDisposable>(ObservableExtensions.Subscribe<House>((IObservable<House>)GameMB.GameBlackboardService.HouseRemoved, (Action<House>)delegate(House h)
{
state.Remove(h);
}), (Component)(object)this);
}
public void Show(House house)
{
this.house = house;
RefreshCounter();
RefreshButtons();
}
private void OnPlusClicked()
{
AdjustResidents(1);
}
private void OnMinusClicked()
{
int num = AdjustResidents(-1);
if (num < house.state.residents.Count)
{
house.Leave(house.state.residents.First());
}
}
private int AdjustResidents(int delta)
{
int num = Count + delta;
state.SetAllowedResidents(house, num);
RefreshCounter();
RefreshButtons();
return num;
}
private void RefreshCounter()
{
((TMP_Text)counter).text = Count.ToString();
}
private void RefreshButtons()
{
if (((BuildingState)house.state).finished)
{
int count = Count;
((Selectable)plusButton).interactable = count < house.GetHousingPlaces();
((Selectable)minusButton).interactable = count > 0;
}
else
{
((Selectable)minusButton).interactable = false;
((Selectable)plusButton).interactable = false;
}
}
}
public class HouseLimitState
{
private Dictionary<int, int> slotsPerHouse => Plugin.State.slotsPerHouse;
public void SetAllowedResidents(House house, int amount)
{
if (amount == house.GetHousingPlaces())
{
slotsPerHouse.Remove(((Building)house).Id);
}
else
{
slotsPerHouse[((Building)house).Id] = amount;
}
}
public int GetAllowedResidents(House house)
{
if (!slotsPerHouse.TryGetValue(((Building)house).Id, out var value))
{
value = 10;
}
return Math.Min(house.GetHousingPlaces(), value);
}
public void Remove(House house)
{
slotsPerHouse.Remove(((Building)house).Id);
}
}
[HarmonyPatch]
internal static class Patches
{
[HarmonyPatch(typeof(GameLoader), "LoadState")]
[HarmonyPostfix]
private static void Load(GameLoader __instance)
{
Plugin.SetupState(__instance.state == null);
}
[HarmonyPatch(typeof(WoodcuttersHUD), "SetUp")]
[HarmonyPostfix]
private static void SetUpHousePanel(WoodcuttersHUD __instance)
{
Woodcutters component = ((Component)Plugin.Instance).gameObject.GetComponent<Woodcutters>();
component.PatchPanel(__instance);
}
[HarmonyPatch(typeof(HousePanel), "Awake")]
[HarmonyPostfix]
private static void SetUpHousePanel(HousePanel __instance)
{
HousePatches.PatchPanel(__instance);
}
[HarmonyPatch(typeof(HousePanel), "Show")]
[HarmonyPostfix]
private static void House__Show(House house)
{
HousePatches.Show(house);
}
[HarmonyPatch(typeof(House), "GetPlacesLeft")]
[HarmonyPrefix]
private static bool House__GetPlacesLeft(House __instance, ref int __result)
{
__result = HousePatches.houseLimiter.state.GetAllowedResidents(__instance) - __instance.state.residents.Count;
return false;
}
[HarmonyPatch(typeof(BuildingWorkerSlot), "Unassign")]
[HarmonyPrefix]
private static bool BuildingWorkerSlot__Unassign(BuildingWorkerSlot __instance)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
IInputService inputService = MB.InputService;
DefaultActions inputConfig = MB.InputConfig;
if (inputService.IsTriggering(((DefaultActions)(ref inputConfig)).InputModifierControl))
{
WorkerSlotPatches.QueueToggleUnassign(__instance);
return false;
}
return true;
}
[HarmonyPatch(typeof(ProductionBuilding), "DispatchProductionFinished")]
[HarmonyPostfix]
private static void UnassignSinceDone(ProductionState production)
{
WorkerSlotPatches.TryUnassign(production);
}
[HarmonyPatch(typeof(WorkerStatusSlot), "SetUpActor")]
[HarmonyPrefix]
private static void OverrideProduction(WorkerStatusSlot __instance)
{
WorkerSlotPatches.UpdateMarkerStatus(__instance);
}
[HarmonyPatch(typeof(VillagersService), "RemoveFromProfession")]
[HarmonyPostfix]
private static void SyncStateVillagerGone(Villager villager)
{
WorkerSlotPatches.Remove(villager);
}
[HarmonyPatch(typeof(IngredientsMenu), "OnIngredientClicked")]
[HarmonyPrefix]
private static bool OnIngredientClicked(IngredientState state)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
IInputService inputService = MB.InputService;
DefaultActions inputConfig = MB.InputConfig;
if (inputService.IsTriggering(((DefaultActions)(ref inputConfig)).InputModifierControl))
{
GoodModel good = Serviceable.Settings.GetGood(state.good);
GameMB.GameBlackboardService.RecipesPopupRequested.OnNext(new RecipesPopupRequest(good, true));
return false;
}
return true;
}
[HarmonyPatch(typeof(IngredientSlot), "OnClick")]
[HarmonyPrefix]
private static bool IngredientSlot__OnClick(IngredientSlot __instance)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
IInputService inputService = MB.InputService;
DefaultActions inputConfig = MB.InputConfig;
if (inputService.IsTriggering(((DefaultActions)(ref inputConfig)).InputModifierControl))
{
GameMB.GameBlackboardService.RecipesPopupRequested.OnNext(new RecipesPopupRequest(__instance.GetGood(), true));
return false;
}
return true;
}
[HarmonyPatch(typeof(TimeScalePanel), "SetUp")]
[HarmonyPostfix]
private static void TimeScalePanel__SetUp(TimeScalePanel __instance)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
Transform transform = ((Component)__instance).gameObject.transform;
Transform val = Object.Instantiate<Transform>(transform.Find("Slot (5)"), transform);
((Object)val).name = "Slot (6)";
val.localPosition = new Vector3(90f, 90f, 0f);
((Component)val).GetComponent<TimeScaleSlot>().timeScale = 5f;
((TMP_Text)((Component)val.Find("Desc")).GetComponent<TextMeshProUGUI>()).text = $"x{Plugin.SUPER_SPEED_SCALE:0.}";
}
[HarmonyPatch(typeof(TimeScaleService), "SpeedUp")]
[HarmonyPrefix]
private static bool TimeScaleService__SpeedUp(TimeScaleService __instance)
{
float value = __instance.Scale.Value;
if (value == Plugin.SUPER_SPEED_SCALE)
{
Serviceable.SoundsManager.PlayFailedSound();
return false;
}
if (value == TimeScaleService.Speeds.Last())
{
__instance.Change(5f, true, false);
return false;
}
return true;
}
[HarmonyPatch(typeof(TimeScaleService), "SlowDown")]
[HarmonyPrefix]
private static bool TimeScaleService__SlowDown(TimeScaleService __instance)
{
float value = __instance.Scale.Value;
if (value == Plugin.SUPER_SPEED_SCALE)
{
__instance.Change(TimeScaleService.Speeds.Last(), true, false);
return false;
}
return true;
}
[HarmonyPatch(typeof(BuildingsPanel), "SetUp")]
[HarmonyPostfix]
private static void BuildingPanel__SetUp(BuildingsPanel __instance)
{
Plugin.buildingPanel = __instance;
}
[HarmonyPatch(typeof(TraderPanel), "Show")]
[HarmonyPostfix]
private static void TraderPanel__Show(TraderPanel __instance)
{
GameObject parent = ((BaseMB)__instance).FindChild("Content");
TextMeshProUGUI val = Utils.PatchInGameObject<TextMeshProUGUI>(parent, "StormwalkerCityScore", (Action<TextMeshProUGUI>)delegate(TextMeshProUGUI t)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
((TMP_Text)t).fontSize = 24f;
((TMP_Text)t).fontSizeMax = 24f;
((TMP_Text)t).transform.localPosition = new Vector3(460f, 328f, 0f);
});
ITradeService tradeService = Serviceable.TradeService;
int score = ((TradeService)((tradeService is TradeService) ? tradeService : null)).GetScore();
((TMP_Text)val).text = $"City Score: {score}";
}
}
public class PluginState
{
public Dictionary<int, int> slotsPerHouse = new Dictionary<int, int>();
public HashSet<int> workersToUnassign = new HashSet<int>();
}
public static class Utils
{
public static T CopyComponent<T>(T original, GameObject destination) where T : Component
{
Type type = ((object)original).GetType();
Component component = destination.GetComponent(type);
T val = (T)(object)((component is T) ? component : null);
if (!Object.op_Implicit((Object)(object)val))
{
Component obj = destination.AddComponent(type);
val = (T)(object)((obj is T) ? obj : null);
}
FieldInfo[] fields = type.GetFields();
FieldInfo[] array = fields;
foreach (FieldInfo fieldInfo in array)
{
if (!fieldInfo.IsStatic)
{
fieldInfo.SetValue(val, fieldInfo.GetValue(original));
}
}
PropertyInfo[] properties = type.GetProperties();
PropertyInfo[] array2 = properties;
foreach (PropertyInfo propertyInfo in array2)
{
if (propertyInfo.CanWrite && propertyInfo.CanWrite && !(propertyInfo.Name == "name"))
{
propertyInfo.SetValue(val, propertyInfo.GetValue(original, null), null);
}
}
return val;
}
public static GameObject MakeGameObject(GameObject parent, string name, bool hide = true)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
GameObject val = new GameObject();
GameObject val2 = Object.Instantiate<GameObject>(val, (parent != null) ? parent.transform : null);
((Object)val2).name = name;
if (hide)
{
((Object)val2).hideFlags = (HideFlags)61;
}
ObjectExtensions.Destroy((Object)(object)val);
return val2;
}
public static T PatchInGameObject<T>(GameObject parent, string name, Action<T> setupScript = null) where T : Component
{
Transform obj = parent.transform.Find(name);
GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
if ((Object)(object)val != (Object)null)
{
return val.GetComponent<T>();
}
val = MakeGameObject(parent, name);
T val2 = val.AddComponent<T>();
setupScript?.Invoke(val2);
return val2;
}
public static T StealComponent<T>(string path) where T : Component
{
GameObject val = GameObject.Find(path);
return val.GetComponent<T>();
}
public static LocaText Text(string value, string key)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Expected O, but got Unknown
TextsService val = (TextsService)MainController.Instance.AppServices.TextsService;
if (!val.texts.ContainsKey(key))
{
val.texts.Add(key, value);
}
return new LocaText
{
key = key
};
}
public static Sprite LoadSprite(string file)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_0045: 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)
string path = Path.Combine(Paths.PluginPath, "assets", file);
byte[] array = File.ReadAllBytes(path);
Texture2D val = new Texture2D(4, 4, (TextureFormat)12, false);
ImageConversion.LoadImage(val, array);
return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 50f);
}
}
public class Woodcutters : GameMB
{
private WoodcuttersHUD woodcuttersHUD;
private void Awake()
{
Hotkeys.RegisterKey("Stormwalker", "assign1", "Assign one Villager", new List<KeyCode>(2)
{
(KeyCode)306,
(KeyCode)120
}, delegate(CallbackContext ctx)
{
if (((CallbackContext)(ref ctx)).performed)
{
woodcuttersHUD.OnRightClick();
}
});
Hotkeys.RegisterKey("Stormwalker", "unassignAll", "Unassign all Villagers", new List<KeyCode>(2)
{
(KeyCode)304,
(KeyCode)120
}, delegate(CallbackContext ctx)
{
if (((CallbackContext)(ref ctx)).performed)
{
woodcuttersHUD.OnClick();
}
});
Hotkeys.RegisterKey("Stormwalker", "balanceHostility", "Unassign Villagers to lower Hostility", new List<KeyCode>(2)
{
(KeyCode)308,
(KeyCode)120
}, delegate(CallbackContext ctx)
{
if (((CallbackContext)(ref ctx)).performed)
{
UnassignSomePressed();
}
});
}
public void PatchPanel(WoodcuttersHUD hud)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
woodcuttersHUD = hud;
((Component)hud).transform.localPosition = new Vector3(120f, -71f, 0f);
}
private void UnassignSomePressed()
{
if (canLowerHostility(out var amount))
{
UnassignSome(amount);
Publish(amount);
}
}
private bool canLowerHostility(out int amount)
{
IHostilityService hostilityService = GameMB.HostilityService;
if (((HostilityService)((hostilityService is HostilityService) ? hostilityService : null)).IsFirstLevel())
{
amount = -1;
return false;
}
int pointsFor = GameMB.HostilityService.GetPointsFor((HostilitySource)70);
if (pointsFor <= 0)
{
amount = -1;
return false;
}
int num = GameMB.HostilityService.Points.Value + 1;
int sourceAmount = GameMB.HostilityService.GetSourceAmount((HostilitySource)70);
amount = (int)Math.Ceiling((double)num * (double)sourceAmount / (double)pointsFor);
return sourceAmount >= amount;
}
private void UnassignSome(int toUnassign)
{
for (int i = 0; i < 6; i++)
{
foreach (Camp value in GameMB.BuildingsService.Camps.Values)
{
toUnassign -= TryUnassignOne(value);
if (toUnassign == 0)
{
return;
}
}
}
}
private int TryUnassignOne(Camp camp)
{
for (int i = 0; i < ((ProductionBuilding)camp).Workers.Length; i++)
{
int num = ((ProductionBuilding)camp).Workers[i];
if (GameMB.ActorsService.HasActor(num))
{
Actor actor = GameMB.ActorsService.GetActor(num);
if (!actor.IsBoundToWorkplace)
{
GameMB.VillagersService.ReleaseFromProfession(GameMB.VillagersService.GetVillager(((ProductionBuilding)camp).Workers[i]), true);
return 1;
}
}
}
return 0;
}
private void Publish(int number)
{
if (number > 0)
{
GameMB.NewsService.PublishNews($"Unassigned {number} woodcutters", (AlertSeverity)1, (Sprite)null, (IBroadcaster)null);
}
}
}
public static class WorkerSlotPatches
{
private static readonly string MARKER_NAME = "StormwalkerMarker";
private static Sprite marker = null;
private static HashSet<int> toUnassign => Plugin.State.workersToUnassign;
public static void PutMarkerIn(BuildingWorkerSlot slot)
{
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
Transform obj = ((Component)slot).transform.Find("StatusIcon");
GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
if (!((Object)(object)val.transform.Find(MARKER_NAME) != (Object)null))
{
GameObject val2 = Utils.MakeGameObject(val, MARKER_NAME);
val2.SetActive(false);
val2.transform.localPosition = new Vector3(-10f, 10f, 0f);
TransformExtensions.SetScale(val2.transform, 0.2f);
Image val3 = val2.AddComponent<Image>();
if ((Object)(object)marker == (Object)null)
{
Image val4 = Utils.StealComponent<Image>("/HUD/GoodsHUD/SacrificeMarker/Content");
marker = val4.sprite;
}
val3.sprite = marker;
}
}
public static void QueueToggleUnassign(BuildingWorkerSlot slot)
{
PutMarkerIn(slot);
if (!toUnassign.Remove(slot.actor.Id))
{
toUnassign.Add(slot.actor.Id);
}
}
public static void TryUnassign(ProductionState production)
{
if (toUnassign.Remove(production.worker))
{
IVillagersService villagersService = GameMB.VillagersService;
Villager villager = villagersService.GetVillager(production.worker);
villagersService.ReleaseFromProfession(villager, false);
}
}
public static void Remove(Villager villager)
{
toUnassign.Remove(((Actor)villager).Id);
}
public static bool UpdateMarkerStatus(WorkerStatusSlot slot)
{
Transform val = ((Component)slot).transform.Find("StatusIcon/" + MARKER_NAME);
if ((Object)(object)val == (Object)null || (Object)(object)slot.actor == (Object)null)
{
return false;
}
bool flag = toUnassign.Contains(slot.actor.Id);
ComponentExtensions.SetActive((Component)(object)val, flag);
return flag;
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "Stormwalker";
public const string PLUGIN_NAME = "Stormwalker";
public const string PLUGIN_VERSION = "0.8.0";
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}