using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using Unity.VisualScripting;
using UnityEngine;
[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.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("BLOKBUSTR")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+90341fc2d6cc7b49573247fc22193d256a74be2d")]
[assembly: AssemblyProduct("LoomConfig")]
[assembly: AssemblyTitle("LoomConfig")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace LoomConfig
{
[HarmonyPatch(typeof(EnemyShadowAnim))]
public class EnemyShadowAnimPatch
{
[HarmonyPrefix]
[HarmonyPatch("Update")]
public static void UpdatePrefix(EnemyShadowAnim __instance)
{
float value = LoomConfig.configIdleLoopVolume.Value;
if (!Mathf.Approximately(value, 0.1f) && !Mathf.Approximately(value, __instance.idleLoop.Volume))
{
__instance.idleLoop.Volume = value;
}
}
[HarmonyPrefix]
[HarmonyPatch("PlayClapSound")]
public static bool PlayClapSoundPrefix(EnemyShadowAnim __instance)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
if (!LoomConfig.configFixGlobalClapAudio.Value)
{
LoomConfig.Debug("Played globalClapSound at vanilla position (Vector3.zero)", (MonoBehaviour?)(object)__instance);
return true;
}
__instance.clapSound.Play(((Component)__instance).transform.position, 1f, 1f, 1f, 1f);
__instance.globalClapSound.Play(((Component)__instance).transform.position, 1f, 1f, 1f, 1f);
LoomConfig.Debug($"Played globalClapSound at fixed position (transform.position: {((Component)__instance).transform.position})", (MonoBehaviour?)(object)__instance);
return false;
}
}
[HarmonyPatch(typeof(EnemyShadow))]
public static class EnemyShadowPatch
{
[HarmonyPostfix]
[HarmonyPatch("Awake")]
public static void AwakePostfix(EnemyShadow __instance)
{
LoomConfig.Debug("Applying custom properties to new Loom, if any", (MonoBehaviour?)(object)__instance);
EnemyShadowUtil enemyShadowUtil = ComponentHolderProtocol.AddComponent<EnemyShadowUtil>((Object)(object)__instance);
enemyShadowUtil.enemyShadow = __instance;
((MonoBehaviour)enemyShadowUtil).StartCoroutine(enemyShadowUtil.SetDelayedProperties());
if (SemiFunc.IsNotMasterClient())
{
return;
}
int value = LoomConfig.configMaxHealth.Value;
if (value != 500)
{
EnemyHealth component = ((Component)__instance).GetComponent<EnemyHealth>();
if (Object.op_Implicit((Object)(object)component))
{
component.health = value;
component.healthCurrent = value;
LoomConfig.Debug($"Changed health to {value}", (MonoBehaviour?)(object)__instance);
}
else
{
LoomConfig.Error("EnemyHealth component not found!", (MonoBehaviour?)(object)__instance);
}
}
int value2 = LoomConfig.configClapEnemyDamage.Value;
if (value2 != 20)
{
__instance.hurtColliderScript.enemyDamage = value2;
LoomConfig.Debug($"Changed clap enemy damage to {value2}", (MonoBehaviour?)(object)__instance);
}
}
[HarmonyPostfix]
[HarmonyPatch("StateLeave")]
public static void StateLeavePostfix(EnemyShadow __instance)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Invalid comparison between Unknown and I4
if ((int)__instance.currentState == 8)
{
float value = LoomConfig.configMovementSpeedLeave.Value;
if (!Mathf.Approximately(value, 2.5f))
{
__instance.enemy.NavMeshAgent.OverrideAgent(value, 30f, 0.1f);
}
}
}
[HarmonyPrefix]
[HarmonyPatch("BendLogic")]
public static void BendLogicPrefix(EnemyShadow __instance)
{
float value = LoomConfig.configPlayerLookDistance.Value;
if (!Mathf.Approximately(value, 7f) && !Mathf.Approximately(value, __instance.distanceFromPlayer))
{
__instance.closeEnoughToLook = __instance.distanceFromPlayer < value;
}
}
}
[HarmonyPatch(typeof(EnemyShadowScreenVeinEffect))]
public class EnemyShadowScreenVeinEffectPatch
{
[HarmonyPrefix]
[HarmonyPatch("Start")]
public static void StartPrefix(EnemyShadowScreenVeinEffect __instance)
{
if (!LoomConfig.configScreenEffectShowHands.Value)
{
((Renderer)__instance.handSpriteRenderer).enabled = false;
}
if (!LoomConfig.configScreenEffectShowVeins.Value)
{
((Renderer)__instance.veinSpriteRenderer).enabled = false;
}
}
}
public class EnemyShadowUtil : MonoBehaviour
{
[CompilerGenerated]
private sealed class <SetDelayedProperties>d__1 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public EnemyShadowUtil <>4__this;
private int <playerDamage>5__1;
private float <speed>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <SetDelayedProperties>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = null;
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
break;
case 2:
<>1__state = -1;
break;
}
if (!Object.op_Implicit((Object)(object)<>4__this.enemyShadow.enemy.NavMeshAgent?.Agent))
{
LoomConfig.Debug("Delaying other properties, NavMeshAgent is not fully set up", (MonoBehaviour?)(object)<>4__this.enemyShadow);
<>2__current = (object)new WaitForSeconds(0.1f);
<>1__state = 2;
return true;
}
<playerDamage>5__1 = LoomConfig.configClapPlayerDamage.Value;
if (SemiFunc.IsNotMasterClient())
{
<playerDamage>5__1 = LoomConfigRoomProperties.GetClapPlayerDamage();
}
if (<playerDamage>5__1 != 100)
{
<>4__this.enemyShadow.hurtColliderScript.playerDamage = <playerDamage>5__1;
LoomConfig.Debug($"Changed clap player damage to {<playerDamage>5__1}", (MonoBehaviour?)(object)<>4__this.enemyShadow);
}
if (SemiFunc.IsNotMasterClient())
{
return false;
}
<speed>5__2 = LoomConfig.configMovementSpeed.Value;
if (!Mathf.Approximately(<speed>5__2, 1.2f))
{
<>4__this.enemyShadow.enemy.NavMeshAgent.Agent.speed = <speed>5__2;
<>4__this.enemyShadow.enemy.NavMeshAgent.DefaultSpeed = <speed>5__2;
LoomConfig.Debug($"Changed movement speed to {<speed>5__2}", (MonoBehaviour?)(object)<>4__this.enemyShadow);
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public EnemyShadow enemyShadow;
[IteratorStateMachine(typeof(<SetDelayedProperties>d__1))]
public IEnumerator SetDelayedProperties()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <SetDelayedProperties>d__1(0)
{
<>4__this = this
};
}
}
[BepInPlugin("BLOKBUSTR.LoomConfig", "LoomConfig", "1.0.0")]
public class LoomConfig : BaseUnityPlugin
{
public static ConfigEntry<int> configMaxHealth;
public static ConfigEntry<int> configClapPlayerDamage;
public static ConfigEntry<int> configClapEnemyDamage;
public static ConfigEntry<float> configMovementSpeed;
public static ConfigEntry<float> configMovementSpeedLeave;
public static ConfigEntry<float> configPlayerLookDistance;
public static ConfigEntry<bool> configScreenEffectShowHands;
public static ConfigEntry<bool> configScreenEffectShowVeins;
public static ConfigEntry<float> configIdleLoopVolume;
public static ConfigEntry<bool> configFixGlobalClapAudio;
private static ConfigEntry<bool> configEnableDebug;
internal static LoomConfig Instance { get; private set; }
internal static ManualLogSource Logger => Instance._logger;
private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;
internal Harmony? Harmony { get; set; }
private void Awake()
{
Instance = this;
((Component)this).gameObject.transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
RegisterConfig();
Patch();
Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
Debug("Debug logging is enabled.");
}
private void RegisterConfig()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Expected O, but got Unknown
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Expected O, but got Unknown
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Expected O, but got Unknown
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Expected O, but got Unknown
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Expected O, but got Unknown
//IL_017a: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Expected O, but got Unknown
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Expected O, but got Unknown
//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
//IL_01ec: Expected O, but got Unknown
//IL_020d: Unknown result type (might be due to invalid IL or missing references)
//IL_0217: Expected O, but got Unknown
//IL_0238: Unknown result type (might be due to invalid IL or missing references)
//IL_0242: Expected O, but got Unknown
configMaxHealth = ((BaseUnityPlugin)this).Config.Bind<int>("Mechanical", "MaxHealth", 500, new ConfigDescription("The maximum health of Loom.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 1000), Array.Empty<object>()));
configClapPlayerDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Mechanical", "ClapPlayerDamage", 100, new ConfigDescription("The amount of damage dealt to players by the clap attack. This setting will be synced to all clients in multiplayer.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>()));
configClapEnemyDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Mechanical", "ClapEnemyDamage", 20, new ConfigDescription("The amount of damage dealt to enemies by the clap attack.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>()));
configMovementSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Mechanical", "MovementSpeed", 1.2f, new ConfigDescription("The base movement speed of Loom.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 4f), Array.Empty<object>()));
configMovementSpeedLeave = ((BaseUnityPlugin)this).Config.Bind<float>("Mechanical", "MovementSpeedLeave", 2.5f, new ConfigDescription("The movement speed of Loom in her Leave state.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 4f), Array.Empty<object>()));
configPlayerLookDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "PlayerLookDistance", 7f, new ConfigDescription("The distance at which Loom considers herself close enough to look at the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 15f), Array.Empty<object>()));
configScreenEffectShowHands = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ScreenEffectShowHands", true, new ConfigDescription("Whether to show the hand layer in the \"targeted\" screen effect.", (AcceptableValueBase)null, Array.Empty<object>()));
configScreenEffectShowVeins = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ScreenEffectShowVeins", true, new ConfigDescription("Whether to show the vein layer in the \"targeted\" screen effect.", (AcceptableValueBase)null, Array.Empty<object>()));
configIdleLoopVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "IdleLoopVolume", 0.1f, new ConfigDescription("The volume of the idleLoop sound.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.2f), Array.Empty<object>()));
configFixGlobalClapAudio = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "FixGlobalClapAudio", true, new ConfigDescription("Patches a vanilla oversight where the globalClapSound is played at the world origin rather than at Loom's actual location. The local clapSound is unaffected by this bug.", (AcceptableValueBase)null, Array.Empty<object>()));
configEnableDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebug", false, new ConfigDescription("Whether to enable debug logging. Keep this disabled for normal gameplay.", (AcceptableValueBase)null, Array.Empty<object>()));
}
internal void Patch()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_0026: Expected O, but got Unknown
if (Harmony == null)
{
Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
Harmony val2 = val;
Harmony = val;
}
Harmony.PatchAll();
}
internal void Unpatch()
{
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
internal static void Debug(string message, MonoBehaviour? instance = null)
{
if (configEnableDebug.Value)
{
string text = (Object.op_Implicit((Object)(object)instance) ? $"{((Object)instance).GetInstanceID()}: " : string.Empty);
Logger.LogDebug((object)(text + message));
}
}
internal static void Error(string message, MonoBehaviour? instance = null)
{
string text = (Object.op_Implicit((Object)(object)instance) ? $"{((Object)instance).GetInstanceID()}: " : string.Empty);
Logger.LogDebug((object)(text + message));
}
}
public static class LoomConfigRoomProperties
{
internal const string LOOM_CLAP_PLAYER_DAMAGE = "LoomClapPlayerDamage";
public static void SetLoomProperties()
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
//IL_0079: Expected O, but got Unknown
if (!SemiFunc.IsNotMasterClient() && SemiFunc.IsMultiplayer())
{
int value = LoomConfig.configClapPlayerDamage.Value;
if (value == GetClapPlayerDamage())
{
LoomConfig.Debug("playerDamage is the same, no need to sync");
return;
}
LoomConfig.Debug($"Setting Custom Room (Loom) Properties | playerDamage: {value}");
Room currentRoom = PhotonNetwork.CurrentRoom;
Hashtable val = new Hashtable();
((Dictionary<object, object>)val).Add((object)"LoomClapPlayerDamage", (object)value);
currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
}
}
public static object? GetLoomProperties(string key)
{
if (!((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).ContainsKey((object)key))
{
return null;
}
object obj = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties[(object)key];
LoomConfig.Debug($"Getting Custom Room (Loom) Properties | key: {key} | damage: {obj}");
return obj;
}
public static int GetClapPlayerDamage()
{
object loomProperties = GetLoomProperties("LoomClapPlayerDamage");
return (loomProperties == null) ? (-1) : ((int)loomProperties);
}
}
[HarmonyPatch(typeof(RunManager))]
public class RunManagerHook
{
[HarmonyPostfix]
[HarmonyPatch("ChangeLevel")]
public static void ChangeLevelPostfix(bool _levelFailed)
{
if (!_levelFailed)
{
LoomConfigRoomProperties.SetLoomProperties();
}
}
}
}