#define DEBUG
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Andy.Configuration;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Radov10.Andy.NetcodePatcher;
using Unity.Netcode;
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: AssemblyCompany("Radov10.Andy")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+514cd4e5d506fea87f830ed09b8380651e4a36b1")]
[assembly: AssemblyProduct("Andy")]
[assembly: AssemblyTitle("Radov10.Andy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
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;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 Andy
{
internal class AndyAI : EnemyAI
{
private enum State
{
SearchingForPlayer,
ChasingPlayer,
ZappingArea
}
[CompilerGenerated]
private sealed class <ZapArea>d__9 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public AndyAI <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <ZapArea>d__9(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Expected O, but got Unknown
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Expected O, but got Unknown
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Expected O, but got Unknown
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>4__this.DamagePlayersPerSecond();
<>4__this.PlayZapSfx();
<>2__current = (object)new WaitForSeconds(2.5f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<>4__this.DamagePlayersPerSecond();
<>4__this.PlayZapSfx();
<>2__current = (object)new WaitForSeconds(2.5f);
<>1__state = 2;
return true;
case 2:
<>1__state = -1;
<>4__this.DamagePlayersPerSecond();
<>4__this.PlayZapSfx();
<>2__current = (object)new WaitForSeconds(2.5f);
<>1__state = 3;
return true;
case 3:
<>1__state = -1;
<>4__this.DamagePlayersPerSecond();
<>4__this.PlayZapSfx();
<>2__current = (object)new WaitForSeconds(2.5f);
<>1__state = 4;
return true;
case 4:
<>1__state = -1;
<>4__this.DamagePlayersPerSecond();
<>4__this.PlayZapSfx();
<>2__current = (object)new WaitForSeconds(2.5f);
<>1__state = 5;
return true;
case 5:
<>1__state = -1;
<>4__this.DoAnimationClientRpc("startWalk");
((EnemyAI)<>4__this).SwitchToBehaviourClientRpc(0);
((MonoBehaviour)<>4__this).StopCoroutine(<>4__this.ZapArea());
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 Transform turnCompass = null;
public Transform attackArea = null;
public AudioClip? zapSfx = null;
private AudioSource? _audioSource;
[Conditional("DEBUG")]
private void LogIfDebugBuild(string text)
{
Plugin.Logger.LogInfo((object)text);
}
public override void Start()
{
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
((EnemyAI)this).Start();
LogIfDebugBuild("Example Enemy Spawned");
DoAnimationClientRpc("startWalk");
_audioSource = ((Component)this).GetComponent<AudioSource>();
if ((Object)(object)_audioSource == (Object)null)
{
_audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
_audioSource.spatialBlend = 1f;
_audioSource.playOnAwake = false;
_audioSource.rolloffMode = (AudioRolloffMode)1;
_audioSource.minDistance = 5f;
_audioSource.maxDistance = 30f;
}
if ((Object)(object)zapSfx == (Object)null && (Object)(object)Plugin.ModAssets != (Object)null)
{
try
{
AudioClip val = Plugin.ModAssets.LoadAsset<AudioClip>("ZapSfx");
if ((Object)(object)val != (Object)null)
{
zapSfx = val;
LogIfDebugBuild("Assigned ZapSfx from bundle.");
}
}
catch
{
}
}
if ((Object)(object)_audioSource.clip == (Object)null && (Object)(object)zapSfx != (Object)null)
{
_audioSource.clip = zapSfx;
}
if ((Object)(object)zapSfx == (Object)null && ((Object)(object)_audioSource == (Object)null || (Object)(object)_audioSource.clip == (Object)null))
{
LogIfDebugBuild("Zap SFX not assigned on Start; will skip unless provided later.");
}
((EnemyAI)this).SwitchToBehaviourClientRpc(0);
((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null);
}
public override void Update()
{
((EnemyAI)this).Update();
if (!base.isEnemyDead)
{
}
}
public override void DoAIInterval()
{
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
((EnemyAI)this).DoAIInterval();
if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
{
return;
}
switch (base.currentBehaviourStateIndex)
{
case 0:
base.agent.speed = 2f;
if (FoundClosestPlayerInRange(25f, 3f))
{
LogIfDebugBuild("Start Target Player");
((EnemyAI)this).StopSearch(base.currentSearch, true);
((EnemyAI)this).SwitchToBehaviourClientRpc(1);
}
break;
case 1:
base.agent.speed = 8f;
if (!TargetClosestPlayerInAnyCase() || (Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) > 20f && !((EnemyAI)this).CheckLineOfSightForPosition(((Component)base.targetPlayer).transform.position, 45f, 60, -1f, (Transform)null)))
{
LogIfDebugBuild("Stop Target Player");
((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null);
((EnemyAI)this).SwitchToBehaviourClientRpc(0);
}
else
{
((EnemyAI)this).SetDestinationToPosition(((Component)base.targetPlayer).transform.position, false);
}
break;
case 2:
base.agent.speed = 0f;
break;
default:
LogIfDebugBuild("This Behavior State doesn't exist!");
break;
}
}
[IteratorStateMachine(typeof(<ZapArea>d__9))]
public IEnumerator ZapArea()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <ZapArea>d__9(0)
{
<>4__this = this
};
}
private void PlayZapSfx()
{
if (!((Object)(object)_audioSource == (Object)null))
{
if ((Object)(object)zapSfx != (Object)null)
{
_audioSource.PlayOneShot(zapSfx);
}
else if ((Object)(object)_audioSource.clip != (Object)null)
{
_audioSource.PlayOneShot(_audioSource.clip);
}
else
{
LogIfDebugBuild("Zap SFX not assigned; skipping sound.");
}
}
}
public void DamagePlayersPerSecond()
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
foreach (PlayerControllerB val in allPlayerScripts)
{
if (Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position) < 10f)
{
val.DamagePlayer(30, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
}
}
}
private bool FoundClosestPlayerInRange(float range, float senseRange)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
((EnemyAI)this).TargetClosestPlayer(1.5f, true, 70f);
if ((Object)(object)base.targetPlayer == (Object)null)
{
((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f);
range = senseRange;
}
return (Object)(object)base.targetPlayer != (Object)null && Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < range;
}
private bool TargetClosestPlayerInAnyCase()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
base.mostOptimalDistance = 2000f;
base.targetPlayer = null;
for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++)
{
base.tempDist = Vector3.Distance(((Component)this).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position);
if (base.tempDist < base.mostOptimalDistance)
{
base.mostOptimalDistance = base.tempDist;
base.targetPlayer = StartOfRound.Instance.allPlayerScripts[i];
}
}
if ((Object)(object)base.targetPlayer == (Object)null)
{
return false;
}
return true;
}
public override void OnCollideWithPlayer(Collider other)
{
PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false);
if ((Object)(object)val != (Object)null && base.currentBehaviourStateIndex != 2)
{
LogIfDebugBuild("Andy Collision with Player!");
((MonoBehaviour)this).StartCoroutine(ZapArea());
DoAnimationClientRpc("stopWalk");
((EnemyAI)this).SwitchToBehaviourClientRpc(2);
}
}
public override void OnCollideWithEnemy(Collider other, EnemyAI collidedEnemy = null)
{
((EnemyAI)this).OnCollideWithEnemy(other, collidedEnemy);
if ((Object)(object)collidedEnemy != (Object)null && base.currentBehaviourStateIndex != 2)
{
((MonoBehaviour)this).StartCoroutine(ZapArea());
DoAnimationClientRpc("stopWalk");
((EnemyAI)this).SwitchToBehaviourClientRpc(2);
}
}
public override void HitEnemy(int force = 1, PlayerControllerB? playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
{
((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitID);
if (!base.isEnemyDead)
{
base.enemyHP -= force;
if (((NetworkBehaviour)this).IsOwner && base.enemyHP <= 0 && !base.isEnemyDead)
{
((MonoBehaviour)this).StopCoroutine(base.searchCoroutine);
((EnemyAI)this).KillEnemyOnOwnerClient(false);
}
}
}
[ClientRpc]
public void DoAnimationClientRpc(string animationName)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Invalid comparison between Unknown and I4
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Invalid comparison between Unknown and I4
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: 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_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
if (networkManager == null || !networkManager.IsListening)
{
return;
}
if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
{
ClientRpcParams val = default(ClientRpcParams);
FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3207112672u, val, (RpcDelivery)0);
bool flag = animationName != null;
((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
if (flag)
{
((FastBufferWriter)(ref val2)).WriteValueSafe(animationName, false);
}
((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3207112672u, val, (RpcDelivery)0);
}
if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
{
((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
LogIfDebugBuild("Animation: " + animationName);
base.creatureAnimator.SetTrigger(animationName);
}
}
protected override void __initializeVariables()
{
((EnemyAI)this).__initializeVariables();
}
protected override void __initializeRpcs()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
((NetworkBehaviour)this).__registerRpc(3207112672u, new RpcReceiveHandler(__rpc_handler_3207112672), "DoAnimationClientRpc");
((EnemyAI)this).__initializeRpcs();
}
private static void __rpc_handler_3207112672(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: 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)
NetworkManager networkManager = target.NetworkManager;
if (networkManager != null && networkManager.IsListening)
{
bool flag = default(bool);
((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
string animationName = null;
if (flag)
{
((FastBufferReader)(ref reader)).ReadValueSafe(ref animationName, false);
}
target.__rpc_exec_stage = (__RpcExecStage)1;
((AndyAI)(object)target).DoAnimationClientRpc(animationName);
target.__rpc_exec_stage = (__RpcExecStage)0;
}
}
protected internal override string __getTypeName()
{
return "AndyAI";
}
}
[BepInPlugin("Radov10.Andy", "Andy", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Logger;
public static AssetBundle? ModAssets;
internal static PluginConfig BoundConfig { get; private set; }
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
BoundConfig = new PluginConfig(((BaseUnityPlugin)this).Config);
InitializeNetworkBehaviours();
string path = "Andyassets";
ModAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), path));
if ((Object)(object)ModAssets == (Object)null)
{
Logger.LogError((object)"Failed to load custom assets.");
return;
}
EnemyType val = ModAssets.LoadAsset<EnemyType>("AndyObj");
AudioClip val2 = null;
try
{
val2 = ModAssets.LoadAsset<AudioClip>("ZapSfx");
}
catch
{
}
if ((Object)(object)val != (Object)null)
{
AndyAI andyAI = (((Object)(object)val.enemyPrefab != (Object)null) ? val.enemyPrefab.GetComponentInChildren<AndyAI>(true) : null);
if ((Object)(object)andyAI != (Object)null && (Object)(object)val2 != (Object)null)
{
andyAI.zapSfx = val2;
}
else if ((Object)(object)andyAI == (Object)null)
{
Logger.LogWarning((object)"AndyAI component not found on enemy prefab; cannot assign ZapSfx automatically.");
}
else if ((Object)(object)val2 == (Object)null)
{
Logger.LogInfo((object)"ZapSfx AudioClip not found in asset bundle. Assign a clip to AndyAI.zapSfx in the prefab or add an AudioSource clip.");
}
}
TerminalNode val3 = ModAssets.LoadAsset<TerminalNode>("AndyTN");
TerminalKeyword val4 = ModAssets.LoadAsset<TerminalKeyword>("AndyTK");
NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab);
Enemies.RegisterEnemy(val, BoundConfig.SpawnWeight.Value, (LevelTypes)(-1), val3, val4);
Logger.LogInfo((object)"Plugin Radov10.Andy is loaded!");
}
private static void InitializeNetworkBehaviours()
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
Type[] array = types;
foreach (Type type in array)
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo[] array2 = methods;
foreach (MethodInfo methodInfo in array2)
{
object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
if (customAttributes.Length != 0)
{
methodInfo.Invoke(null, null);
}
}
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "Radov10.Andy";
public const string PLUGIN_NAME = "Andy";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace Andy.Configuration
{
public class PluginConfig
{
public ConfigEntry<int> SpawnWeight;
public PluginConfig(ConfigFile cfg)
{
SpawnWeight = cfg.Bind<int>("General", "Spawn weight", 20, "The spawn chance weight for Andy, relative to other existing enemies.\nGoes up from 0, lower is more rare, 100 and up is very common.");
ClearUnusedEntries(cfg);
}
private void ClearUnusedEntries(ConfigFile cfg)
{
PropertyInfo property = ((object)cfg).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(cfg, null);
dictionary.Clear();
cfg.Save();
}
}
}
namespace __GEN
{
internal class NetworkVariableSerializationHelper
{
[RuntimeInitializeOnLoadMethod]
internal static void InitializeSerialization()
{
}
}
}
namespace Radov10.Andy.NetcodePatcher
{
[AttributeUsage(AttributeTargets.Module)]
internal class NetcodePatchedAssemblyAttribute : Attribute
{
}
}