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.Text.Json;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using HarmonyLib;
using Il2CppSystem.Collections.Generic;
using SOD.Common;
using SOD.Common.BepInEx;
using SOD.Common.BepInEx.Configuration;
using SOD.Common.Helpers;
using SOD.LifeAndLiving.Patches;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SOD.LifeAndLiving")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+39e7d38cb081176eb7ff96baff8d2037a5edfa15")]
[assembly: AssemblyProduct("SOD.LifeAndLiving")]
[assembly: AssemblyTitle("SOD.LifeAndLiving")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SOD.LifeAndLiving
{
public interface IPluginBindings : ISideJobBindings, IMurderCaseBindings, ISpawnRateBindings, IHousingBindings, IDialogBindings, IMoneyBindings, IShopsBindings, IItemPriceBindings
{
}
public interface ISideJobBindings
{
[Binding(50, "The minimum amount a side job should reward.", "LifeAndLiving.SideJobs.MinSideJobReward")]
int MinSideJobReward { get; set; }
[Binding(85, "The percentage reduction of job resolve payouts.", "LifeAndLiving.SideJobs.PayoutReductionJobs")]
int PayoutReductionJobs { get; set; }
}
public interface IMurderCaseBindings
{
[Binding(80, "The percentage reduction of murder case resolve payouts.", "LifeAndLiving.MurderCases.PayoutReductionMurders")]
int PayoutReductionMurders { get; set; }
[Binding(50, "The minimum a resolve question of a murder case should payout.", "LifeAndLiving.MurderCases.MinimumMurderResolveQuestionPayout")]
int MinimumMurderResolveQuestionPayout { get; set; }
}
public interface ISpawnRateBindings
{
[Binding(true, "This drastically reduces lockpicks per room", "LifeAndLiving.SpawnRate.ReduceLockPickSpawnPerRoom")]
bool ReduceLockPickSpawnPerRoom { get; set; }
[Binding(true, "This drastically reduces lockpicks per address", "LifeAndLiving.SpawnRate.ReduceLockPickSpawnPerAddress")]
bool ReduceLockPickSpawnPerAddress { get; set; }
[Binding(true, "This drastically reduces diamonds spawned per address", "LifeAndLiving.SpawnRate.ReduceDiamondSpawnPerAddress")]
bool ReduceDiamondSpawnPerAddress { get; set; }
[Binding(true, "Should diamonds only spawn in apartements.", "LifeAndLiving.SpawnRate.SpawnDiamondsOnlyInApartements")]
bool SpawnDiamondsOnlyInApartements { get; set; }
[Binding(true, "Should hair pins only spawn in apartment homes?", "LifeAndLiving.SpawnRate.LimitHairPinToHomeOnly")]
bool LimitHairPinToHomeOnly { get; set; }
[Binding(true, "Should paper clips only spawn in office buildings?", "LifeAndLiving.SpawnRate.LimitPaperclipToOfficeOnly")]
bool LimitPaperclipToOfficeOnly { get; set; }
[Binding(true, "Should loose change only spawn in apartements.", "LifeAndLiving.SpawnRate.LimitLooseMoneyToApartementsOnly")]
bool LimitLooseMoneyToApartementsOnly { get; set; }
[Binding(true, "This drastically reduces sync disk upgrade modules spawns.", "LifeAndLiving.SpawnRate.LimitSpawnrateSyncDiskUpgradeModules")]
bool LimitSpawnrateSyncDiskUpgradeModules { get; set; }
[Binding(true, "This drastically reduces sync disk spawns.", "LifeAndLiving.SpawnRate.LimitSpawnrateSyncDisks")]
bool LimitSpawnrateSyncDisks { get; set; }
}
public interface IHousingBindings
{
[Binding(50, "The percentage increase of apartement cost based on the existing price", "LifeAndLiving.Housing.ApartementCostPercentage")]
int ApartementCostPercentage { get; set; }
[Binding(5000, "The minimum $ cost of an apartement, if the percentage increase does not cover this minimum it will be adjusted.", "LifeAndLiving.Housing.MinimumApartementCost")]
int MinimumApartementCost { get; set; }
[Binding(40, "The percentage increase of furniture cost based on the existing price", "LifeAndLiving.Housing.FurniteCostPercentage")]
int FurniteCostPercentage { get; set; }
[Binding(250, "The cost of a lower suite in a hotel per day.", "LifeAndLiving.Housing.CostLowerSuiteHotel")]
int CostLowerSuiteHotel { get; set; }
[Binding(500, "The cost of a higher suite in a hotel per day.", "LifeAndLiving.Housing.CostHigherSuiteHotel")]
int CostHigherSuiteHotel { get; set; }
}
public interface IDialogBindings
{
[Binding(80, "The percentage increase of things such as guest pass cost, things within dialogs.", "LifeAndLiving.Dialog.DialogCostPricePercentage")]
int DialogCostPricePercentage { get; set; }
}
public interface IMoneyBindings
{
[Binding(7, "The maximum $ of loose change in a small stack.", "LifeAndLiving.Money.MaxM1Crows")]
int MaxM1Crows { get; set; }
[Binding(14, "The maximum $ of loose change in a medium stack.", "LifeAndLiving.Money.MaxM2Crows")]
int MaxM2Crows { get; set; }
[Binding(18, "The maximum $ of loose change in a big stack.", "LifeAndLiving.Money.MaxM3Crows")]
int MaxM3Crows { get; set; }
[Binding(25, "The maximum $ of loose change in a huge stack.", "LifeAndLiving.Money.MaxM4Crows")]
int MaxM4Crows { get; set; }
}
public interface IShopsBindings
{
[Binding(5, "The amount of lockpicks the buyable kit should give", "LifeAndLiving.Shops.LockPickKitAmount")]
int LockPickKitAmount { get; set; }
[Binding(15, "The percentage of item value that is taken for selling items to general stores (default game is 50%)", "LifeAndLiving.Shops.PercentageSalePriceGeneral")]
int PercentageSalePriceGeneral { get; set; }
[Binding(40, "The percentage of item value that is taken for selling items to blackmarket (default game is 80%)", "LifeAndLiving.Shops.PercentageSalePriceBlackMarket")]
int PercentageSalePriceBlackMarket { get; set; }
[Binding(70, "The max price an item can be sold for in general stores. (diamond excluded)", "LifeAndLiving.Shops.MaxSellPriceAllItemsGeneral")]
int MaxSellPriceAllItemsGeneral { get; set; }
[Binding(200, "The max price an item can be sold for in blackmarket. (diamond excluded)", "LifeAndLiving.Shops.MaxSellPriceAllItemsBlackMarket")]
int MaxSellPriceAllItemsBlackMarket { get; set; }
}
public interface IItemPriceBindings
{
[Binding(65, "The percentage the value should increase of items.", "LifeAndLiving.ItemPrice.PercentageValueIncrease")]
int PercentageValueIncrease { get; set; }
[Binding(25, "The minimum value of an item.", "LifeAndLiving.ItemPrice.MinItemValue")]
int MinItemValue { get; set; }
[Binding(300, "The minimum value of a diamond.", "LifeAndLiving.ItemPrice.MinDiamondValue")]
int MinDiamondValue { get; set; }
[Binding(1000, "The maximum value of a diamond.", "LifeAndLiving.ItemPrice.MaxDiamondValue")]
int MaxDiamondValue { get; set; }
[Binding(750, "The minimum value of a sync disk upgrade module.", "LifeAndLiving.ItemPrice.MinSyncDiskUpgradeModuleValue")]
int MinSyncDiskUpgradeModuleValue { get; set; }
[Binding(1000, "The maximum value of a sync disk upgrade module.", "LifeAndLiving.ItemPrice.MaxSyncDiskUpgradeModuleValue")]
int MaxSyncDiskUpgradeModuleValue { get; set; }
}
[BepInPlugin("Venomaus.SOD.LifeAndLiving", "LifeAndLiving", "1.0.5")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : PluginController<Plugin, IPluginBindings>
{
public const string PLUGIN_GUID = "Venomaus.SOD.LifeAndLiving";
public const string PLUGIN_NAME = "LifeAndLiving";
public const string PLUGIN_VERSION = "1.0.5";
public override void Load()
{
Lib.SaveGame.OnBeforeLoad += SaveGame_OnBeforeLoad;
Lib.SaveGame.OnBeforeSave += SaveGame_OnBeforeSave;
Lib.SaveGame.OnBeforeDelete += SaveGame_OnBeforeDelete;
base.Harmony.PatchAll(Assembly.GetExecutingAssembly());
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Plugin is patched.");
}
private void SaveGame_OnBeforeDelete(object sender, SaveGameArgs e)
{
string uniqueString = Lib.SaveGame.GetUniqueString(e.FilePath);
string savestoreDirectoryPath = Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), "apartmentpricecache_" + uniqueString + ".json");
if (File.Exists(savestoreDirectoryPath))
{
File.Delete(savestoreDirectoryPath);
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Deleted apartment price cache.");
}
}
private void SaveGame_OnBeforeSave(object sender, SaveGameArgs e)
{
Dictionary<string, int> apartementPriceCache = NewGameLocationPatches.NewGameLocation_GetPrice.ApartementPriceCache;
if (apartementPriceCache.Count > 0)
{
string uniqueString = Lib.SaveGame.GetUniqueString(e.FilePath);
string savestoreDirectoryPath = Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), "apartmentpricecache_" + uniqueString + ".json");
string contents = JsonSerializer.Serialize(apartementPriceCache, new JsonSerializerOptions
{
WriteIndented = false
});
File.WriteAllText(savestoreDirectoryPath, contents);
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Saved apartment price cache.");
}
}
private void SaveGame_OnBeforeLoad(object sender, SaveGameArgs e)
{
Dictionary<string, int> apartementPriceCache = NewGameLocationPatches.NewGameLocation_GetPrice.ApartementPriceCache;
apartementPriceCache.Clear();
string uniqueString = Lib.SaveGame.GetUniqueString(e.FilePath);
string savestoreDirectoryPath = Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), "apartmentpricecache_" + uniqueString + ".json");
if (!File.Exists(savestoreDirectoryPath))
{
return;
}
foreach (KeyValuePair<string, int> item in JsonSerializer.Deserialize<Dictionary<string, int>>(File.ReadAllText(savestoreDirectoryPath)))
{
apartementPriceCache.Add(item.Key, item.Value);
}
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Loaded apartment price cache.");
}
}
}
namespace SOD.LifeAndLiving.Patches
{
internal class ActionControllerPatches
{
[HarmonyPatch(typeof(ActionController), "TakeLockpickKit")]
internal class ActionController_TakeLockpickKit
{
private static int _previousLockPicks;
[HarmonyPrefix]
internal static void Prefix()
{
_previousLockPicks = GameplayController.Instance.lockPicks;
}
[HarmonyPostfix]
internal static void Postfix()
{
int num = GameplayController.Instance.lockPicks - _previousLockPicks;
GameplayController.Instance.AddLockpicks(-num + ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.LockPickKitAmount, false);
}
}
}
internal class BuyInterfacePatches
{
[HarmonyPatch(typeof(BuyInterfaceController), "UpdateElements")]
internal class BuyInterfaceController_UpdateElements
{
[HarmonyPostfix]
internal static void Postfix(BuyInterfaceController __instance)
{
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Expected O, but got Unknown
List<ShopSelectButtonController> spawned = __instance.spawned;
bool flag = __instance.company != null && __instance.company.preset.enableSellingOfIllegalItems;
int maxSellPriceAllItemsGeneral = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MaxSellPriceAllItemsGeneral;
int maxSellPriceAllItemsBlackMarket = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MaxSellPriceAllItemsBlackMarket;
bool flag2 = false;
int num = 0;
Enumerator<ShopSelectButtonController> enumerator = spawned.GetEnumerator();
while (enumerator.MoveNext())
{
ShopSelectButtonController current = enumerator.Current;
if (current.sellInteractable != null && current.sellMode && !((SoCustomComparison)current.sellInteractable.preset).presetName.Equals("Diamond"))
{
int price = current.price;
current.price = Math.Min(current.price, flag ? maxSellPriceAllItemsBlackMarket : maxSellPriceAllItemsGeneral);
if (price != current.price)
{
((ButtonController)current).UpdateButtonText();
flag2 = true;
num++;
}
}
}
if (flag2)
{
__instance.UpdatePurchaseAbility();
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
bool flag3 = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(49, 1, ref flag3);
if (flag3)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Capped sale price of \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" items at store interface.");
}
log.LogInfo(val);
}
}
}
}
internal class CityControlsPatches
{
[HarmonyPatch(typeof(CityControls), "Awake")]
internal class CityControls_Awake
{
[HarmonyPrefix]
internal static void Prefix(CityControls __instance)
{
__instance.hotelCostLower = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.CostLowerSuiteHotel;
__instance.hotelCostUpper = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.CostHigherSuiteHotel;
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Updated hotel suite prices.");
}
}
}
internal class GameplayControlsPatches
{
[HarmonyPatch(typeof(GameplayControls), "Awake")]
internal class GameplayControls_Awake
{
private static bool _appliedOnce;
[HarmonyPostfix]
internal static void Postfix(GameplayControls __instance)
{
if (!_appliedOnce)
{
_appliedOnce = true;
ReduceMurderPayouts(__instance);
}
}
private static void ReduceMurderPayouts(GameplayControls __instance)
{
//IL_003e: 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_006a: 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_009b: 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_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Expected O, but got Unknown
//IL_00bd: 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_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
int payoutReductionMurders = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.PayoutReductionMurders;
int minimumMurderResolveQuestionPayout = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MinimumMurderResolveQuestionPayout;
int num = 0;
Enumerator<ResolveQuestion> enumerator = __instance.murderResolveQuestions.GetEnumerator();
while (enumerator.MoveNext())
{
ResolveQuestion current = enumerator.Current;
int num2 = Math.Max(minimumMurderResolveQuestionPayout, (int)current.rewardRange.x - (int)(current.rewardRange.x / 100f * (float)payoutReductionMurders));
int num3 = Math.Max(minimumMurderResolveQuestionPayout, (int)current.rewardRange.y - (int)(current.rewardRange.y / 100f * (float)payoutReductionMurders));
current.rewardRange = new Vector2((float)num2, (float)num3);
if (current.penaltyRange.x > 0f && current.penaltyRange.y > 0f)
{
num2 = Math.Max(minimumMurderResolveQuestionPayout, (int)current.penaltyRange.x + (int)(current.penaltyRange.x / 100f * (float)(payoutReductionMurders / 4)));
num3 = Math.Max(minimumMurderResolveQuestionPayout, (int)current.penaltyRange.y + (int)(current.penaltyRange.y / 100f * (float)(payoutReductionMurders / 4)));
current.penaltyRange = new Vector2((float)num2, (float)num3);
}
num++;
}
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(43, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Reduced \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" murder resolve question payouts.");
}
log.LogInfo(val);
}
}
}
internal class InteractablePatches
{
[HarmonyPatch(typeof(Interactable), "SetValue")]
internal class Interactable_SetValue
{
[HarmonyPrefix]
internal static void Prefix(Interactable __instance, ref float newValue)
{
if (!((SoCustomComparison)(object)__instance.preset == (SoCustomComparison)null))
{
Dictionary<string, int> dictionary = new Dictionary<string, int>
{
{
"M1",
((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MaxM1Crows
},
{
"M2",
((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MaxM2Crows
},
{
"M3",
((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MaxM3Crows
},
{
"M4",
((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MaxM4Crows
}
};
if (__instance.preset.isMoney && dictionary.TryGetValue(((SoCustomComparison)__instance.preset).presetName, out var value) && newValue > (float)value)
{
newValue = value;
}
}
}
}
}
internal class NewGameLocationPatches
{
[HarmonyPatch(typeof(NewGameLocation), "GetPrice")]
internal class NewGameLocation_GetPrice
{
private static readonly Random _valueRandom = new Random();
internal static readonly Dictionary<string, int> ApartementPriceCache = new Dictionary<string, int>();
[HarmonyPostfix]
internal static void Postfix(NewGameLocation __instance, ref int __result)
{
string key = __instance.building.buildingID + "_" + __instance.residenceNumber;
if (ApartementPriceCache.TryGetValue(key, out var value))
{
__result = value;
return;
}
__result += __result / 100 * ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.ApartementCostPercentage;
if (__result < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MinimumApartementCost)
{
int num = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MinimumApartementCost / 2;
int num2 = num / 100 * 25;
__result = RoundToNearestInterval(_valueRandom.Next(num, num + num2) * 2, 50, 100);
}
ApartementPriceCache.Add(key, __result);
}
private static int RoundToNearestInterval(int number, int lowerInterval, int higherInterval)
{
int num = (int)Math.Round((double)number / (double)lowerInterval) * lowerInterval;
int num2 = (int)Math.Round((double)number / (double)higherInterval) * higherInterval;
int num3 = Math.Abs(number - num);
int num4 = Math.Abs(number - num2);
if (num3 < num4)
{
return num;
}
return num2;
}
}
}
internal class PriceVisualPatches
{
[HarmonyPatch(typeof(MurderController), "UpdateResolveQuestions")]
internal class MurderController_UpdateResolveQuestions
{
[HarmonyPostfix]
internal static void Postfix(MurderController __instance)
{
//IL_002a: 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)
if (__instance.currentActiveCase != null)
{
Enumerator<ResolveQuestion> enumerator = __instance.currentActiveCase.resolveQuestions.GetEnumerator();
while (enumerator.MoveNext())
{
ResolveQuestion current = enumerator.Current;
current.reward = Mathf.RoundToInt(Toolbox.Instance.VectorToRandom(current.rewardRange) * Game.Instance.jobRewardMultiplier);
current.penalty = Mathf.RoundToInt(Toolbox.Instance.VectorToRandom(current.penaltyRange) * Game.Instance.jobPenaltyMultiplier);
}
}
}
}
[HarmonyPatch(typeof(SideJob), "GenerateResolveQuestions")]
internal class SideJob_GenerateResolveQuestions
{
[HarmonyPostfix]
internal static void Postfix(SideJob __instance)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Invalid comparison between Unknown and I4
//IL_0094: 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_0070: 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)
__instance.reward = 0;
Enumerator<ResolveQuestion> enumerator = __instance.resolveQuestions.GetEnumerator();
while (enumerator.MoveNext())
{
ResolveQuestion current = enumerator.Current;
if (__instance.rewardSyncDisk != null && __instance.rewardSyncDisk.Length > 0)
{
continue;
}
float num = 1f;
if ((int)current.inputType == 3)
{
RevengeObjective revengeObjective = __instance.GetRevengeObjective(current);
if ((SoCustomComparison)(object)revengeObjective != (SoCustomComparison)null)
{
float num2 = Toolbox.Instance.Rand(0f, 1f, false);
num = Mathf.Lerp(revengeObjective.rewardMultiplier.x, revengeObjective.rewardMultiplier.y, num2);
}
}
current.reward = Mathf.RoundToInt(Toolbox.Instance.VectorToRandom(current.rewardRange) * Game.Instance.jobRewardMultiplier * num * GameplayControls.Instance.sideJobDifficultyRewardMultiplier.Evaluate(__instance.GetDifficulty()));
current.reward = Mathf.RoundToInt((float)current.reward * (1f + UpgradeEffectController.Instance.GetUpgradeEffect((Effect)17)));
current.penalty = Mathf.RoundToInt(Toolbox.Instance.VectorToRandom(current.penaltyRange) * Game.Instance.jobPenaltyMultiplier * GameplayControls.Instance.sideJobDifficultyRewardMultiplier.Evaluate(__instance.GetDifficulty()));
__instance.reward += current.reward;
}
}
}
}
internal class ToolboxPatches
{
[HarmonyPatch(typeof(Toolbox), "LoadAll")]
internal class Toolbox_LoadAll
{
private static bool _appliedOnce;
[HarmonyPostfix]
internal static void Postfix(Toolbox __instance)
{
if (!_appliedOnce)
{
_appliedOnce = true;
ReduceJobPayouts(__instance);
AdjustInteractableSpawns(__instance);
AdjustFurnitureCostPrices(__instance);
AdjustDialogCostPrices(__instance);
AdjustItemPrices(__instance);
AdjustCompanyItemSellMultipliers(__instance);
}
}
private static void AdjustDialogCostPrices(Toolbox __instance)
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Expected O, but got Unknown
int dialogCostPricePercentage = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.DialogCostPricePercentage;
int num = 0;
Enumerator<DialogPreset> enumerator = __instance.allDialog.GetEnumerator();
while (enumerator.MoveNext())
{
DialogPreset current = enumerator.Current;
if (current.cost > 0)
{
current.cost += current.cost / 100 * dialogCostPricePercentage;
num++;
}
}
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Adjusted \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" dialog cost prices.");
}
log.LogInfo(val);
}
private static void AdjustFurnitureCostPrices(Toolbox __instance)
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Expected O, but got Unknown
int furniteCostPercentage = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.FurniteCostPercentage;
int num = 0;
Enumerator<FurniturePreset> enumerator = __instance.allFurniture.GetEnumerator();
while (enumerator.MoveNext())
{
FurniturePreset current = enumerator.Current;
if (current.cost > 0)
{
current.cost += current.cost / 100 * furniteCostPercentage;
num++;
}
}
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(34, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Adjusted \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" furniture cost prices.");
}
log.LogInfo(val);
}
private static void AdjustCompanyItemSellMultipliers(Toolbox __instance)
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected O, but got Unknown
int percentageSalePriceGeneral = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.PercentageSalePriceGeneral;
int percentageSalePriceBlackMarket = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.PercentageSalePriceBlackMarket;
int num = 0;
Enumerator<CompanyPreset> enumerator = __instance.allCompanyPresets.GetEnumerator();
while (enumerator.MoveNext())
{
CompanyPreset current = enumerator.Current;
if (current.enableSellingOfIllegalItems)
{
current.sellValueMultiplier = (float)percentageSalePriceBlackMarket / 100f;
}
else
{
current.sellValueMultiplier = (float)percentageSalePriceGeneral / 100f;
}
num++;
}
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Adjusted \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" store prices.");
}
log.LogInfo(val);
}
private static void AdjustItemPrices(Toolbox __instance)
{
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Expected O, but got Unknown
//IL_0069: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
float num = (float)((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.PercentageValueIncrease / 100f + 1f;
int minItemValue = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MinItemValue;
Random random = new Random(1000);
int num2 = 0;
Enumerator<string, InteractablePreset> enumerator = __instance.objectPresetDictionary.GetEnumerator();
while (enumerator.MoveNext())
{
InteractablePreset value = enumerator.Current.value;
if ((SoCustomComparison)(object)value != (SoCustomComparison)null && value.value.y > 0f && !((SoCustomComparison)value).presetName.Equals("Diamond") && !((SoCustomComparison)value).presetName.Equals("SyncDiskUpgrade"))
{
int num3 = Math.Max(minItemValue, (int)value.value.x);
int num4 = Math.Max(num3 + ((int)value.value.y - (int)value.value.x), (int)value.value.y);
num3 = (int)((float)num3 * num);
num4 = (int)((float)num4 * num);
int num5 = num3 - minItemValue;
if (num5 > 0)
{
num3 -= random.Next(0, Math.Min(num5, 15) + 1);
}
num4 += random.Next(0, 16);
value.value = new Vector2((float)num3, (float)num4);
num2++;
}
}
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Adjusted \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num2);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" item purchase prices.");
}
log.LogInfo(val);
}
private static void ReduceJobPayouts(Toolbox __instance)
{
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Expected O, but got Unknown
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
List<JobPreset> allSideJobs = __instance.allSideJobs;
int payoutReductionJobs = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.PayoutReductionJobs;
int num = 0;
int minSideJobReward = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MinSideJobReward;
Enumerator<JobPreset> enumerator = allSideJobs.GetEnumerator();
while (enumerator.MoveNext())
{
JobPreset current = enumerator.Current;
int num2 = 0;
int num3 = 0;
Enumerator<ResolveQuestion> enumerator2 = current.resolveQuestions.GetEnumerator();
while (enumerator2.MoveNext())
{
ResolveQuestion current2 = enumerator2.Current;
int num4 = Math.Max(1, (int)current2.rewardRange.x - (int)(current2.rewardRange.x / 100f * (float)payoutReductionJobs));
int num5 = Math.Max(1, (int)current2.rewardRange.y - (int)(current2.rewardRange.y / 100f * (float)payoutReductionJobs));
current2.rewardRange = new Vector2((float)num4, (float)num5);
num2 += num4;
num3 += num5;
}
if (num2 < minSideJobReward || num3 < minSideJobReward)
{
int num6 = (int)Math.Ceiling((float)minSideJobReward / (float)current.resolveQuestions.Count);
enumerator2 = current.resolveQuestions.GetEnumerator();
while (enumerator2.MoveNext())
{
enumerator2.Current.rewardRange = new Vector2((float)num6, (float)num6);
}
}
num++;
}
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(23, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Reduced \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" job payouts.");
}
log.LogInfo(val);
}
private static void AdjustInteractableSpawns(Toolbox __instance)
{
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
InteractablePreset interactablePreset = __instance.GetInteractablePreset("Diamond");
InteractablePreset interactablePreset2 = __instance.GetInteractablePreset("Hairpin");
InteractablePreset interactablePreset3 = __instance.GetInteractablePreset("Paperclip");
InteractablePreset interactablePreset4 = __instance.GetInteractablePreset("SyncDiskUpgrade");
InteractablePreset interactablePreset5 = __instance.GetInteractablePreset("SyncDisk");
InteractablePreset[] looseChange = new string[4] { "M1", "M2", "M3", "M4" }.Select((string a) => __instance.GetInteractablePreset(a)).ToArray();
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.ReduceDiamondSpawnPerAddress)
{
interactablePreset.perRoomLimit = 1;
interactablePreset.perAddressLimit = 1;
interactablePreset.limitPerRoom = true;
interactablePreset.limitPerAddress = true;
}
interactablePreset.value = new Vector2((float)((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MinDiamondValue, (float)((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MaxDiamondValue);
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.SpawnDiamondsOnlyInApartements)
{
interactablePreset.autoPlacement = (AutoPlacement)2;
}
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.LimitSpawnrateSyncDiskUpgradeModules)
{
interactablePreset4.perRoomLimit = 1;
interactablePreset4.perAddressLimit = 2;
interactablePreset4.perObjectLimit = 1;
interactablePreset4.perCommercialLimit = 2;
interactablePreset4.limitInCommercial = true;
interactablePreset4.limitPerRoom = true;
interactablePreset4.limitPerAddress = true;
interactablePreset4.limitPerObject = true;
}
interactablePreset4.value = new Vector2((float)((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MinSyncDiskUpgradeModuleValue, (float)((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.MaxSyncDiskUpgradeModuleValue);
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.LimitSpawnrateSyncDisks)
{
interactablePreset5.perRoomLimit = 1;
interactablePreset5.perAddressLimit = 2;
interactablePreset5.perObjectLimit = 1;
interactablePreset5.perCommercialLimit = 2;
interactablePreset5.limitInCommercial = true;
interactablePreset5.limitPerRoom = true;
interactablePreset5.limitPerAddress = true;
interactablePreset5.limitPerObject = true;
}
AdjustHairPins(interactablePreset2);
AdjustPaperClips(interactablePreset3);
AdjustLooseChange(looseChange);
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Adjusted spawn rate of interactables.");
}
private static void AdjustLooseChange(InteractablePreset[] looseChange)
{
foreach (InteractablePreset val in looseChange)
{
val.perRoomLimit = 1;
val.perAddressLimit = 1;
val.frequencyPerOwnerMax = 1;
val.limitPerAddress = true;
val.limitPerRoom = true;
val.limitPerObject = true;
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.LimitLooseMoneyToApartementsOnly)
{
val.autoPlacement = (AutoPlacement)2;
}
}
}
private static void AdjustPaperClips(InteractablePreset paperClipPreset)
{
paperClipPreset.frequencyPerOwnerMin = 0;
paperClipPreset.frequencyPerOwnerMax = 1;
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.ReduceLockPickSpawnPerRoom)
{
paperClipPreset.perRoomLimit = 1;
paperClipPreset.limitPerRoom = true;
}
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.ReduceLockPickSpawnPerAddress)
{
paperClipPreset.perAddressLimit = 2;
paperClipPreset.limitPerAddress = true;
}
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.LimitPaperclipToOfficeOnly)
{
paperClipPreset.autoPlacement = (AutoPlacement)1;
}
}
private static void AdjustHairPins(InteractablePreset hairPinPreset)
{
hairPinPreset.frequencyPerOwnerMin = 0;
hairPinPreset.frequencyPerOwnerMax = 1;
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.ReduceLockPickSpawnPerRoom)
{
hairPinPreset.perRoomLimit = 1;
hairPinPreset.limitPerRoom = true;
}
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.ReduceLockPickSpawnPerAddress)
{
hairPinPreset.perAddressLimit = 2;
hairPinPreset.limitPerAddress = true;
}
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.LimitHairPinToHomeOnly)
{
hairPinPreset.autoPlacement = (AutoPlacement)2;
}
}
}
}
}