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<string, GameObject> Prefabs = new Dictionary<string, GameObject>();
public static List<Turret> 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<Turret>();
MainAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "curiosityplugin"));
ContentLoader = new ContentLoader(((BaseUnityPlugin)this).Info, MainAssets, (Action<CustomContent, GameObject>)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<GameObject>(BeerTankard.tankardPrefab, pos, Quaternion.identity).GetComponent<NetworkObject>();
component.Spawn(false);
((GrabbableObject)((Component)component).GetComponent<BeerTankard>()).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<Turret>() != (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<GameObject>(val, pos, rot).GetComponent<NetworkObject>();
Logger.LogInfo((object)("NetObj: " + ((Object)networkObject).name));
friendlyTurrets.Add(((Component)networkObject).GetComponentInChildren<Turret>());
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<Turret>());
networkObject.Despawn(true);
}
}
}
public class PluginConfig : SyncedInstance<PluginConfig>
{
[CompilerGenerated]
private static class <>O
{
public static HandleNamedMessageDelegate <0>__OnRequestSync;
public static HandleNamedMessageDelegate <1>__OnReceiveSync;
}
public static ConfigEntry<bool> triggerShenanigans { get; private set; }
public static ConfigEntry<bool> turretsShenanigans { get; private set; }
public static ConfigEntry<bool> itemShenanigans { get; private set; }
public static ConfigEntry<bool> drinkingHurts { get; private set; }
public static ConfigEntry<bool> imaginaryFriend { get; private set; }
public static ConfigEntry<int> drinkingDamage { get; private set; }
public static ConfigEntry<int> tankardRefills { get; private set; }
public static ConfigEntry<float> tankardDrinkingTime { get; private set; }
public static ConfigEntry<bool> spawnMultipleTurrets { get; private set; }
public static ConfigEntry<bool> allowSpawnTurretsOutdoors { get; private set; }
public static ConfigEntry<int> spawnTurretsChance { get; private set; }
public static ConfigEntry<bool> despawnTurrets { get; private set; }
public static ConfigEntry<int> despawnTurretTimeInSeconds { get; private set; }
public static ConfigEntry<string> bannedCreatures { get; private set; }
public PluginConfig(ConfigFile cfg)
{
InitInstance(this);
triggerShenanigans = cfg.Bind<bool>("General", "Enable Shenanigans?", true, "Whether or not to trigger shenanigans on enemy death");
turretsShenanigans = cfg.Bind<bool>("General", "Turrets Shenanigans", true, "Whether or not to spawn turrets shenanigans");
itemShenanigans = cfg.Bind<bool>("General", "Item Shenanigans", true, "Whether or not to spawn item shenanigans");
drinkingHurts = cfg.Bind<bool>("General.Items", "Drinking Hurts", false, "Does drinking hurt you?");
imaginaryFriend = cfg.Bind<bool>("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<float>("General.Items", "Tankard Drinking Time", 2f, "How fast do you drink?(in seconds)");
allowSpawnTurretsOutdoors = cfg.Bind<bool>("General.Turrets", "AllowSpawnTurretsOutdoors", false, "True to spawn turret outdoors as well. False to spawn only indoors");
spawnMultipleTurrets = cfg.Bind<bool>("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<bool>("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<string>("General.Misc", "BannedCreatures", "Manticoil, Red Locust Bees, Docile Locust Bees", "List all creatures that don't trigger shenanigans");
ConfigEntry<int> ConfigBindClamp(string section, string key, int defaultValue, string description, int min, int max)
{
ConfigEntry<int> val = cfg.Bind<int>(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<PluginConfig>.IsClient)
{
return;
}
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(SyncedInstance<PluginConfig>.IntSize, (Allocator)2, -1);
try
{
SyncedInstance<PluginConfig>.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<PluginConfig>.IsHost)
{
return;
}
Plugin.Logger.LogInfo((object)$"Config: Config sync request received from client: {clientId}");
byte[] array = SyncedInstance<PluginConfig>.SerializeToBytes(SyncedInstance<PluginConfig>.Instance);
int num = array.Length;
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(num + SyncedInstance<PluginConfig>.IntSize, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
SyncedInstance<PluginConfig>.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<PluginConfig>.IntSize))
{
Plugin.Logger.LogError((object)"Config: Config sync error: Could not begin reading buffer.");
return;
}
int num = default(int);
((FastBufferReader)(ref reader)).ReadValueSafe<int>(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<PluginConfig>.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<PluginConfig>.IsHost)
{
CustomMessagingManager messageManager = SyncedInstance<PluginConfig>.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<PluginConfig>.Synced = true;
return;
}
SyncedInstance<PluginConfig>.Synced = false;
CustomMessagingManager messageManager2 = SyncedInstance<PluginConfig>.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<PluginConfig>.RevertSync();
}
}
[Serializable]
public class SyncedInstance<T>
{
[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<NetworkObject> spawnedTurrets;
private static ulong currentEnemy = 9999999uL;
public static void Init()
{
spawnedTurrets = new List<NetworkObject>();
}
[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<Turret>() != (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<GameObject>(tur, ((Component)player).transform.position, Quaternion.identity).GetComponent<NetworkObject>();
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<EnemyAICollisionDetect>(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<EnemyAI>(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<Item>("Assets/BeerItem/BeerTankard.asset");
tankardPrefab = val.spawnPrefab;
BeerTankard beerTankard = tankardPrefab.AddComponent<BeerTankard>();
beerTankard.interactionSound = Plugin.MainAssets.LoadAsset<AudioClip>("Assets/BeerItem/BeerInteraction.mp3");
beerTankard.interactionEndSound = Plugin.MainAssets.LoadAsset<AudioClip>("Assets/BeerItem/BeerClarity.mp3");
beerTankard.interactionEmptySound = Plugin.MainAssets.LoadAsset<AudioClip>("Assets/BeerItem/BeerEmpty.mp3");
beerTankard.interactionDeathSound = Plugin.MainAssets.LoadAsset<AudioClip>("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<AudioSource>();
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);
}
}
}