using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using Eremite;
using Eremite.Buildings;
using Eremite.Characters;
using Eremite.Services;
using Eremite.Services.Monitors;
using HarmonyLib;
using UniRx;
[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 = "")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("IdleNotify")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Idle Worker Notification Mod for Against The Storm")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("IdleNotify")]
[assembly: AssemblyTitle("IdleNotify")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
namespace IdleNotify
{
internal class IdleBuildingMonitor : GameMonitor
{
private Dictionary<ProductionBuilding, MonitorAlert> current = new Dictionary<ProductionBuilding, MonitorAlert>();
private Dictionary<ProductionBuilding, float> queue = new Dictionary<ProductionBuilding, float>();
public override bool IsEnabled()
{
return true;
}
public override void OnInit()
{
DisposableExtensions.AddTo<IDisposable>(ObservableExtensions.Subscribe<Building>(Observable.Where<Building>((IObservable<Building>)Serviceable.GameBlackboardService.FinishedBuildingRemoved, (Func<Building, bool>)((Building building) => building is ProductionBuilding)), (Action<Building>)ProductionBuildingRemoved), (ICollection<IDisposable>)base.disposables);
}
private void ProductionBuildingRemoved(Building building)
{
ProductionBuilding building2 = (ProductionBuilding)(object)((building is ProductionBuilding) ? building : null);
if (IsShowing(building2))
{
HideAlert(building2);
}
}
public override void OnSlowUpdate()
{
foreach (ProductionBuilding productionBuilding in Serviceable.BuildingsService.ProductionBuildings)
{
if (((Building)productionBuilding).IsFinished())
{
UpdateBuilding(productionBuilding);
}
}
}
private void UpdateBuilding(ProductionBuilding building)
{
CheckForDequeue(building);
CheckForQueue(building);
CheckForHiding(building);
CheckForShowing(building);
}
private void CheckForDequeue(ProductionBuilding building)
{
if (IsQueued(building) && !IsBuildingIdle(building))
{
queue.Remove(building);
}
}
private void CheckForQueue(ProductionBuilding building)
{
if (!IsShowing(building) && !IsQueued(building) && IsBuildingIdle(building))
{
queue.Add(building, Serviceable.GameTime);
}
}
private void CheckForHiding(ProductionBuilding building)
{
if (IsShowing(building) && (!((GameMonitor)this).IsEnabled() || !IsBuildingIdle(building)))
{
HideAlert(building);
}
}
private void CheckForShowing(ProductionBuilding building)
{
if (!IsShowing(building) && IsQueued(building) && ((GameMonitor)this).IsEnabled() && ShouldShow(building))
{
ShowAlert(building, CreateAlert(building));
}
}
private void ShowAlert(ProductionBuilding building, MonitorAlert alert)
{
current.Add(building, alert);
((GameMonitor)this).AddAlert(alert);
}
private void HideAlert(ProductionBuilding building)
{
((GameMonitor)this).RemoveAlert(current[building]);
current.Remove(building);
}
private MonitorAlert CreateAlert(ProductionBuilding building)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Expected O, but got Unknown
return new MonitorAlert
{
severity = (AlertSeverity)2,
text = $"Worker idle in {((Building)building).BuildingModel.displayName}",
description = $"At least one worker is idle in your {((Building)building).BuildingModel.displayName}. Click here to go to it.",
showTime = ((GameMonitor)this).GetShowTime(),
clickCallback = OnAlertClicked
};
}
private void OnAlertClicked(MonitorAlert alert)
{
Focus(current.First((KeyValuePair<ProductionBuilding, MonitorAlert> a) => a.Value == alert).Key);
}
private void Focus(ProductionBuilding building)
{
Serviceable.GameInputService.Focus((IMapObject)(object)building, true);
}
private bool IsShowing(ProductionBuilding building)
{
return current.ContainsKey(building);
}
private bool IsBuildingIdle(ProductionBuilding building)
{
return building.IsBuildingIdle();
}
private bool IsQueued(ProductionBuilding building)
{
return queue.ContainsKey(building);
}
private bool ShouldShow(ProductionBuilding building)
{
return Serviceable.GameTime - queue[building] >= 0f;
}
}
[BepInPlugin("IdleNotify", "IdleNotify", "1.0.1")]
public class Plugin : BaseUnityPlugin
{
public static Plugin Instance;
private Harmony harmony;
public static void Log(string str)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)str);
}
private void Awake()
{
Instance = this;
harmony = Harmony.CreateAndPatchAll(typeof(Plugin), (string)null);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin IdleNotify is loaded!");
}
[HarmonyPatch(typeof(MonitorsService), "CreateMonitors")]
[HarmonyPostfix]
private static void MonitorsService_CreateMonitors_Postfix(MonitorsService __instance)
{
__instance.monitors = __instance.monitors.Concat((IEnumerable<GameMonitor>)(object)new GameMonitor[1]
{
new IdleBuildingMonitor()
}).ToArray();
}
[HarmonyPatch(typeof(ProductionBuilding), "IsBuildingIdle")]
[HarmonyPrefix]
private static bool ProductionBuilding_IsBuildingIdle_Prefix(ProductionBuilding __instance, ref bool __result)
{
bool flag = false;
int[] workers = __instance.Workers;
foreach (int num in workers)
{
if (GameMB.ActorsService.HasActor(num))
{
Actor actor = GameMB.ActorsService.GetActor(num);
if (!actor.IsBoundToWorkplace && !actor.ActorState.isWorking)
{
flag = true;
break;
}
}
}
if (!flag)
{
__instance.ProductionBuildingState.idleTime = 0f;
__result = false;
return false;
}
ProductionBuildingState productionBuildingState = __instance.ProductionBuildingState;
productionBuildingState.idleTime += ((Building)__instance).GetSlowDeltaTime();
__result = __instance.ProductionBuildingState.idleTime > 0.2f;
return false;
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "IdleNotify";
public const string PLUGIN_NAME = "IdleNotify";
public const string PLUGIN_VERSION = "1.0.1";
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}