Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of RepairRV v1.0.1
RVRepairVan.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using HarmonyLib; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using RVRepairVan; using ScheduleOne.DevUtilities; using ScheduleOne.Dialogue; using ScheduleOne.Money; using ScheduleOne.Persistence; using ScheduleOne.Property; using ScheduleOne.VoiceOver; using TMPro; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(Core), "RVRepairVan", "1.0.0", "DooDesch", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RVRepairVan")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RVRepairVan")] [assembly: AssemblyTitle("RVRepairVan")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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 RVRepairVan { public class Core : MelonMod { public static MelonPreferences_Entry<float> repairPrice; public static Core Instance { get; private set; } public static Instance Logger { get; private set; } public float RepairPrice => repairPrice.Value; public override void OnInitializeMelon() { Instance = this; repairPrice = MelonPreferences.CreateEntry<float>("Settings", "Repair Price", 1500f, "The price to repair the RV.", (string)null, false, false, (ValueValidator)null); if (repairPrice.Value < 0f) { Logger.Msg("Repair price cannot be negative. Setting to default value of 1500."); repairPrice.Value = 1500f; } Logger = ((MelonBase)this).LoggerInstance; Logger.Msg("RVRepairVan Initialized."); } } public class RVManager : MonoBehaviour { private RV rv; public void Init(RV rvInstance) { rv = rvInstance; LoadState(); Start(); } private void Start() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if ((Object)(object)Singleton<LoadManager>.Instance != (Object)null) { Singleton<LoadManager>.Instance.onLoadComplete.AddListener(new UnityAction(OnLoadComplete)); } } private void OnLoadComplete() { Core.Logger.Msg("Load complete!"); LoadState(selfCall: true); } private void OnDestroy() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if ((Object)(object)Singleton<LoadManager>.Instance != (Object)null) { Singleton<LoadManager>.Instance.onLoadComplete.RemoveListener(new UnityAction(OnLoadComplete)); } } public bool IsVanDestroyed() { Transform val = ((Component)this).transform.Find("Destroyed RV"); if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf) { return true; } return false; } private bool IsVanOwned() { return Property.OwnedProperties.Contains((Property)(object)rv); } private bool IsVanUnowned() { return Property.UnownedProperties.Contains((Property)(object)rv); } private void SetVanOwned() { if (IsVanOwned()) { Core.Logger.Msg("RV is already owned."); return; } Property.OwnedProperties.Add((Property)(object)rv); Property.UnownedProperties.Remove((Property)(object)rv); if ((Object)(object)((Property)rv).ForSaleSign != (Object)null && ((Property)rv).ForSaleSign.activeSelf) { ((Property)rv).ForSaleSign.SetActive(false); } Core.Logger.Msg("RV is now owned."); } private void SetVanUnowned() { if (!IsVanOwned()) { Core.Logger.Msg("RV is already unowned."); return; } Property.UnownedProperties.Add((Property)(object)rv); Property.OwnedProperties.Remove((Property)(object)rv); if ((Object)(object)((Property)rv).ForSaleSign != (Object)null && !((Property)rv).ForSaleSign.activeSelf) { ((Property)rv).ForSaleSign.SetActive(true); ((TMP_Text)((Component)((Property)rv).ForSaleSign.transform.Find("Price")).GetComponent<TextMeshPro>()).text = MoneyManager.FormatAmount(10000f, false, false); } Core.Logger.Msg("RV is now unowned."); } public void RepairVan() { Core.Logger.Msg("Repairing RV..."); SetVanOwned(); if (!IsVanDestroyed()) { Core.Logger.Msg("RV is not destroyed, no repair needed."); return; } FieldInfo field = typeof(RV).GetField("<_isExploded>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { field.SetValue(rv, false); } else { Core.Logger.Msg("_isExploded field not found, cannot set to false."); } Transform val = ((Component)this).transform.Find("RV"); Transform val2 = ((Component)this).transform.Find("Destroyed RV"); Transform val3 = null; if ((Object)(object)val2 != (Object)null) { val3 = val2.Find("CartelNote"); } if ((Object)(object)val != (Object)null && !((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeSelf) { ((Component)val2).gameObject.SetActive(false); } if ((Object)(object)val3 != (Object)null && ((Component)val3).gameObject.activeSelf) { ((Component)val3).gameObject.SetActive(false); if ((Object)(object)val != (Object)null) { val3.SetParent(val); } } if ((Object)(object)rv.FXContainer != (Object)null && !((Component)rv.FXContainer).gameObject.activeSelf) { ((Component)rv.FXContainer).gameObject.SetActive(true); } Core.Logger.Msg("RV was repaired."); } public void SaveState(bool setDefaultSettings = false) { RVStateData rVStateData = new RVStateData(); if (setDefaultSettings) { rVStateData.isDestroyed = true; rVStateData.isOwned = false; } else { rVStateData.isDestroyed = IsVanDestroyed(); rVStateData.isOwned = IsVanOwned(); } string contents = JsonUtility.ToJson((object)rVStateData, true); string path = Path.Combine(Application.persistentDataPath, "rv_state.json"); File.WriteAllText(path, contents); } public void LoadState(bool selfCall = false) { Core.Logger.Msg("Loading RV state..."); string text = Path.Combine(Application.persistentDataPath, "rv_state.json"); if (File.Exists(text)) { string text2 = File.ReadAllText(text); RVStateData rVStateData = JsonUtility.FromJson<RVStateData>(text2); if (!rVStateData.isDestroyed) { RepairVan(); } if (rVStateData.isOwned) { SetVanOwned(); } else { SetVanUnowned(); } Core.Logger.Msg("RV state loaded."); } else { SaveState(setDefaultSettings: true); if (!selfCall) { LoadState(selfCall: true); } Core.Logger.Msg("RV state file not found at: " + text); } } } [Serializable] public class RVStateData { public bool isDestroyed; public bool isOwned; } } namespace RVRepairVan.Patches { [HarmonyPatch(typeof(DialogueController_Ming))] public class DialogueController_Ming_Patch : DialogueController { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ShouldShowCheck <>9__2_0; internal bool <StartPostfix>b__2_0(bool enabled) { return RV_Patch.Instance.IsVanDestroyed(); } } public static float RepairPrice = Core.Instance.RepairPrice; public static DialogueChoice RepairVanChoice; [HarmonyPostfix] [HarmonyPatch("Start")] public static void StartPostfix(DialogueController_Ming __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0044: Expected O, but got Unknown DialogueChoice val = new DialogueChoice(); val.ChoiceText = "Can you repair my Van?"; val.Conversation = CreateVanRepairDialogue(); val.Enabled = true; object obj = <>c.<>9__2_0; if (obj == null) { ShouldShowCheck val2 = (bool enabled) => RV_Patch.Instance.IsVanDestroyed(); <>c.<>9__2_0 = val2; obj = (object)val2; } val.shouldShowCheck = (ShouldShowCheck)obj; RepairVanChoice = val; ((DialogueController)__instance).AddDialogueChoice(val, 10); } public static DialogueContainer CreateVanRepairDialogue() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown DialogueContainer val = ScriptableObject.CreateInstance<DialogueContainer>(); val.NodeLinks = new List<NodeLinkData>(); val.DialogueNodeData = new List<DialogueNodeData>(); val.BranchNodeData = new List<BranchNodeData>(); DialogueNodeData val2 = new DialogueNodeData(); val2.Guid = Guid.NewGuid().ToString(); val2.DialogueNodeLabel = "ENTRY"; val2.DialogueText = "Alright, I'll repair your van. It will cost you a fee, but you'll be back on the road in no time!"; val2.Position = new Vector2(100f, 100f); val2.VoiceLine = (EVOLineType)10; DialogueChoiceData val3 = new DialogueChoiceData(); val3.Guid = Guid.NewGuid().ToString(); val3.ChoiceLabel = "CHOICE_REPAIR_VAN"; val3.ChoiceText = $"Yes ({RepairPrice}$)"; DialogueChoiceData val4 = new DialogueChoiceData(); val4.Guid = Guid.NewGuid().ToString(); val4.ChoiceText = "Maybe later"; val2.choices = new List<DialogueChoiceData> { val3, val4 }.ToArray(); val.DialogueNodeData.Add(val2); return val; } } [HarmonyPatch(typeof(DialogueController_Ming), "ChoiceCallback")] public class DialogueController_Ming_ChoiceCallback_Patch { public static void Postfix(DialogueController_Ming __instance, string choiceLabel) { if (!(choiceLabel == "CHOICE_REPAIR_VAN")) { return; } MoneyManager instance = NetworkSingleton<MoneyManager>.Instance; if (instance.cashBalance >= DialogueController_Ming_Patch.RepairPrice) { instance.ChangeCashBalance(0f - DialogueController_Ming_Patch.RepairPrice, true, true); if ((Object)(object)RV_Patch.Instance != (Object)null) { RV_Patch.Instance.RepairVan(); } else { Core.Logger.Msg("RVRepairer instance not found!"); } } else { Core.Logger.Msg("Not enough cash."); } } } [HarmonyPatch(typeof(RV))] public class RV_Patch { public static RVManager Instance; [HarmonyPostfix] [HarmonyPatch("Awake")] public static void AwakePostfix(RV __instance) { RVManager rVManager = ((Component)__instance).gameObject.GetComponent<RVManager>(); if ((Object)(object)rVManager == (Object)null) { rVManager = ((Component)__instance).gameObject.AddComponent<RVManager>(); rVManager.Init(__instance); } Instance = rVManager; } [HarmonyPostfix] [HarmonyPatch("OnSpawnServer")] public static void StartPostfix(RV __instance) { Instance.LoadState(); } } [HarmonyPatch(typeof(SaveManager), "Save", new Type[] { })] public class SaveManager_Patch { [HarmonyPostfix] public static void SavePostfix() { Core.Logger.Msg("SavePostfix called!"); RV_Patch.Instance.SaveState(); } } }