using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using SSSGame;
using SSSGame.Vegetation;
using SSSGame.Weather;
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("AlwaysBeSearchin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1+35bcb3c0e2c107c02f6a130e147a0c9fb212ab1d")]
[assembly: AssemblyProduct("AlwaysBeSearchin")]
[assembly: AssemblyTitle("AlwaysBeSearchin")]
[assembly: AssemblyVersion("0.1.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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 AlwaysBeSearchin
{
public class AlwaysOnGlow : MonoBehaviour
{
private static readonly int ValueId = Shader.PropertyToID("Global_ResFinderValue");
private static readonly int RadiusId = Shader.PropertyToID("Global_ResFinderRadius");
private static readonly int ColorId = Shader.PropertyToID("Global_ResFinderColor");
internal static bool RoutineActive;
internal static float RoutineDeadline;
private PlayerInteractionAgent _agent;
private float _nextAgentLookup;
private SettingsManager _settings;
private bool _wasGameTurn;
private bool _zeroWritten;
private string _parsedFrom;
private bool _hasOurColor;
private Vector4 _ourColor;
private MaterialPropertyBlock _mpb;
private bool _wasExcluding;
private int _cursor = -1;
private float _nextCharLog;
private double _worstFrameMs;
private double _worstLookupMs;
private double _worstWriteMs;
private WeatherSystem _weather;
private float _nextWeatherLookup;
private float _nextStrengthLog;
private bool _weatherFailed;
private readonly Dictionary<int, (bool overrideOn, float strength)> _plantOriginals = new Dictionary<int, (bool, float)>();
private float _nextPlantPass;
private float _lastPlantStrength = float.NaN;
private string _lastPlantTypes;
private string _lastBoostTypes;
private float _lastBoostStrength = float.NaN;
private bool _plantsLogged;
private bool _updateFailed;
private bool _lateFailed;
private bool _colorFailed;
private bool _villagerFailed;
private bool _plantFailed;
private const int KindCount = 4;
private const int RendererBudget = 150;
private const int MaxVisits = 200;
private const float CacheSeconds = 10f;
private readonly bool[] _kindOn = new bool[4];
private readonly Queue<Known> _restore = new Queue<Known>();
private Known _cur;
private int _seedStep = -1;
private long _frameSeedTicks;
private const int ModeNone = 0;
private const int ModeZero = 1;
private const int ModeValue = 2;
private const int ModeClear = 3;
public AlwaysOnGlow(IntPtr ptr)
: base(ptr)
{
}
private void Update()
{
try
{
if (RoutineActive && Time.time > RoutineDeadline)
{
RoutineActive = false;
}
}
catch (Exception ex)
{
if (_updateFailed)
{
return;
}
_updateFailed = true;
Plugin.Logger.LogWarning((object)("Update failed: " + ex));
}
try
{
TickPlants();
}
catch (Exception ex2)
{
if (!_plantFailed)
{
_plantFailed = true;
Plugin.Logger.LogWarning((object)("Plant strength failed: " + ex2));
}
}
}
private void TickPlants()
{
//IL_022f: Unknown result type (might be due to invalid IL or missing references)
//IL_0236: Expected O, but got Unknown
float time = Time.time;
float value = Plugin.PlantStrength.Value;
string value2 = Plugin.PlantTypes.Value;
string value3 = Plugin.BoostTypes.Value;
float value4 = Plugin.BoostStrength.Value;
if (value == _lastPlantStrength && string.Equals(value2, _lastPlantTypes, StringComparison.Ordinal) && string.Equals(value3, _lastBoostTypes, StringComparison.Ordinal) && value4 == _lastBoostStrength && time < _nextPlantPass)
{
return;
}
_nextPlantPass = time + 5f;
_lastPlantStrength = value;
_lastPlantTypes = value2;
_lastBoostTypes = value3;
_lastBoostStrength = value4;
VegetationVFXAddon instance = VegetationVFXAddon.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
List<VFXItemRenderer> vfxRenderers = instance._vfxRenderers;
if (vfxRenderers == null)
{
return;
}
HashSet<int> hashSet = new HashSet<int>();
List<string> list = new List<string>();
int num = 0;
HashSet<int> hashSet2 = new HashSet<int>();
int count = vfxRenderers.Count;
for (int i = 0; i < count; i++)
{
VFXItemRenderer val = vfxRenderers[i];
VFXVegetationConfig val2 = ((val != null) ? val.Profile : null);
if ((Object)(object)val2 == (Object)null)
{
continue;
}
int instanceID = ((Object)val2).GetInstanceID();
if (!_plantOriginals.TryGetValue(instanceID, out (bool, float) value5))
{
value5 = (val2.overrideHighlightStrength, val2.highlightStrength);
_plantOriginals[instanceID] = value5;
}
float num2 = GlowMath.TypeMultiplier(((Object)val2).name, value5.Item2, value2, value, value3, value4);
bool flag = num2 != value5.Item2;
bool flag2 = flag || value5.Item1;
if (hashSet.Add(instanceID) && flag)
{
if (num2 > value5.Item2)
{
list.Add(((Object)val2).name);
}
else
{
num++;
}
}
if (val2.overrideHighlightStrength != flag2 || val2.highlightStrength != num2)
{
val2.overrideHighlightStrength = flag2;
val2.highlightStrength = num2;
hashSet2.Add(instanceID);
}
if (hashSet2.Contains(instanceID))
{
val._UpdateHighlightStrength();
}
}
if (!_plantsLogged && count > 0)
{
_plantsLogged = true;
ManualLogSource logger = Plugin.Logger;
bool flag3 = default(bool);
BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(49, 4, ref flag3);
if (flag3)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("vegetation types scaled: ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" dimmed, ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(list.Count);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" boosted of ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(hashSet.Count);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" (");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(string.Join(", ", list.GetRange(0, Math.Min(20, list.Count))));
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")");
}
logger.LogInfo(val3);
}
}
private void LateUpdate()
{
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)_agent == (Object)null)
{
float time = Time.time;
if (time < _nextAgentLookup)
{
return;
}
_nextAgentLookup = time + 2f;
_agent = Object.FindObjectOfType<PlayerInteractionAgent>();
if ((Object)(object)_agent == (Object)null)
{
return;
}
_seedStep = 0;
}
if (_seedStep >= 0)
{
TickSeed();
}
float num = CurrentBaseline();
float globalFloat = Shader.GetGlobalFloat(ValueId);
if (GlowMath.GameHasTurn(RoutineActive, globalFloat, num))
{
if (!_wasGameTurn)
{
Shader.SetGlobalVector(ColorId, PlayerColor());
}
_wasGameTurn = true;
_zeroWritten = false;
}
else if (num <= 0f)
{
if (_wasGameTurn || !_zeroWritten)
{
Shader.SetGlobalFloat(ValueId, 0f);
}
_wasGameTurn = false;
_zeroWritten = true;
}
else
{
Shader.SetGlobalFloat(ValueId, num);
Shader.SetGlobalFloat(RadiusId, Plugin.GlowRadius.Value);
Shader.SetGlobalVector(ColorId, CurrentColor());
_wasGameTurn = false;
_zeroWritten = false;
}
TickCharacters(GlowMath.ExcludeKindNow(num, Plugin.ExcludeVillagers.Value), GlowMath.ExcludeKindNow(num, Plugin.ExcludeStructures.Value));
}
catch (Exception ex)
{
if (!_lateFailed)
{
_lateFailed = true;
Plugin.Logger.LogWarning((object)("LateUpdate failed: " + ex));
}
}
}
private float CurrentBaseline()
{
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Expected O, but got Unknown
float num = 1f;
float num2 = float.NaN;
bool flag = false;
try
{
float time = Time.time;
if ((Object)(object)_weather == (Object)null && time >= _nextWeatherLookup)
{
_nextWeatherLookup = time + 2f;
_weather = Object.FindObjectOfType<WeatherSystem>();
flag = (Object)(object)_weather != (Object)null;
}
if ((Object)(object)_weather != (Object)null)
{
num = _weather.DayNightValue;
num2 = _weather.narmalizedDayTime;
}
}
catch (Exception ex)
{
if (!_weatherFailed)
{
_weatherFailed = true;
Plugin.Logger.LogWarning((object)("Reading the day and night failed: " + ex));
}
}
float num3 = GlowMath.DayNightStrength(Plugin.DayStrength.Value, Plugin.NightStrength.Value, num);
if ((Object)(object)_weather != (Object)null && (flag || Time.time >= _nextStrengthLog))
{
_nextStrengthLog = Time.time + 60f;
ManualLogSource logger = Plugin.Logger;
bool flag2 = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 3, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("daylight ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "0.###");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" time ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num2, "0.###");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" strength ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num3, "0.###");
}
logger.LogInfo(val);
}
return num3;
}
private Vector4 CurrentColor()
{
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
string value = Plugin.GlowColor.Value;
if (!string.Equals(value, _parsedFrom, StringComparison.Ordinal))
{
_parsedFrom = value;
if (GlowMath.TryParseHexColor(value, out var r, out var g, out var b))
{
_ourColor = new Vector4(r, g, b, 1f);
_hasOurColor = true;
}
else
{
_hasOurColor = false;
if (!string.IsNullOrEmpty(value))
{
ManualLogSource logger = Plugin.Logger;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(68, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("GlowColor '");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(value);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is not #RRGGBB; using the game's Resource Finder color.");
}
logger.LogWarning(val);
}
}
}
if (!_hasOurColor)
{
return PlayerColor();
}
return _ourColor;
}
private Vector4 PlayerColor()
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: 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: 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_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)_settings == (Object)null)
{
_settings = Object.FindObjectOfType<SettingsManager>();
}
if ((Object)(object)_settings != (Object)null)
{
Color value = _settings.ResourceFinderColor.Value;
return new Vector4(value.r, value.g, value.b, 1f);
}
}
catch (Exception ex)
{
if (!_colorFailed)
{
_colorFailed = true;
Plugin.Logger.LogWarning((object)("Reading the Resource Finder color failed: " + ex));
}
}
return new Vector4(1f, 1f, 1f, 1f);
}
private static bool KindExcluded(int kind, bool characters, bool structures)
{
if (kind != 3)
{
return characters;
}
return structures;
}
private static double Ms(long ticks)
{
return (double)ticks * 1000.0 / (double)Stopwatch.Frequency;
}
private void TickSeed()
{
long timestamp = Stopwatch.GetTimestamp();
int seedStep = _seedStep;
_seedStep = ((seedStep + 1 >= 4) ? (-1) : (seedStep + 1));
switch (seedStep)
{
case 0:
foreach (Villager item in Object.FindObjectsOfType<Villager>())
{
GlowRegistry.Seed((Component)(object)item, 0);
}
break;
case 1:
foreach (PlayerCharacter item2 in Object.FindObjectsOfType<PlayerCharacter>())
{
GlowRegistry.Seed((Component)(object)item2, 1);
}
break;
case 2:
foreach (Creature item3 in Object.FindObjectsOfType<Creature>())
{
GlowRegistry.Seed((Component)(object)item3, 2);
}
break;
default:
foreach (Structure item4 in Object.FindObjectsOfType<Structure>())
{
GlowRegistry.Seed((Component)(object)item4, 3);
}
break;
}
_frameSeedTicks += Stopwatch.GetTimestamp() - timestamp;
}
private void TickCharacters(bool characters, bool structures)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Expected O, but got Unknown
//IL_0298: Unknown result type (might be due to invalid IL or missing references)
//IL_029f: Expected O, but got Unknown
bool flag = characters || structures;
if (!flag && !_wasExcluding && _restore.Count == 0 && _cur == null)
{
_frameSeedTicks = 0L;
return;
}
try
{
float time = Time.time;
Stopwatch stopwatch = Stopwatch.StartNew();
if (_mpb == null)
{
_mpb = new MaterialPropertyBlock();
}
bool flag2 = !_wasExcluding;
for (int i = 0; i < 4; i++)
{
bool flag3 = KindExcluded(i, characters, structures);
if (_kindOn[i] && !flag3)
{
foreach (Known item in GlowRegistry.List)
{
if (item.Kind == i && !item.Removed && (item.Touched || item.Excluded))
{
item.Restoring = true;
_restore.Enqueue(item);
}
}
}
else if (!_kindOn[i] && flag3)
{
foreach (Known item2 in GlowRegistry.List)
{
if (item2.Kind == i && !item2.Removed)
{
GlowRegistry.Fresh.Enqueue(item2);
}
}
}
_kindOn[i] = flag3;
}
_wasExcluding = flag;
if (flag2 && flag)
{
_nextCharLog = time + 60f;
}
long num = _frameSeedTicks + GlowRegistry.TakeTicks();
long lookupTicks = num;
long writeTicks = 0L;
_frameSeedTicks = 0L;
RunBudget(time, flag, ref lookupTicks, ref writeTicks);
stopwatch.Stop();
double val = Ms(lookupTicks);
double val2 = Ms(writeTicks);
_worstFrameMs = Math.Max(_worstFrameMs, stopwatch.Elapsed.TotalMilliseconds + Ms(num));
_worstLookupMs = Math.Max(_worstLookupMs, val);
_worstWriteMs = Math.Max(_worstWriteMs, val2);
if (!flag || !(time >= _nextCharLog))
{
return;
}
_nextCharLog = time + 60f;
int[] array = new int[4];
foreach (Known item3 in GlowRegistry.List)
{
if (!item3.Removed && _kindOn[item3.Kind])
{
array[item3.Kind]++;
}
}
ManualLogSource logger = Plugin.Logger;
bool flag4 = default(bool);
BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(131, 10, ref flag4);
if (flag4)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("excluded from glow: ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(array[0]);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" villagers, ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(array[1]);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" players, ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(array[2]);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" creatures, ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(array[3]);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" structures; worst frame ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<double>(_worstFrameMs, "0.00");
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" ms (lookup ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<double>(_worstLookupMs, "0.00");
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", write ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<double>(_worstWriteMs, "0.00");
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("), seeded ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(GlowRegistry.Seeded);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", spawned ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(GlowRegistry.SpawnedCount);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", despawned ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(GlowRegistry.DespawnedCount);
}
logger.LogInfo(val3);
_worstFrameMs = 0.0;
_worstLookupMs = 0.0;
_worstWriteMs = 0.0;
}
catch (Exception ex)
{
_wasExcluding = flag;
_cur = null;
for (int j = 0; j < 4; j++)
{
_kindOn[j] = KindExcluded(j, characters, structures);
}
if (!_villagerFailed)
{
_villagerFailed = true;
Plugin.Logger.LogWarning((object)("Glow exclusion failed: " + ex));
}
}
}
[HideFromIl2Cpp]
private void RunBudget(float now, bool anyOn, ref long lookupTicks, ref long writeTicks)
{
int num = 150;
int visits = 0;
bool flag = false;
float globalFloat = Shader.GetGlobalFloat(ValueId);
while (num > 0 && visits < 200)
{
if (_cur == null)
{
long timestamp = Stopwatch.GetTimestamp();
_cur = NextKnown(anyOn, ref visits);
lookupTicks += Stopwatch.GetTimestamp() - timestamp;
if (_cur == null)
{
break;
}
_cur.Index = 0;
}
Known cur = _cur;
if (cur.Removed || (Object)(object)cur.Comp == (Object)null)
{
GlowRegistry.Drop(cur);
_cur = null;
continue;
}
if (cur.Index == 0)
{
if (cur.Rends == null || now - cur.RendTime > 10f)
{
if (flag)
{
break;
}
flag = true;
long timestamp2 = Stopwatch.GetTimestamp();
cur.Rends = Il2CppArrayBase<Renderer>.op_Implicit(cur.Comp.GetComponentsInChildren<Renderer>(true));
cur.RendTime = now;
lookupTicks += Stopwatch.GetTimestamp() - timestamp2;
}
cur.Mode = ModeFor(cur, globalFloat);
}
long timestamp3 = Stopwatch.GetTimestamp();
Renderer[] rends = cur.Rends;
int num2 = ((cur.Mode != 0) ? GlowMath.TakeBudget(rends.Length - cur.Index, num) : 0);
for (int i = 0; i < num2; i++)
{
Renderer val = rends[cur.Index + i];
if (!((Object)(object)val == (Object)null))
{
if (cur.Mode == 3)
{
val.SetPropertyBlock((MaterialPropertyBlock)null);
continue;
}
val.GetPropertyBlock(_mpb);
_mpb.SetFloat(ValueId, (cur.Mode == 1) ? 0f : globalFloat);
val.SetPropertyBlock(_mpb);
}
}
writeTicks += Stopwatch.GetTimestamp() - timestamp3;
cur.Index += num2;
num -= num2;
if (cur.Mode == 0 || cur.Index >= rends.Length)
{
cur.Restoring = false;
cur.Index = 0;
_cur = null;
}
}
}
[HideFromIl2Cpp]
private static int ModeFor(Known k, float global)
{
bool flag = !k.Restoring;
if (k.Kind != 2)
{
if (flag)
{
k.Touched = true;
return 1;
}
if (!k.Touched)
{
return 0;
}
k.Touched = false;
return 2;
}
Creature val = ((Il2CppObjectBase)k.Comp).TryCast<Creature>();
if ((Object)(object)val == (Object)null)
{
return 0;
}
if (GlowMath.ExcludeCreature(flag, val.IsDead))
{
k.Excluded = true;
return 1;
}
if (!k.Excluded)
{
return 0;
}
k.Excluded = false;
if (!val.IsDead)
{
return 2;
}
return 3;
}
[HideFromIl2Cpp]
private Known NextKnown(bool anyOn, ref int visits)
{
while (_restore.Count > 0)
{
Known known = _restore.Dequeue();
if (!known.Removed)
{
return known;
}
}
if (!anyOn)
{
return null;
}
Queue<Known> fresh = GlowRegistry.Fresh;
while (fresh.Count > 0 && visits < 200)
{
visits++;
Known known2 = fresh.Dequeue();
if (!known2.Removed && _kindOn[known2.Kind])
{
return known2;
}
}
List<Known> list = GlowRegistry.List;
while (list.Count > 0 && visits < 200)
{
visits++;
_cursor = (_cursor + 1) % list.Count;
Known known3 = list[_cursor];
if (known3.Removed || (Object)(object)known3.Comp == (Object)null)
{
GlowRegistry.Drop(known3);
list.RemoveAt(_cursor);
_cursor--;
}
else if (_kindOn[known3.Kind])
{
return known3;
}
}
return null;
}
}
internal sealed class Known
{
public int Kind;
public int Id;
public Component Comp;
public bool Excluded;
public bool Touched;
public bool Removed;
public bool Restoring;
public Renderer[] Rends;
public float RendTime;
public int Index;
public int Mode;
}
internal static class GlowRegistry
{
internal static readonly List<Known> List = new List<Known>();
internal static readonly Queue<Known> Fresh = new Queue<Known>();
private static readonly Dictionary<int, Known> ById = new Dictionary<int, Known>();
private static long _ticks;
internal static int Seeded;
internal static int SpawnedCount;
internal static int DespawnedCount;
internal static long TakeTicks()
{
long ticks = _ticks;
_ticks = 0L;
return ticks;
}
private static bool Add(Component c, int kind)
{
if ((Object)(object)c == (Object)null)
{
return false;
}
int instanceID = ((Object)c).GetInstanceID();
if (ById.ContainsKey(instanceID))
{
return false;
}
Known known = new Known
{
Kind = kind,
Id = instanceID,
Comp = c
};
List.Add(known);
ById[instanceID] = known;
Fresh.Enqueue(known);
return true;
}
internal static void Seed(Component c, int kind)
{
if (Add(c, kind))
{
Seeded++;
}
}
internal static void Spawned(Component c, int kind)
{
long timestamp = Stopwatch.GetTimestamp();
if (Add(c, kind))
{
SpawnedCount++;
}
_ticks += Stopwatch.GetTimestamp() - timestamp;
}
internal static void Despawned(Component c)
{
long timestamp = Stopwatch.GetTimestamp();
if ((Object)(object)c != (Object)null && ById.TryGetValue(((Object)c).GetInstanceID(), out var value))
{
Drop(value);
DespawnedCount++;
}
_ticks += Stopwatch.GetTimestamp() - timestamp;
}
internal static void Drop(Known k)
{
k.Removed = true;
if (ById.TryGetValue(k.Id, out var value) && value == k)
{
ById.Remove(k.Id);
}
}
}
[HarmonyPatch]
internal static class GlowPatches
{
private static bool _pressFailed;
private static bool _routineFailed;
private static int _spawnedHooks = -1;
private static int _despawnedHooks = -1;
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerInteractionAgent), "ActivateResourceFinder")]
private static void Press(PlayerInteractionAgent __instance)
{
try
{
AlwaysOnGlow.RoutineActive = true;
AlwaysOnGlow.RoutineDeadline = Time.time + __instance.finderActiveTime + __instance.finderFadeOutTime + 1f;
}
catch (Exception ex)
{
if (!_pressFailed)
{
_pressFailed = true;
Plugin.Logger.LogWarning((object)("ActivateResourceFinder patch failed: " + ex));
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(__ResourceFinderRoutine_d__189), "MoveNext")]
private static void Routine(bool __result)
{
try
{
if (!__result)
{
AlwaysOnGlow.RoutineActive = false;
}
}
catch (Exception ex)
{
if (!_routineFailed)
{
_routineFailed = true;
Plugin.Logger.LogWarning((object)("Resource Finder routine patch failed: " + ex));
}
}
}
internal static int KindOf(Component c)
{
if ((Object)(object)((Il2CppObjectBase)c).TryCast<Villager>() != (Object)null)
{
return 0;
}
if ((Object)(object)((Il2CppObjectBase)c).TryCast<PlayerCharacter>() != (Object)null)
{
return 1;
}
if ((Object)(object)((Il2CppObjectBase)c).TryCast<Creature>() != (Object)null)
{
return 2;
}
if (!((Object)(object)((Il2CppObjectBase)c).TryCast<Structure>() != (Object)null))
{
return -1;
}
return 3;
}
internal static IEnumerable<MethodBase> Targets(string method)
{
int found = 0;
Type[] array = new Type[4]
{
typeof(Villager),
typeof(PlayerCharacter),
typeof(Creature),
typeof(Structure)
};
bool flag = default(bool);
foreach (Type type in array)
{
MethodInfo methodInfo = AccessTools.Method(type, method, (Type[])null, (Type[])null);
if (methodInfo == null)
{
ManualLogSource logger = Plugin.Logger;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(24, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("spawn hooks: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(method);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found");
}
logger.LogWarning(val);
}
else
{
found++;
yield return methodInfo;
}
}
if (method == "Spawned")
{
_spawnedHooks = found;
}
else
{
_despawnedHooks = found;
}
if (_spawnedHooks >= 0 && _despawnedHooks >= 0)
{
ManualLogSource logger2 = Plugin.Logger;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(33, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("spawn hooks: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_spawnedHooks);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" Spawned, ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_despawnedHooks);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" Despawned");
}
logger2.LogInfo(val2);
}
}
}
[HarmonyPatch]
internal static class SpawnedPatch
{
private static bool _failed;
private static IEnumerable<MethodBase> TargetMethods()
{
return GlowPatches.Targets("Spawned");
}
private static void Postfix(object __instance)
{
try
{
Component val = (Component)((__instance is Component) ? __instance : null);
if (val != null)
{
int num = GlowPatches.KindOf(val);
if (num >= 0)
{
GlowRegistry.Spawned(val, num);
}
}
}
catch (Exception ex)
{
if (!_failed)
{
_failed = true;
Plugin.Logger.LogWarning((object)("Spawned patch failed: " + ex));
}
}
}
}
[HarmonyPatch]
internal static class DespawnedPatch
{
private static bool _failed;
private static IEnumerable<MethodBase> TargetMethods()
{
return GlowPatches.Targets("Despawned");
}
private static void Postfix(object __instance)
{
try
{
Component val = (Component)((__instance is Component) ? __instance : null);
if (val != null)
{
GlowRegistry.Despawned(val);
}
}
catch (Exception ex)
{
if (!_failed)
{
_failed = true;
Plugin.Logger.LogWarning((object)("Despawned patch failed: " + ex));
}
}
}
}
public static class GlowMath
{
public static float Clamp01(float v)
{
if (float.IsNaN(v))
{
return 0f;
}
return Math.Clamp(v, 0f, 1f);
}
public static float DayNightStrength(float dayStrength, float nightStrength, float daylight)
{
float num = Clamp01(dayStrength);
float num2 = Clamp01(nightStrength);
float num3 = (float.IsNaN(daylight) ? 1f : Clamp01(daylight));
return num2 + (num - num2) * num3;
}
public static bool GameHasTurn(bool routineActive, float gameValue, float baseline)
{
if (routineActive)
{
return !(gameValue < Clamp01(baseline));
}
return false;
}
public static bool ExcludeKindNow(float baseline, bool kindSetting)
{
return Clamp01(baseline) > 0f && kindSetting;
}
public static bool ExcludeCreature(bool excludeNow, bool isDead)
{
if (excludeNow)
{
return !isDead;
}
return false;
}
public static int TakeBudget(int remainingInObject, int budgetLeft)
{
return Math.Min(Math.Max(0, remainingInObject), Math.Max(0, budgetLeft));
}
public static bool IsPlantType(string configName, string typeList)
{
return ContainsAny(configName, typeList);
}
private static bool ContainsAny(string configName, string list)
{
if (string.IsNullOrEmpty(configName) || string.IsNullOrEmpty(list))
{
return false;
}
string[] array = list.Split(',');
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim();
if (text.Length > 0 && configName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
}
return false;
}
public static float TypeMultiplier(string configName, float original, string plantTypes, float plantStrength, string boostTypes, float boostStrength)
{
if (ContainsAny(configName, boostTypes))
{
return original * (float.IsNaN(boostStrength) ? 1f : Math.Clamp(boostStrength, 1f, 10f));
}
if (IsPlantType(configName, plantTypes))
{
return original * Clamp01(plantStrength);
}
return original;
}
public static bool TryParseHexColor(string s, out float r, out float g, out float b)
{
r = (g = (b = 0f));
if (string.IsNullOrEmpty(s))
{
return false;
}
if (s[0] == '#')
{
s = s.Substring(1);
}
if (s.Length != 6)
{
return false;
}
int num = 0;
string text = s;
foreach (char c in text)
{
int num2;
if (c >= '0' && c <= '9')
{
num2 = c - 48;
}
else if (c >= 'a' && c <= 'f')
{
num2 = c - 97 + 10;
}
else
{
if (c < 'A' || c > 'F')
{
return false;
}
num2 = c - 65 + 10;
}
num = num * 16 + num2;
}
r = (float)((num >> 16) & 0xFF) / 255f;
g = (float)((num >> 8) & 0xFF) / 255f;
b = (float)(num & 0xFF) / 255f;
return true;
}
}
[BepInPlugin("solrlabs.aska.alwaysbesearchin", "Always Be Searchin'", "0.1.1")]
public class Plugin : BasePlugin
{
public const string Guid = "solrlabs.aska.alwaysbesearchin";
public const string Name = "Always Be Searchin'";
public const string Version = "0.1.1";
internal static ManualLogSource Logger;
internal static ConfigEntry<float> DayStrength;
internal static ConfigEntry<float> NightStrength;
internal static ConfigEntry<float> GlowRadius;
internal static ConfigEntry<string> GlowColor;
internal static ConfigEntry<bool> ExcludeVillagers;
internal static ConfigEntry<bool> ExcludeStructures;
internal static ConfigEntry<float> PlantStrength;
internal static ConfigEntry<string> PlantTypes;
internal static ConfigEntry<string> BoostTypes;
internal static ConfigEntry<float> BoostStrength;
public override void Load()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Expected O, but got Unknown
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Expected O, but got Unknown
//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_01e3: Expected O, but got Unknown
//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
//IL_0218: Unknown result type (might be due to invalid IL or missing references)
//IL_021e: Expected O, but got Unknown
Logger = ((BasePlugin)this).Log;
DayStrength = ((BasePlugin)this).Config.Bind<float>("General", "DayStrength", 0.17f, new ConfigDescription("Strength of the always-on glow in full daylight, 0 to 1.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
NightStrength = ((BasePlugin)this).Config.Bind<float>("General", "NightStrength", 0.08f, new ConfigDescription("Strength of the always-on glow at night, 0 to 1. The glow blends between the two with the game's day and night. Set both to 0 to turn the always-on glow off; Z then works as in the base game.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
GlowRadius = ((BasePlugin)this).Config.Bind<float>("General", "GlowRadius", 60f, new ConfigDescription("Radius in metres of the always-on glow around the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 200f), Array.Empty<object>()));
GlowColor = ((BasePlugin)this).Config.Bind<string>("General", "GlowColor", "#FFFF33", "Color of the always-on glow as #RRGGBB. Empty uses the game's Resource Finder color from its settings.");
ExcludeVillagers = ((BasePlugin)this).Config.Bind<bool>("General", "ExcludeVillagers", true, "Keep villagers, players and live creatures, and what they carry, out of the glow, including during Z.");
ExcludeStructures = ((BasePlugin)this).Config.Bind<bool>("General", "ExcludeStructures", true, "Keep items stored in or on buildings (storage, cooking pots, racks) out of the glow. Items on the landscape still glow.");
PlantStrength = ((BasePlugin)this).Config.Bind<float>("General", "PlantStrength", 0.5f, new ConfigDescription("Multiplier on the glow of plants (ferns, bushes, grass and similar), which glow much brighter than rocks. 1 leaves them as the game draws them. Also applies during Z.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
PlantTypes = ((BasePlugin)this).Config.Bind<string>("General", "PlantTypes", "Fern,Bush,Grass,Reed,Flower,Lupin", "Comma-separated name fragments of the vegetation types that PlantStrength applies to.");
BoostTypes = ((BasePlugin)this).Config.Bind<string>("General", "BoostTypes", "Flax", "Comma-separated name fragments of vegetation types whose glow is multiplied by BoostStrength (never dimmed by PlantStrength).");
BoostStrength = ((BasePlugin)this).Config.Bind<float>("General", "BoostStrength", 3f, new ConfigDescription("Multiplier on the glow of BoostTypes, for items that are hard to see (1 = as the game draws them).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
new Harmony("solrlabs.aska.alwaysbesearchin").PatchAll(typeof(Plugin).Assembly);
((BasePlugin)this).AddComponent<AlwaysOnGlow>();
ManualLogSource log = ((BasePlugin)this).Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(79, 6, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Always Be Searchin' ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.1.1");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded (day ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(DayStrength.Value);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", night ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(NightStrength.Value);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", radius ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(GlowRadius.Value);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", color ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(GlowColor.Value);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", exclude villagers ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(ExcludeVillagers.Value);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
}
log.LogInfo(val);
}
}
}