using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CuriosityPlugin.MonoBehaviours; using CuriosityPlugin.Patches; using GameNetcodeStuff; using HarmonyLib; using LethalLib.Modules; using Microsoft.CodeAnalysis; using Unity.Collections; 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("CuriosityPlugin")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("My first plugin")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CuriosityPlugin")] [assembly: AssemblyTitle("CuriosityPlugin")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 CuriosityPlugin { [BepInPlugin("Yakua.CuriosityPlugin", "CuriosityPlugin", "0.1.0")] public class Plugin : BaseUnityPlugin { private const string pluginGUID = "Yakua.CuriosityPlugin"; private const string pluginName = "CuriosityPlugin"; private const string pluginVer = "0.1.0"; private readonly Harmony harmony = new Harmony("Yakua.CuriosityPlugin"); public static ManualLogSource Logger; public static AssetBundle MainAssets; public static ContentLoader ContentLoader; public static Dictionary Prefabs = new Dictionary(); public static List friendlyTurrets; public static Plugin Instance { get; private set; } public static PluginConfig MyConfig { get; internal set; } private void Awake() { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown if ((Object)(object)Instance == (Object)null) { Instance = this; } Logger = Logger.CreateLogSource("Yakua.CuriosityPlugin"); Logger.LogInfo((object)"Main: Plugin Yakua.CuriosityPlugin is loaded!"); MyConfig = new PluginConfig(((BaseUnityPlugin)this).Config); friendlyTurrets = new List(); MainAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "curiosityplugin")); ContentLoader = new ContentLoader(((BaseUnityPlugin)this).Info, MainAssets, (Action)delegate(CustomContent content, GameObject prefab) { Prefabs.Add(content.ID, prefab); }); BeerTankard.Init(); TurretSpawner.Init(); harmony.PatchAll(typeof(Plugin)); harmony.PatchAll(typeof(PluginConfig)); harmony.PatchAll(typeof(TurretSpawner)); harmony.PatchAll(typeof(TurretWhisperer)); } [HarmonyPatch(typeof(EnemyAI), "KillEnemyServerRpc")] [HarmonyPostfix] private static void OnEnemyDeath(EnemyAI __instance) { TurretSpawner.SpawnTurretOnDeath(__instance); } public void OnDespawnTurret(Vector3 pos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) NetworkObject component = Object.Instantiate(BeerTankard.tankardPrefab, pos, Quaternion.identity).GetComponent(); component.Spawn(false); ((GrabbableObject)((Component)component).GetComponent()).itemProperties.creditsWorth = 69; } public void SpawnFriendlyTurret(Vector3 pos, Quaternion rot) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if (!PluginConfig.imaginaryFriend.Value) { return; } Logger.LogInfo((object)("Current level is: " + ((Object)RoundManager.Instance.currentLevel).name)); GameObject val = null; SpawnableMapObject[] spawnableMapObjects = RoundManager.Instance.currentLevel.spawnableMapObjects; foreach (SpawnableMapObject val2 in spawnableMapObjects) { if ((Object)(object)val2.prefabToSpawn.GetComponentInChildren() != (Object)null) { val = val2.prefabToSpawn; } } if ((Object)(object)val == (Object)null) { Logger.LogInfo((object)"Main: No turret found to spawn a friendly turret"); return; } Logger.LogInfo((object)"SFT: Found a turret"); ManualLogSource logger = Logger; Vector3 val3 = pos; logger.LogInfo((object)("SFT: Pos is: " + ((object)(Vector3)(ref val3)).ToString())); ManualLogSource logger2 = Logger; Quaternion val4 = rot; logger2.LogInfo((object)("SFT: Rot is: " + ((object)(Quaternion)(ref val4)).ToString())); NetworkObject networkObject = Object.Instantiate(val, pos, rot).GetComponent(); Logger.LogInfo((object)("NetObj: " + ((Object)networkObject).name)); friendlyTurrets.Add(((Component)networkObject).GetComponentInChildren()); networkObject.Spawn(true); ((MonoBehaviour)networkObject).StartCoroutine(WaitForDespawn()); IEnumerator WaitForDespawn() { yield return (object)new WaitForSeconds((float)PluginConfig.despawnTurretTimeInSeconds.Value); Logger.LogInfo((object)"TS: Turret Should Despawn"); friendlyTurrets.Remove(((Component)networkObject).GetComponentInChildren()); networkObject.Despawn(true); } } } public class PluginConfig : SyncedInstance { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnRequestSync; public static HandleNamedMessageDelegate <1>__OnReceiveSync; } public static ConfigEntry triggerShenanigans { get; private set; } public static ConfigEntry turretsShenanigans { get; private set; } public static ConfigEntry itemShenanigans { get; private set; } public static ConfigEntry drinkingHurts { get; private set; } public static ConfigEntry imaginaryFriend { get; private set; } public static ConfigEntry drinkingDamage { get; private set; } public static ConfigEntry tankardRefills { get; private set; } public static ConfigEntry tankardDrinkingTime { get; private set; } public static ConfigEntry spawnMultipleTurrets { get; private set; } public static ConfigEntry allowSpawnTurretsOutdoors { get; private set; } public static ConfigEntry spawnTurretsChance { get; private set; } public static ConfigEntry despawnTurrets { get; private set; } public static ConfigEntry despawnTurretTimeInSeconds { get; private set; } public static ConfigEntry bannedCreatures { get; private set; } public PluginConfig(ConfigFile cfg) { InitInstance(this); triggerShenanigans = cfg.Bind("General", "Enable Shenanigans?", true, "Whether or not to trigger shenanigans on enemy death"); turretsShenanigans = cfg.Bind("General", "Turrets Shenanigans", true, "Whether or not to spawn turrets shenanigans"); itemShenanigans = cfg.Bind("General", "Item Shenanigans", true, "Whether or not to spawn item shenanigans"); drinkingHurts = cfg.Bind("General.Items", "Drinking Hurts", false, "Does drinking hurt you?"); imaginaryFriend = cfg.Bind("General.Items", "Imaginary Friend", false, "Does drinking spawn a friendly turret?"); drinkingDamage = ConfigBindClamp("General.Items", "Drinking Damage", 20, "How much does drinking hurt you?", 0, 100); tankardRefills = ConfigBindClamp("General.Items", "Tankard Refills", 4, "How much can your drink refill until empty?", 0, 100); tankardDrinkingTime = cfg.Bind("General.Items", "Tankard Drinking Time", 2f, "How fast do you drink?(in seconds)"); allowSpawnTurretsOutdoors = cfg.Bind("General.Turrets", "AllowSpawnTurretsOutdoors", false, "True to spawn turret outdoors as well. False to spawn only indoors"); spawnMultipleTurrets = cfg.Bind("General.Turrets", "SpawnMultipleTurrets", false, "True to spawn turret on one player. False to spawn on all players"); spawnTurretsChance = ConfigBindClamp("General.Turrets", "SpawnTurretsChance", 20, "Chance to spawn turret on each individual player(in percents from 1 to 100)", 1, 100); despawnTurrets = cfg.Bind("General.Turrets", "DespawnTurrets", true, "Do turrets despawn over time"); despawnTurretTimeInSeconds = ConfigBindClamp("General.Turrets", "DespawnTurretsTimeInSeconds", 120, "Time that takes turrets to despawn", 0, 3600); bannedCreatures = cfg.Bind("General.Misc", "BannedCreatures", "Manticoil, Red Locust Bees, Docile Locust Bees", "List all creatures that don't trigger shenanigans"); ConfigEntry ConfigBindClamp(string section, string key, int defaultValue, string description, int min, int max) { ConfigEntry val = cfg.Bind(section, key, defaultValue, description); val.Value = Mathf.Clamp(val.Value, min, max); return val; } } public static void RequestSync() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance.IsClient) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(SyncedInstance.IntSize, (Allocator)2, -1); try { SyncedInstance.MessageManager.SendNamedMessage("ModName_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static void OnRequestSync(ulong clientId, FastBufferReader _) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance.IsHost) { return; } Plugin.Logger.LogInfo((object)$"Config: Config sync request received from client: {clientId}"); byte[] array = SyncedInstance.SerializeToBytes(SyncedInstance.Instance); int num = array.Length; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(num + SyncedInstance.IntSize, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0); SyncedInstance.MessageManager.SendNamedMessage("ModName_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3); } catch (Exception arg) { Plugin.Logger.LogWarning((object)$"Config: Error occurred syncing config with client: {clientId}\n{arg}"); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static void OnReceiveSync(ulong _, FastBufferReader reader) { //IL_002d: 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) if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance.IntSize)) { Plugin.Logger.LogError((object)"Config: Config sync error: Could not begin reading buffer."); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num, default(ForPrimitives)); if (!((FastBufferReader)(ref reader)).TryBeginRead(num)) { Plugin.Logger.LogError((object)"Config: Config sync error: Host could not sync."); return; } byte[] data = new byte[num]; ((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0); SyncedInstance.SyncInstance(data); Plugin.Logger.LogInfo((object)"Config: Successfully synced config with host."); } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] public static void InitializeLocalPlayer() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (SyncedInstance.IsHost) { CustomMessagingManager messageManager = SyncedInstance.MessageManager; object obj = <>O.<0>__OnRequestSync; if (obj == null) { HandleNamedMessageDelegate val = OnRequestSync; <>O.<0>__OnRequestSync = val; obj = (object)val; } messageManager.RegisterNamedMessageHandler("CurYATM_OnRequestConfigSync", (HandleNamedMessageDelegate)obj); SyncedInstance.Synced = true; return; } SyncedInstance.Synced = false; CustomMessagingManager messageManager2 = SyncedInstance.MessageManager; object obj2 = <>O.<1>__OnReceiveSync; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnReceiveSync; <>O.<1>__OnReceiveSync = val2; obj2 = (object)val2; } messageManager2.RegisterNamedMessageHandler("CurYATM_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2); RequestSync(); } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")] public static void PlayerLeave() { SyncedInstance.RevertSync(); } } [Serializable] public class SyncedInstance { [NonSerialized] protected static int IntSize = 4; internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager; internal static bool IsClient => NetworkManager.Singleton.IsClient; internal static bool IsHost => NetworkManager.Singleton.IsHost; public static T Default { get; private set; } public static T Instance { get; private set; } public static bool Synced { get; internal set; } protected void InitInstance(T instance) { Default = instance; Instance = instance; IntSize = 4; } internal static void SyncInstance(byte[] data) { Instance = DeserializeFromBytes(data); Synced = true; } internal static void RevertSync() { Instance = Default; Synced = false; } public static byte[] SerializeToBytes(T val) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream memoryStream = new MemoryStream(); try { binaryFormatter.Serialize(memoryStream, val); return memoryStream.ToArray(); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Error serializing instance: {arg}"); return null; } } public static T DeserializeFromBytes(byte[] data) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream serializationStream = new MemoryStream(data); try { return (T)binaryFormatter.Deserialize(serializationStream); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Error deserializing instance: {arg}"); return default(T); } } } public static class PluginInfo { public const string PLUGIN_GUID = "CuriosityPlugin"; public const string PLUGIN_NAME = "CuriosityPlugin"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace CuriosityPlugin.Patches { public class TurretSpawner { public static Random turretSpawnRandom; private static List spawnedTurrets; private static ulong currentEnemy = 9999999uL; public static void Init() { spawnedTurrets = new List(); } [HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")] [HarmonyPostfix] private static void updateCurrentTurretSeed(int randomSeed) { turretSpawnRandom = new Random(randomSeed + 24); Plugin.Logger.LogInfo((object)$"TS: Generated a seed for turrets: {randomSeed + 24}"); } public static void SpawnTurretOnDeath(EnemyAI instance) { Plugin.Logger.LogInfo((object)("TS: Got into Initial Spawn Method called from " + instance.enemyType.enemyName + ".")); if (!PluginConfig.turretsShenanigans.Value || currentEnemy == ((NetworkBehaviour)instance).NetworkObject.NetworkObjectId || !((NetworkBehaviour)instance).IsHost) { return; } string[] array = PluginConfig.bannedCreatures.Value.Split(','); string[] array2 = array; foreach (string text in array2) { if (instance.enemyType.enemyName == text) { return; } } currentEnemy = ((NetworkBehaviour)instance).NetworkObject.NetworkObjectId; GameObject val = null; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; PlayerControllerB[] array3 = allPlayerScripts.Where((PlayerControllerB p) => p.isPlayerControlled && !p.isPlayerDead && (p.isInsideFactory | PluginConfig.allowSpawnTurretsOutdoors.Value)).ToArray(); Plugin.Logger.LogInfo((object)$"TS: {instance.enemyType.enemyName} has died. Trying to spawn turret on ({array3.Length}) suitable players."); SpawnableMapObject[] spawnableMapObjects = RoundManager.Instance.currentLevel.spawnableMapObjects; foreach (SpawnableMapObject val2 in spawnableMapObjects) { if ((Object)(object)val2.prefabToSpawn.GetComponentInChildren() != (Object)null) { val = val2.prefabToSpawn; } } if ((Object)(object)val == (Object)null) { Plugin.Logger.LogInfo((object)"TS: No turret found"); } else { SpawnTurrets(val, array3); } } private static void SpawnTurrets(GameObject tur, PlayerControllerB[] suitablePlayers) { if ((Object)(object)tur == (Object)null || suitablePlayers.Length == 0) { Plugin.Logger.LogInfo((object)"TS: No turret or player found to spawn a hostile turret"); return; } if (!PluginConfig.spawnMultipleTurrets.Value) { Spawn(suitablePlayers[turretSpawnRandom.Next(0, suitablePlayers.Length)]); return; } foreach (PlayerControllerB player2 in suitablePlayers) { Spawn(player2); } GameObject Spawn(PlayerControllerB player) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) int num = turretSpawnRandom.Next(1, 101); bool flag = ((num <= PluginConfig.spawnTurretsChance.Value) ? true : false); Plugin.Logger.LogInfo((object)$"TS: Rolled: {num} out of {PluginConfig.spawnTurretsChance.Value}. Target: {player.playerUsername}"); NetworkObject networkObject; if (flag && (Object)(object)tur != (Object)null) { networkObject = null; try { networkObject = Object.Instantiate(tur, ((Component)player).transform.position, Quaternion.identity).GetComponent(); networkObject.Spawn(true); spawnedTurrets.Add(networkObject); if (PluginConfig.despawnTurrets.Value) { ((MonoBehaviour)networkObject).StartCoroutine(WaitForDespawn()); } } catch (Exception arg) { Plugin.Logger.LogWarning((object)$"Exception: {arg}"); } return ((Component)networkObject).gameObject; } if ((Object)(object)tur == (Object)null) { Plugin.Logger.LogInfo((object)"TS: No turret object found for this map to spawn a hostile turret"); } return null; IEnumerator WaitForDespawn() { yield return (object)new WaitForSeconds((float)PluginConfig.despawnTurretTimeInSeconds.Value); Plugin.Logger.LogInfo((object)"TS: Turret Should Despawn"); Plugin.Instance.OnDespawnTurret(((Component)networkObject).transform.position); Despawn(networkObject); } } } public static void Despawn(NetworkObject networkObject) { spawnedTurrets.Remove(networkObject); networkObject.Despawn(true); } [HarmonyPatch(typeof(StartOfRound), "ShipLeave")] [HarmonyPrefix] private static void DeleteTurretsOnShipLeave() { if (spawnedTurrets == null) { return; } foreach (NetworkObject spawnedTurret in spawnedTurrets) { if ((Object)(object)spawnedTurret != (Object)null) { spawnedTurret.Despawn(true); } } spawnedTurrets = null; } } [HarmonyPatch(typeof(Turret))] internal class TurretWhisperer { public static float viewRadius = 20f; public static float viewAngle = 180f; public static float missChance = 0.97f; [HarmonyPatch("Update")] [HarmonyPrefix] public static void PatchUpdateBefore(ref Turret __instance) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0045: Invalid comparison between Unknown and I4 //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Invalid comparison between Unknown and I4 //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Invalid comparison between Unknown and I4 //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Invalid comparison between Unknown and I4 //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Invalid comparison between Unknown and I4 if (!Plugin.friendlyTurrets.Contains(__instance)) { return; } TurretMode val = (TurretMode)AccessTools.Field(typeof(Turret), "turretModeLastFrame").GetValue(__instance); TurretMode val2 = val; TurretMode val3 = val2; if ((int)val3 != 0) { if ((int)val3 == 1 && (Object)(object)CheckForEnemiesInLOS(__instance, 3f, angleRangeCheck: true) != (Object)null) { __instance.turretMode = (TurretMode)2; } } else if ((Object)(object)CheckForEnemiesInLOS(__instance, 3f, angleRangeCheck: true) != (Object)null) { __instance.turretMode = (TurretMode)1; SetFieldBase(__instance, "turretInterval", 0f); } if ((int)__instance.turretMode == 1 || (int)__instance.turretMode == 2 || (int)__instance.turretMode == 3) { EnemyAI val4 = CheckForEnemiesInLOS(__instance, 3f, angleRangeCheck: true); if ((Object)(object)val4 != (Object)null) { __instance.targetTransform = ((Component)val4).transform; } else { __instance.targetTransform = null; } if ((float)GetFieldBase(__instance, "turretInterval") > 0.1f && !TargetEnemy(__instance, val4) && ((int)val == 2 || (int)val == 3)) { __instance.turretMode = (TurretMode)0; } } } [HarmonyPatch("TurnTowardsTargetIfHasLOS")] [HarmonyPrefix] public static void PatchTurnTowardsTargetIfHasLOS(ref Turret __instance) { //IL_0022: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.friendlyTurrets.Contains(__instance)) { return; } bool flag = true; if (Physics.Linecast(__instance.aimPoint.position, __instance.targetTransform.position, StartOfRound.Instance.collidersAndRoomMask, (QueryTriggerInteraction)1)) { flag = false; } if (flag) { SetFieldBase(__instance, "hasLineOfSight", true); SetFieldBase(__instance, "lostLOSTimer", 0f); __instance.tempTransform.position = __instance.targetTransform.position; Transform tempTransform = __instance.tempTransform; tempTransform.position -= Vector3.up * 0.15f; __instance.turnTowardsObjectCompass.LookAt(__instance.tempTransform); return; } if ((bool)GetFieldBase(__instance, "hasLineOfSight")) { SetFieldBase(__instance, "hasLineOfSight", false); SetFieldBase(__instance, "lostLOSTimer", 0f); } SetFieldBase(__instance, "lostLOSTimer", (float)GetFieldBase(__instance, "lostLOSTimer") + Time.deltaTime); if (!((double)GetFieldBase(__instance, "lostLOSTimer") < 2.0)) { SetFieldBase(__instance, "lostLOSTimer", 0f); Debug.Log((object)"Turret: LOS timer ended on server. checking for new player target"); EnemyAI val = CheckForEnemiesInLOS(__instance); if ((Object)(object)val != (Object)null) { Debug.Log((object)"Turret: Got new enemy target"); } else { Debug.Log((object)"Turret: No new player to target; returning to detection mode."); } } } public static bool TargetEnemy(Turret turret, EnemyAI visibleEnemy) { //IL_0049: 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) bool result = false; if ((Object)(object)visibleEnemy != (Object)null) { if ((double)Random.Range(0f, 1f) > (double)missChance) { SetFieldBase(turret, "turretInterval", 0f); visibleEnemy.HitEnemyOnLocalClient(3, default(Vector3), (PlayerControllerB)null, false, -1); Plugin.Logger.LogInfo((object)("TW: " + (visibleEnemy.enemyType.enemyName + " was hit by a friendly turret."))); result = true; } else { result = false; } } return result; } public static EnemyAI CheckForEnemiesInLOS(Turret instance, float radius = 2f, bool angleRangeCheck = false) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) Vector3 forward = ((Transform)GetFieldBase(instance, "aimPoint")).forward; Vector3 val = Quaternion.Euler(0f, (float)(int)(0f - (float)GetFieldBase(instance, "rotationRange")) / radius, 0f) * forward; float num = (float)((double)instance.rotationRange / (double)radius * 2.0); SetFieldBase(instance, "shootRay", (object)new Ray(instance.centerPoint.position, val)); RaycastHit[] array = Physics.RaycastAll((Ray)GetFieldBase(instance, "shootRay"), 30f); if (array.Length == 0) { return null; } RaycastHit[] array2 = array; EnemyAICollisionDetect val3 = default(EnemyAICollisionDetect); EnemyAI val4 = default(EnemyAI); for (int i = 0; i < array2.Length; i++) { RaycastHit val2 = array2[i]; if (((Component)((RaycastHit)(ref val2)).transform).CompareTag("Enemy")) { SetFieldBase(instance, "hit", val2); if (((Component)((RaycastHit)(ref val2)).transform).TryGetComponent(ref val3)) { Plugin.Logger.LogWarning((object)("TW: Acquired enemy component from " + ((Object)((RaycastHit)(ref val2)).collider).name)); if (!((Object)(object)val3 == (Object)null)) { return (angleRangeCheck && (double)Vector3.Angle(((Component)val3).transform.position + Vector3.up * 1.75f - instance.centerPoint.position, instance.forwardFacingPos.forward) > (double)instance.rotationRange) ? null : val3.mainScript; } } else if (((Component)((RaycastHit)(ref val2)).transform).TryGetComponent(ref val4)) { Plugin.Logger.LogWarning((object)("TW: Acquired enemy component from " + ((Object)((RaycastHit)(ref val2)).collider).name)); if (!((Object)(object)val4 == (Object)null)) { return (angleRangeCheck && (double)Vector3.Angle(((Component)val4).transform.position + Vector3.up * 1.75f - instance.centerPoint.position, instance.forwardFacingPos.forward) > (double)instance.rotationRange) ? null : val4; } } else { Plugin.Logger.LogWarning((object)"TW: Doesn't have the EnemyAI or EnemyAICollisionDetect component."); Plugin.Logger.LogWarning((object)("TW: Hit Name: " + ((Object)((RaycastHit)(ref val2)).collider).name)); } } else { val = Quaternion.Euler(0f, num / 6f, 0f) * val; } } return null; } private static object GetFieldBase(Turret turret, string fieldName) { return AccessTools.Field(typeof(Turret), fieldName).GetValue(turret); } private static void SetFieldBase(Turret turret, string fieldName, object fieldValue) { AccessTools.Field(typeof(Turret), fieldName).SetValue(turret, fieldValue); } [HarmonyPatch("CheckForPlayersInLineOfSight")] [HarmonyPostfix] public static void PatchCheckForPlayersInLineOfSight(ref Turret __instance, ref PlayerControllerB __result) { if (Plugin.friendlyTurrets.Contains(__instance)) { __result = null; } } } } namespace CuriosityPlugin.MonoBehaviours { internal class BeerTankard : PhysicsProp { private static int DamageNumber = 100; private static float TimeToEmpty = 2f; private static int MaxRefills = 4; public static GameObject tankardPrefab; private PlayerControllerB previousPlayerHeldBy; private Coroutine useTankardCoroutine; public AudioSource audioSource; public AudioClip interactionSound; public AudioClip interactionEndSound; public AudioClip interactionEmptySound; public AudioClip interactionDeathSound; private bool runningOut; private float fuel = 1f; private int charges; public static void Init() { Item val = Plugin.MainAssets.LoadAsset("Assets/BeerItem/BeerTankard.asset"); tankardPrefab = val.spawnPrefab; BeerTankard beerTankard = tankardPrefab.AddComponent(); beerTankard.interactionSound = Plugin.MainAssets.LoadAsset("Assets/BeerItem/BeerInteraction.mp3"); beerTankard.interactionEndSound = Plugin.MainAssets.LoadAsset("Assets/BeerItem/BeerClarity.mp3"); beerTankard.interactionEmptySound = Plugin.MainAssets.LoadAsset("Assets/BeerItem/BeerEmpty.mp3"); beerTankard.interactionDeathSound = Plugin.MainAssets.LoadAsset("Assets/BeerItem/BeerDeath.mp3"); ((GrabbableObject)beerTankard).grabbable = true; ((GrabbableObject)beerTankard).grabbableToEnemies = true; ((GrabbableObject)beerTankard).itemProperties = val; DamageNumber = PluginConfig.drinkingDamage.Value; TimeToEmpty = PluginConfig.tankardDrinkingTime.Value; MaxRefills = PluginConfig.tankardRefills.Value; NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab); Utilities.FixMixerGroups(val.spawnPrefab); Items.RegisterItem(val); } public void Awake() { audioSource = ((Component)this).GetComponent(); charges = MaxRefills; } public override void Update() { //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) if (runningOut) { if ((Object)(object)previousPlayerHeldBy == (Object)null || !((GrabbableObject)this).isHeld || (double)fuel <= 0.0) { RunOutOfFuelServerRpc(); } previousPlayerHeldBy.drunknessInertia = Mathf.Clamp(previousPlayerHeldBy.drunknessInertia + Time.deltaTime / 1.75f * (22f / (TimeToEmpty * (float)MaxRefills)) * previousPlayerHeldBy.drunknessSpeed, 0.1f, 3f); previousPlayerHeldBy.increasingDrunknessThisFrame = true; if ((double)fuel <= 0.0) { if (charges <= 0) { Plugin.Logger.LogInfo((object)"KILL"); if (((NetworkBehaviour)this).IsOwner) { ((GrabbableObject)this).playerHeldBy.playerBodyAnimator.SetBool("useTZPItem", false); ((GrabbableObject)this).playerHeldBy.activatingItem = false; if (PluginConfig.drinkingHurts.Value) { ((GrabbableObject)this).playerHeldBy.DamagePlayer(DamageNumber, true, true, (CauseOfDeath)0, 1, false, default(Vector3)); } } if (((NetworkBehaviour)this).IsHost) { Plugin.Instance.SpawnFriendlyTurret(((Component)((GrabbableObject)this).playerHeldBy).transform.position, ((Component)((GrabbableObject)this).playerHeldBy).transform.rotation); } audioSource.PlayOneShot(interactionDeathSound); WalkieTalkie.TransmitOneShotAudio(audioSource, interactionDeathSound, 1f); } else { Plugin.Logger.LogInfo((object)"Clarity moment"); if (((NetworkBehaviour)this).IsOwner) { ((GrabbableObject)this).playerHeldBy.playerBodyAnimator.SetBool("useTZPItem", false); ((GrabbableObject)this).playerHeldBy.activatingItem = false; ((GrabbableObject)this).playerHeldBy.DamagePlayer(DamageNumber, true, true, (CauseOfDeath)0, 1, false, default(Vector3)); } audioSource.PlayOneShot(interactionEndSound); WalkieTalkie.TransmitOneShotAudio(audioSource, interactionEndSound, 1f); } if (charges > 0) { charges--; fuel = 1f; } else { ((GrabbableObject)this).itemProperties.creditsWorth = 10; } } else { fuel -= Time.deltaTime / TimeToEmpty; } } ((GrabbableObject)this).Update(); } public override void ItemActivate(bool used, bool buttonDown = true) { ((GrabbableObject)this).ItemActivate(used, buttonDown); if (!((GrabbableObject)this).isBeingUsed) { ((GrabbableObject)this).isBeingUsed = true; if ((double)fuel <= 0.0) { ((GrabbableObject)this).isBeingUsed = false; audioSource.PlayOneShot(interactionEmptySound); WalkieTalkie.TransmitOneShotAudio(audioSource, interactionEmptySound, 1f); previousPlayerHeldBy.playerBodyAnimator.SetTrigger("shakeItem"); } else { previousPlayerHeldBy = ((GrabbableObject)this).playerHeldBy; audioSource.PlayOneShot(interactionSound); WalkieTalkie.TransmitOneShotAudio(audioSource, interactionSound, 1f); runningOut = true; useTankardCoroutine = ((MonoBehaviour)this).StartCoroutine(TankardAnimation()); } } } public override void EquipItem() { ((PhysicsProp)this).EquipItem(); StartOfRound.Instance.RefreshPlayerVoicePlaybackObjects(); if ((Object)(object)((GrabbableObject)this).playerHeldBy != (Object)null) { previousPlayerHeldBy = ((GrabbableObject)this).playerHeldBy; } } [ServerRpc] public void RunOutOfFuelServerRpc() { RunOutOfFuelClientRpc(); } [ClientRpc] public void RunOutOfFuelClientRpc() { previousPlayerHeldBy.playerBodyAnimator.SetBool("useTZPItem", false); ((MonoBehaviour)this).StopCoroutine(useTankardCoroutine); previousPlayerHeldBy.activatingItem = false; ((GrabbableObject)this).itemUsedUp = true; ((GrabbableObject)this).isBeingUsed = false; runningOut = false; fuel = 0f; } public override void DiscardItem() { runningOut = false; ((GrabbableObject)this).playerHeldBy.playerBodyAnimator.ResetTrigger("shakeItem"); previousPlayerHeldBy.playerBodyAnimator.SetBool("useTZPItem", false); if ((Object)(object)previousPlayerHeldBy != (Object)null) { previousPlayerHeldBy.activatingItem = false; } ((GrabbableObject)this).DiscardItem(); } public IEnumerator TankardAnimation() { ((GrabbableObject)this).playerHeldBy.activatingItem = true; ((GrabbableObject)this).playerHeldBy.playerBodyAnimator.SetBool("useTZPItem", true); yield return (object)new WaitForSeconds(0.75f); HUDManager.Instance.gasHelmetAnimator.SetBool("gasEmitting", true); } } }