using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
[assembly: AssemblyTitle("Potato Shop Tweaks")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("1.0.1.0")]
namespace PotatoShopTweaks;
internal static class AutoPrice
{
private sealed class Tally
{
public int Checked;
public int Changed;
public int AlreadyRight;
public int NoMarket;
public int Failed;
}
[HarmonyPatch(typeof(PriceChangeManager), "OnDayStarted")]
internal static class Morning
{
[HarmonyPriority(0)]
private static void Postfix()
{
if (Plugin.AutoPriceEveryMorning.Value)
{
Run("morning");
}
}
}
private const int PerFrame = 20;
private static bool running;
internal static void Run(string why)
{
if (running)
{
return;
}
if (Coop.IsGuest)
{
if (why == "hotkey")
{
Plugin.Toast("Auto-pricing: only the host can do this in co-op.");
}
return;
}
ShelfManager val = FindShelfManager();
if ((Object)(object)val == (Object)null)
{
if (why == "hotkey")
{
Plugin.Toast("Auto-pricing: load your shop first.");
}
}
else
{
((MonoBehaviour)Runner.Ensure()).StartCoroutine(Price(val, why));
}
}
private static ShelfManager FindShelfManager()
{
ShelfManager result = null;
int num = -1;
ShelfManager[] array = Object.FindObjectsOfType<ShelfManager>();
foreach (ShelfManager val in array)
{
if (!((Object)(object)val == (Object)null))
{
int num2 = Count(val.m_ShelfList) + Count(val.m_CardShelfList) + Count(val.m_CardItemCombiShelfList);
if (num2 > num)
{
result = val;
num = num2;
}
}
}
return result;
}
private static int Count<T>(List<T> list)
{
return list?.Count ?? 0;
}
private static IEnumerator Price(ShelfManager shelves, string why)
{
running = true;
int step = 0;
float factor = 1f + Plugin.AutoPriceMarkup.Value / 100f;
Tally items = new Tally();
Tally cards = new Tally();
List<EItemType> itemTypes = new List<EItemType>();
List<CardData> cardList = new List<CardData>();
try
{
Collect(shelves, itemTypes, cardList);
}
catch (Exception ex)
{
running = false;
Plugin.Log.LogError((object)("Auto-pricing couldn't read the shelves: " + ex));
Plugin.Toast("Auto-pricing failed; see the BepInEx log.");
yield break;
}
Plugin.Log.LogInfo((object)($"Auto-pricing: {Count(shelves.m_ShelfList)} shelves, {Count(shelves.m_CardShelfList)} card shelves, " + $"{Count(shelves.m_CardItemCombiShelfList)} combo shelves; {itemTypes.Count} kinds of items and {cardList.Count} kinds of cards on them."));
foreach (EItemType type in itemTypes)
{
items.Checked++;
try
{
float itemMarketPrice = CPlayerData.GetItemMarketPrice(type);
if (itemMarketPrice <= 0f)
{
items.NoMarket++;
}
else
{
float num = Round(itemMarketPrice * factor);
if (Mathf.Abs(CPlayerData.GetItemPrice(type, true) - num) > 0.001f)
{
CPlayerData.SetItemPrice(type, num);
items.Changed++;
}
else
{
items.AlreadyRight++;
}
}
}
catch (Exception ex2)
{
items.Failed++;
Plugin.Log.LogWarning((object)$"Auto-pricing skipped item {type}: {ex2.Message}");
}
int num2;
step = (num2 = step + 1);
if (num2 % 20 == 0)
{
yield return null;
}
}
foreach (CardData card in cardList)
{
cards.Checked++;
try
{
float cardMarketPrice = CPlayerData.GetCardMarketPrice(card);
if (cardMarketPrice <= 0f)
{
cards.NoMarket++;
}
else
{
float num3 = Round(cardMarketPrice * factor);
if (Mathf.Abs(CPlayerData.GetCardPrice(card) - num3) > 0.001f)
{
CPlayerData.SetCardPrice(card, num3);
cards.Changed++;
}
else
{
cards.AlreadyRight++;
}
}
}
catch (Exception ex3)
{
cards.Failed++;
Plugin.Log.LogWarning((object)$"Auto-pricing skipped a card: {ex3.Message}");
}
int num2;
step = (num2 = step + 1);
if (num2 % 20 == 0)
{
yield return null;
}
}
running = false;
Plugin.Log.LogInfo((object)($"Auto-pricing items: {items.Checked} checked, {items.Changed} changed, {items.AlreadyRight} already right, " + $"{items.NoMarket} without a market price, {items.Failed} failed. Cards: {cards.Checked} checked, {cards.Changed} changed, " + $"{cards.AlreadyRight} already right, {cards.NoMarket} without a market price, {cards.Failed} failed."));
if (!(why != "hotkey") || items.Changed + cards.Changed != 0)
{
if (items.Checked + cards.Checked == 0)
{
Plugin.Toast("Auto-pricing: found nothing on your shelves to price.");
yield break;
}
string markup = ((!(Plugin.AutoPriceMarkup.Value >= 0f)) ? $"{Plugin.AutoPriceMarkup.Value:0.#}%" : $"+{Plugin.AutoPriceMarkup.Value:0.#}%");
string what = ((!Plugin.AutoPriceCards.Value) ? $"{items.Changed} of {items.Checked} items" : $"{items.Changed} of {items.Checked} items and {cards.Changed} of {cards.Checked} cards");
int right = items.AlreadyRight + cards.AlreadyRight;
Plugin.Toast($"Auto-pricing: repriced {what} to market {markup}" + ((right <= 0) ? "." : $" ({right} already were)."));
}
}
private static void Collect(ShelfManager shelves, List<EItemType> itemTypes, List<CardData> cardList)
{
HashSet<EItemType> seen = new HashSet<EItemType>();
if (shelves.m_ShelfList != null)
{
foreach (Shelf shelf in shelves.m_ShelfList)
{
if ((Object)(object)shelf != (Object)null)
{
AddItems(shelf.GetItemCompartmentList(), seen, itemTypes);
}
}
}
if (shelves.m_CardItemCombiShelfList != null)
{
foreach (CardItemCombiShelf cardItemCombiShelf in shelves.m_CardItemCombiShelfList)
{
if ((Object)(object)cardItemCombiShelf != (Object)null)
{
AddItems(cardItemCombiShelf.GetItemCompartmentList(), seen, itemTypes);
}
}
}
if (!Plugin.AutoPriceCards.Value)
{
return;
}
HashSet<string> seen2 = new HashSet<string>();
if (shelves.m_CardShelfList != null)
{
foreach (CardShelf cardShelf in shelves.m_CardShelfList)
{
AddCards(cardShelf, seen2, cardList);
}
}
if (shelves.m_CardItemCombiShelfList == null)
{
return;
}
foreach (CardItemCombiShelf cardItemCombiShelf2 in shelves.m_CardItemCombiShelfList)
{
AddCards((CardShelf)(object)cardItemCombiShelf2, seen2, cardList);
}
}
private static void AddItems(List<ShelfCompartment> compartments, HashSet<EItemType> seen, List<EItemType> itemTypes)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Invalid comparison between Unknown and I4
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
if (compartments == null)
{
return;
}
foreach (ShelfCompartment compartment in compartments)
{
if (!((Object)(object)compartment == (Object)null))
{
EItemType itemType = compartment.GetItemType();
if ((int)itemType >= 0 && seen.Add(itemType))
{
itemTypes.Add(itemType);
}
}
}
}
private static void AddCards(CardShelf shelf, HashSet<string> seen, List<CardData> cardList)
{
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)shelf == (Object)null)
{
return;
}
List<InteractableCardCompartment> cardCompartmentList = shelf.GetCardCompartmentList();
if (cardCompartmentList == null)
{
return;
}
foreach (InteractableCardCompartment item2 in cardCompartmentList)
{
if ((Object)(object)item2 == (Object)null || item2.m_StoredCardList == null)
{
continue;
}
foreach (InteractableCard3d storedCard in item2.m_StoredCardList)
{
CardData val = ((!((Object)(object)storedCard != (Object)null) || !((Object)(object)storedCard.m_Card3dUI != (Object)null) || !((Object)(object)storedCard.m_Card3dUI.m_CardUI != (Object)null)) ? null : storedCard.m_Card3dUI.m_CardUI.GetCardData());
if (val != null)
{
string item = $"{val.expansionType}|{val.monsterType}|{val.borderType}|{val.isFoil}|{val.isDestiny}|{val.cardGrade}|{val.gradedCardIndex}";
if (seen.Add(item))
{
cardList.Add(val);
}
}
}
}
}
private static float Round(float price)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Invalid comparison between Unknown and I4
if (Plugin.AutoPriceRound.Value)
{
float currencyConversionRate = GameInstance.GetCurrencyConversionRate();
CGameManager instance = CSingleton<CGameManager>.Instance;
price = ((!((Object)(object)instance != (Object)null) || (int)instance.m_CurrencyType != 2) ? ((float)Mathf.RoundToInt(price * currencyConversionRate)) : ((float)Mathf.RoundToInt(price * currencyConversionRate / 100f) * 100f));
price /= currencyConversionRate;
}
float currencyRoundDivideAmount = GameInstance.GetCurrencyRoundDivideAmount();
if (currencyRoundDivideAmount > 0f)
{
price = (float)Mathf.RoundToInt(price * currencyRoundDivideAmount) / currencyRoundDivideAmount;
}
return (!(price > 0f)) ? 0.5f : price;
}
}
internal static class Coop
{
internal const string OriginalId = "com.zwhit.cardshopcoop";
internal const string CommunityId = "dev.meepen.cardshopcoop";
private static bool looked;
private static PropertyInfo roleProperty;
private static PropertyInfo RoleProperty
{
get
{
if (!looked)
{
looked = true;
if (Chainloader.PluginInfos.ContainsKey("com.zwhit.cardshopcoop") || Chainloader.PluginInfos.ContainsKey("dev.meepen.cardshopcoop"))
{
roleProperty = AccessTools.TypeByName("CardShopCoop.CoopCore")?.GetProperty("Role", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (roleProperty == null)
{
Plugin.Log.LogWarning((object)"A co-op mod is installed but its session role couldn't be read; this mod acts as if every game is the host's.");
}
}
}
return roleProperty;
}
}
internal static bool IsGuest
{
[CompilerGenerated]
get
{
return Role() == "Client";
}
}
private static string Role()
{
PropertyInfo propertyInfo = RoleProperty;
if (propertyInfo == null)
{
return "None";
}
try
{
return propertyInfo.GetValue(null, null)?.ToString() ?? "None";
}
catch
{
return "None";
}
}
internal static string Describe()
{
if (Chainloader.PluginInfos.ContainsKey("dev.meepen.cardshopcoop"))
{
return "CardShopCoopCommunity";
}
if (Chainloader.PluginInfos.ContainsKey("com.zwhit.cardshopcoop"))
{
return "CardShopCoop";
}
return "none (solo)";
}
}
internal static class Customers
{
[HarmonyPatch(typeof(CustomerManager), "EvaluateMaxCustomerCount")]
internal static class Count
{
private static void Postfix(CustomerManager __instance)
{
if (!Coop.IsGuest)
{
float value = Plugin.CustomerCount.Value;
if (!(value <= 0f) && value != 1f)
{
__instance.m_CustomerCountMax = Mathf.Max(1, Mathf.RoundToInt((float)__instance.m_CustomerCountMax * value));
__instance.m_TimePerCustomer = Mathf.Max(0.5f, __instance.m_TimePerCustomer / value);
}
}
}
}
[HarmonyPatch(typeof(CustomerManager), "GetCustomerMaxMoney")]
internal static class Cash
{
private static void Postfix(ref float __result)
{
if (!Coop.IsGuest)
{
__result *= Plugin.CustomerCash.Value;
}
}
}
}
internal static class Smelly
{
[HarmonyPatch(typeof(Customer), "ActivateCustomer")]
internal static class SpawnRoll
{
private static void Prefix()
{
Spawning = true;
}
private static void Finalizer()
{
Spawning = false;
}
}
[HarmonyPatch(typeof(Customer), "SetSmelly")]
internal static class Roll
{
private static bool Prefix()
{
if (!Spawning || Coop.IsGuest)
{
return true;
}
float value = Plugin.SmellyChance.Value;
if (value >= 100f)
{
return true;
}
return Random.value * 100f < value;
}
}
[HarmonyPatch(typeof(Customer), "StenchLeaveCheck")]
internal static class Stench
{
private static bool Prefix(ref bool __result)
{
if (Plugin.StenchDrivesAway.Value || Coop.IsGuest)
{
return true;
}
__result = false;
return false;
}
}
internal static bool Spawning;
}
[HarmonyPatch(typeof(LightManager), "Update")]
internal static class DayLengthPatch
{
[HarmonyPriority(0)]
private static void Prefix(LightManager __instance, out float __state)
{
__state = -1f;
float value = Plugin.DayLength.Value;
if (!(value <= 0f) && value != 1f && !Coop.IsGuest)
{
__state = __instance.m_TimerLerpSpeed;
__instance.m_TimerLerpSpeed = __state / value;
}
}
private static void Finalizer(LightManager __instance, float __state)
{
if (__state >= 0f)
{
__instance.m_TimerLerpSpeed = __state;
}
}
}
internal static class Expansions
{
[HarmonyPatch(typeof(CPlayerData), "GetUnlockShopRoomCost")]
internal static class ShopRoom
{
private static void Postfix(ref float __result)
{
__result *= Plugin.ExpansionCost.Value;
}
}
[HarmonyPatch(typeof(CPlayerData), "GetUnlockWarehouseRoomCost")]
internal static class WarehouseRoom
{
private static void Postfix(ref float __result)
{
__result *= Plugin.ExpansionCost.Value;
}
}
[HarmonyPatch(typeof(ExpansionShopUIScreen), "Init")]
internal static class ShopScreen
{
private static void Prefix()
{
Apply(force: true);
}
}
private static UnlockRoomManager manager;
private static int managerId;
private static float gamePrice;
private static float appliedFactor = 1f;
private static float nextLook;
internal static void Apply(bool force)
{
if ((Object)(object)manager == (Object)null)
{
if (!force && Time.realtimeSinceStartup < nextLook)
{
return;
}
nextLook = Time.realtimeSinceStartup + 2f;
manager = Object.FindObjectOfType<UnlockRoomManager>();
if ((Object)(object)manager == (Object)null)
{
return;
}
}
if (((Object)manager).GetInstanceID() != managerId)
{
managerId = ((Object)manager).GetInstanceID();
gamePrice = manager.m_ShopB_UnlockPrice;
appliedFactor = 1f;
}
float value = Plugin.ExpansionCost.Value;
if (value != appliedFactor || force)
{
manager.m_ShopB_UnlockPrice = gamePrice * value;
appliedFactor = value;
}
}
}
internal static class Market
{
[HarmonyPatch(typeof(PriceChangeManager), "OnDayStarted")]
internal static class DailyChange
{
private static void Prefix()
{
Rolling = !Coop.IsGuest;
}
private static void Finalizer()
{
Rolling = false;
}
}
[HarmonyPatch(typeof(CPlayerData), "AddItemPricePercentChange")]
internal static class ItemSwing
{
[HarmonyPriority(800)]
private static void Prefix(ref float percentChange)
{
if (Rolling)
{
percentChange *= Plugin.PriceSwing.Value;
}
}
}
[HarmonyPatch(typeof(CPlayerData), "AddCardPricePercentChange")]
internal static class CardSwing
{
[HarmonyPriority(800)]
private static void Prefix(ref float percentChange)
{
if (Rolling)
{
percentChange *= Plugin.PriceSwing.Value;
}
}
}
[HarmonyPatch(typeof(PriceChangeManager), "EvaluatePriceCrash")]
internal static class Crashes
{
private static bool Prefix()
{
return Plugin.PriceCrashes.Value || Coop.IsGuest;
}
}
internal static bool Rolling;
}
[BepInPlugin("potato.shoptweaks", "Potato Shop Tweaks", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInProcess("Card Shop Simulator.exe")]
public sealed class Plugin : BaseUnityPlugin
{
public const string Id = "potato.shoptweaks";
public const string Version = "1.0.1";
internal static ManualLogSource Log;
internal static Plugin Instance;
internal static ConfigEntry<float> WorkerWorkSpeed;
internal static ConfigEntry<float> WorkerWalkSpeed;
internal static ConfigEntry<float> WorkerSalary;
internal static ConfigEntry<float> CustomerCount;
internal static ConfigEntry<float> CustomerCash;
internal static ConfigEntry<float> SmellyChance;
internal static ConfigEntry<bool> StenchDrivesAway;
internal static ConfigEntry<float> PriceSwing;
internal static ConfigEntry<bool> PriceCrashes;
internal static ConfigEntry<KeyboardShortcut> AutoPriceKey;
internal static ConfigEntry<float> AutoPriceMarkup;
internal static ConfigEntry<bool> AutoPriceRound;
internal static ConfigEntry<bool> AutoPriceCards;
internal static ConfigEntry<bool> AutoPriceEveryMorning;
internal static ConfigEntry<float> DayLength;
internal static ConfigEntry<float> ExpansionCost;
private Harmony harmony;
private static ConfigFile configFile;
private static FileSystemWatcher watcher;
private static volatile bool configChanged;
private static float reloadAt;
private void Awake()
{
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0241: Unknown result type (might be due to invalid IL or missing references)
//IL_024b: Expected O, but got Unknown
//IL_034d: Unknown result type (might be due to invalid IL or missing references)
//IL_0357: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Instance = this;
WorkerWorkSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Workers", "Work speed", 1f, Host("How fast hired workers restock, scan items and give change: 2 = twice as fast. 1 = the game's normal. Applies when a worker starts their shift or changes task.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f)));
WorkerWalkSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Workers", "Walk speed", 1f, Host("How fast hired workers walk: 1.5 = half again as fast. 1 = the game's normal. Applies when a worker starts their shift or changes task.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f)));
WorkerSalary = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Workers", "Salary", 1f, Shared("Multiplies what workers cost per day, in the hiring screen and on the daily bill: 0.5 = half pay, 0 = they work for free. 1 = the game's normal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f)));
CustomerCount = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Customers", "Customer count", 1f, Host("Multiplies how many customers can be in the shop at once and how often new ones arrive: 2 = twice as many, arriving twice as often. 1 = the game's normal. Applies on the next day, level-up or room unlock. A lot of customers can slow the game down.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 3f)));
CustomerCash = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Customers", "Customer cash", 1f, Host("Multiplies how much money each new customer can spend: 2 = twice as much. 1 = the game's normal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f)));
SmellyChance = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Smelly customers", "Smelly chance", 100f, Host("Percent of the game's chance that a new customer is smelly: 50 = half as many smelly customers, 0 = none. 100 = the game's normal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f)));
StenchDrivesAway = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Smelly customers", "Stench drives customers away", true, Host("On: the game's normal, other customers near a smelly one may leave and leave a bad review. Off: they don't mind the smell."));
PriceSwing = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Market prices", "Daily price swing", 1f, Host("Multiplies how far market prices of items and cards move each morning: 0.5 = half as much, 0 = prices never move, 2 = twice as wild. 1 = the game's normal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f)));
PriceCrashes = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Market prices", "Price crashes", true, Host("On: the game's normal, prices can sometimes crash or spike. Off: no crashes or spikes."));
AutoPriceKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("5 - Auto-pricing", "Hotkey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Press to set the price of everything on your shelves to its market price plus the markup below. In co-op only the host can use it (the new prices reach everyone). Personal.");
AutoPriceMarkup = ((BaseUnityPlugin)this).Config.Bind<float>("5 - Auto-pricing", "Markup percent", 10f, new ConfigDescription("Percent above market price: 10 = market price + 10%, 0 = exactly market price, -10 = 10% below. Personal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-50f, 200f), Array.Empty<object>()));
AutoPriceRound = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Auto-pricing", "Round prices", false, "Round each price to a whole amount, the way the workers' \"round up\" option does. Rounding can push cheap items far above market. Personal.");
AutoPriceCards = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Auto-pricing", "Include cards", true, "Also price the cards on your card shelves. Personal.");
AutoPriceEveryMorning = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Auto-pricing", "Every morning", false, "Also auto-price every morning, right after the market moves. Host or solo only. Personal.");
DayLength = ((BaseUnityPlugin)this).Config.Bind<float>("6 - Day length", "Day length", 1f, Host("Multiplies how long a shop day lasts in real time: 2 = days last twice as long (the clock runs at half speed). Customers keep arriving at their usual pace, so a longer day brings more of them. 1 = the game's normal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 4f)));
ExpansionCost = ((BaseUnityPlugin)this).Config.Bind<float>("7 - Expansions", "Expansion cost", 1f, Shared("Multiplies the cost of shop rooms, warehouse rooms and shop lot B: 0.5 = half price. 1 = the game's normal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f)));
ExpansionCost.SettingChanged += delegate
{
Expansions.Apply(force: true);
};
harmony = new Harmony("potato.shoptweaks");
Type[] array = new Type[18]
{
typeof(Workers.Speed),
typeof(Workers.SalaryTotal),
typeof(Workers.SalaryText),
typeof(Workers.SalaryScreen),
typeof(Customers.Count),
typeof(Customers.Cash),
typeof(Smelly.SpawnRoll),
typeof(Smelly.Roll),
typeof(Smelly.Stench),
typeof(Market.DailyChange),
typeof(Market.ItemSwing),
typeof(Market.CardSwing),
typeof(Market.Crashes),
typeof(AutoPrice.Morning),
typeof(DayLengthPatch),
typeof(Expansions.ShopRoom),
typeof(Expansions.WarehouseRoom),
typeof(Expansions.ShopScreen)
};
foreach (Type type in array)
{
Patch(type);
}
WatchConfigFile();
Runner.Ensure();
Log.LogInfo((object)string.Format("Potato Shop Tweaks {0} loaded. Co-op mod: {1}.", "1.0.1", Coop.Describe()));
}
private void WatchConfigFile()
{
configFile = ((BaseUnityPlugin)this).Config;
try
{
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath));
fileSystemWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;
watcher = fileSystemWatcher;
watcher.Changed += delegate
{
configChanged = true;
};
watcher.Created += delegate
{
configChanged = true;
};
watcher.Renamed += delegate
{
configChanged = true;
};
watcher.EnableRaisingEvents = true;
}
catch (Exception ex)
{
Log.LogWarning((object)("Settings won't reload while the game runs: " + ex.Message));
}
}
internal static void CheckConfigReload()
{
if (!configChanged)
{
return;
}
if (reloadAt == 0f)
{
reloadAt = Time.realtimeSinceStartup + 1f;
}
else if (!(Time.realtimeSinceStartup < reloadAt))
{
configChanged = false;
reloadAt = 0f;
try
{
configFile.Reload();
Toast("Potato Shop Tweaks: settings reloaded.");
}
catch (Exception ex)
{
Log.LogWarning((object)("Couldn't reload settings: " + ex.Message));
}
}
}
private static ConfigDescription Host(string text, AcceptableValueBase range = null)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
return new ConfigDescription(text + " In co-op the host's setting counts.", range, Array.Empty<object>());
}
private static ConfigDescription Shared(string text, AcceptableValueBase range = null)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
return new ConfigDescription(text + " In co-op the host's setting is what's charged; keep it the same on every player's game so menus show the same prices.", range, Array.Empty<object>());
}
private void Patch(Type type)
{
try
{
harmony.CreateClassProcessor(type).Patch();
}
catch (Exception ex)
{
Log.LogError((object)$"{type.Name} is disabled: {ex.GetBaseException().Message}");
}
}
private void Start()
{
Runner.Ensure();
}
internal static void Toast(string text)
{
Runner.Toast(text);
}
}
internal sealed class Runner : MonoBehaviour
{
private static Runner instance;
private static string toast;
private static float toastUntil;
private static GUIStyle toastStyle;
internal static Runner Ensure()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
if ((Object)(object)instance != (Object)null)
{
return instance;
}
GameObject val = new GameObject("PotatoShopTweaks");
Object.DontDestroyOnLoad((Object)(object)val);
((Object)val).hideFlags = (HideFlags)61;
instance = val.AddComponent<Runner>();
return instance;
}
internal static void Toast(string text)
{
toast = text;
toastUntil = Time.realtimeSinceStartup + 4f;
Plugin.Log.LogInfo((object)text);
}
private void Update()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
try
{
Plugin.CheckConfigReload();
KeyboardShortcut value = Plugin.AutoPriceKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
AutoPrice.Run("hotkey");
}
Expansions.Apply(force: false);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Update: " + ex));
}
}
private void OnGUI()
{
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
if (toast != null && !(Time.realtimeSinceStartup > toastUntil))
{
if (toastStyle == null)
{
GUIStyle val = new GUIStyle(GUI.skin.box);
val.fontSize = 20;
val.alignment = (TextAnchor)4;
val.wordWrap = true;
toastStyle = val;
toastStyle.normal.textColor = Color.white;
}
float num = Mathf.Min(700f, (float)Screen.width - 40f);
GUI.Box(new Rect(((float)Screen.width - num) / 2f, 60f, num, 48f), toast, toastStyle);
}
}
}
internal static class Workers
{
internal struct Stats
{
public float Restock;
public float Scan;
public float Change;
public float Walk;
}
[HarmonyPatch]
internal static class Speed
{
private static IEnumerable<MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(Worker), "EvaluateWorkerAttribute", (Type[])null, (Type[])null);
yield return AccessTools.Method(typeof(Worker), "EvaluateTaskLevelStat", (Type[])null, (Type[])null);
}
private static void Prefix(Worker __instance, out Stats __state)
{
__state = Read(__instance);
}
private static void Postfix(Worker __instance, Stats __state)
{
if (Coop.IsGuest)
{
return;
}
Stats stats = Read(__instance);
float value = Plugin.WorkerWorkSpeed.Value;
float value2 = Plugin.WorkerWalkSpeed.Value;
if (value > 0f && value != 1f)
{
if (stats.Restock != __state.Restock)
{
__instance.m_RestockTime = stats.Restock / value;
}
if (stats.Scan != __state.Scan)
{
__instance.m_ScanItemTime = stats.Scan / value;
}
if (stats.Change != __state.Change)
{
__instance.m_GiveChangeTime = stats.Change / value;
}
}
if (value2 > 0f && value2 != 1f && stats.Walk != __state.Walk)
{
SetWalk(__instance, stats.Walk * value2);
}
}
private static Stats Read(Worker w)
{
return new Stats
{
Restock = w.m_RestockTime,
Scan = w.m_ScanItemTime,
Change = w.m_GiveChangeTime,
Walk = GetWalk(w)
};
}
}
[HarmonyPatch(typeof(WorkerManager), "EvaluateSalaryCost")]
internal static class SalaryTotal
{
private static void Postfix(WorkerManager __instance)
{
float value = Plugin.WorkerSalary.Value;
if (value != 1f)
{
__instance.m_TotalSalaryCost *= value;
}
}
}
[HarmonyPatch(typeof(WorkerData), "GetSalaryCostText")]
internal static class SalaryText
{
private static void Prefix(WorkerData __instance, out float __state)
{
if (Scaled.IsScaled(__instance))
{
__state = float.NaN;
return;
}
__state = __instance.costPerDay;
__instance.costPerDay *= Plugin.WorkerSalary.Value;
}
private static void Finalizer(WorkerData __instance, float __state)
{
if (!float.IsNaN(__state))
{
__instance.costPerDay = __state;
}
}
}
[HarmonyPatch(typeof(WorkerInteractUIScreen), "OpenScreen")]
internal static class SalaryScreen
{
private static void Prefix(Worker worker, out WorkerData __state)
{
__state = ((!((Object)(object)worker != (Object)null)) ? null : worker.GetWorkerData());
if (__state != null)
{
Scaled.Push(__state);
}
}
private static void Finalizer(WorkerData __state)
{
if (__state != null)
{
Scaled.Pop(__state);
}
}
}
private static class Scaled
{
private static readonly Dictionary<WorkerData, float> originals = new Dictionary<WorkerData, float>();
internal static bool IsScaled(WorkerData data)
{
return originals.ContainsKey(data);
}
internal static void Push(WorkerData data)
{
if (!originals.ContainsKey(data))
{
originals[data] = data.costPerDay;
data.costPerDay *= Plugin.WorkerSalary.Value;
}
}
internal static void Pop(WorkerData data)
{
if (originals.TryGetValue(data, out var value))
{
data.costPerDay = value;
originals.Remove(data);
}
}
}
private static readonly FieldInfo ExtraSpeedField = AccessTools.Field(typeof(Worker), "m_ExtraSpeedMultiplier");
private static float GetWalk(Worker w)
{
return (float)ExtraSpeedField.GetValue(w);
}
private static void SetWalk(Worker w, float value)
{
ExtraSpeedField.SetValue(w, value);
}
}