Decompiled source of VoidDrones v0.26.2
VoidDrones.dll
Decompiled 11 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CG; using CG.Client.Audio; using CG.Client.Player.HUD; using CG.Client.Player.Interactions; using CG.Client.Ship.Hull; using CG.Client.UserData; using CG.Game; using CG.Game.Missions; using CG.Game.Player; using CG.Game.SpaceObjects; using CG.Game.SpaceObjects.Controllers; using CG.Network; using CG.Objects; using CG.Ship; using CG.Ship.Hull; using CG.Ship.Modules; using CG.Ship.Modules.AutoMechanic; using CG.Ship.Modules.Weapons; using CG.Ship.Object; using CG.Ship.Scanning; using CG.Space; using CG.Space.SpaceObjects; using CG.Space.SpaceObjects.Weapons; using CG.SpaceObjects; using Cinemachine; using Client.Player.Interactions; using Client.Ship.Actor; using Code.Gameplay; using FMOD; using FMOD.Studio; using FMODUnity; using Gameplay.CompositeWeapons; using Gameplay.CompositeWeapons.Effects; using Gameplay.Damage; using Gameplay.Loot; using Gameplay.NPC.AI; using Gameplay.Ship; using Gameplay.Ship.VoidJump; using Gameplay.SpacePlatforms; using Gameplay.Utilities; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Opsive.Shared.Input; using Photon.Pun; using Photon.Realtime; using ResourceAssets; using RuntimeAssets; using TMPro; using UI.Core; using UI.ObjectMarker; using UI.Ping; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.VFX; using VFX; using VoidDrones.Content; using VoidDrones.Patches; using VoidManager; using VoidManager.Chat.Router; using VoidManager.MPModChecks; using VoidManager.ModMessages; using VoidManager.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("YourName")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Player-controlled drones and hijack missiles for Void Crew.")] [assembly: AssemblyFileVersion("0.26.2.0")] [assembly: AssemblyInformationalVersion("0.26.2")] [assembly: AssemblyProduct("VoidDrones")] [assembly: AssemblyTitle("VoidDrones")] [assembly: AssemblyVersion("0.26.2.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VoidDrones { public class DronesCommand : ChatCommand { public override string[] CommandAliases() { return new string[1] { "drones" }; } public override string Description() { return "Void Drones debug info: ship, nearby, modules, weapons, enemies, fx [N]"; } public override string[] UsageExamples() { return new string[9] { "/drones ship", "/drones nearby", "/drones modules", "/drones weapons", "/drones enemies", "/drones fx", "/drones fx 3", "/drones find beamcaster", "/drones model drone" }; } public override void Execute(string arguments) { string text = (arguments ?? string.Empty).Trim().ToLowerInvariant(); if (text == "fx" || text.StartsWith("fx ")) { DroneEffects(text.Substring(2).Trim()); return; } if (text.StartsWith("find ")) { Plugin.Log.LogInfo((object)FindAssets(text.Substring(5).Trim())); Messaging.Echo("/drones " + text + ": results in the BepInEx log", true); return; } if (text.StartsWith("model ")) { Plugin.Log.LogInfo((object)DescribeModel(text.Substring(6).Trim())); Messaging.Echo("/drones " + text + ": model tree in the BepInEx log", true); return; } string text2; switch (text) { case "layout": Messaging.Echo("/drones layout: " + DroneKitbash.Reload() + " (" + DroneKitbash.LayoutPath + ")", true); return; case "ship": text2 = DescribePlayerShip(); break; case "nearby": text2 = DescribeNearby(); break; case "modules": text2 = DescribeModuleContainer(); break; case "weapons": text2 = DescribeWeapons(); break; case "enemies": text2 = DescribeShipPrefabs(); break; default: Messaging.Echo("Usage: /drones ship | nearby | modules | weapons | enemies | fx [N] | find <text> | model <drone|bay|guid> | layout", true); return; } Plugin.Log.LogInfo((object)text2); Messaging.Echo("/drones " + text + ": written to BepInEx log", true); } private static string FindAssets(string text) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder("Find \"" + text + "\":\n"); foreach (CloneStarObjectDef def in ((ResourceAssetContainer<CloneStarObjectContainer, AbstractCloneStarObject, CloneStarObjectDef>)(object)ResourceAssetContainer<CloneStarObjectContainer, AbstractCloneStarObject, CloneStarObjectDef>.Instance).AssetDescriptions) { string text2 = SafeHeader(delegate { IResourceAssetContextInfo contextInfo = def.ContextInfo; return (contextInfo == null) ? null : contextInfo.HeaderText; }); if (Matches(text2, text) || Matches(((ResourceAssetDef<AbstractCloneStarObject>)(object)def).Path, text)) { stringBuilder.AppendLine($" object \"{text2}\" path={((ResourceAssetDef<AbstractCloneStarObject>)(object)def).Path} guid={((ResourceAssetDef<AbstractCloneStarObject>)(object)def).AssetGuid}"); } } foreach (CompositeWeaponDataDef def2 in ((ResourceAssetContainer<CompositeWeaponDataContainer, CompositeWeaponData, CompositeWeaponDataDef>)(object)ResourceAssetContainer<CompositeWeaponDataContainer, CompositeWeaponData, CompositeWeaponDataDef>.Instance).AssetDescriptions) { string text3 = SafeHeader(delegate { IResourceAssetContextInfo contextInfo = ((PurchasableResourceAssetDef<CompositeWeaponData>)(object)def2).ContextInfo; return (contextInfo == null) ? null : contextInfo.HeaderText; }); if (Matches(text3, text) || Matches(((ResourceAssetDef<CompositeWeaponData>)(object)def2).Path, text)) { CompositeWeapon val = ((ResourceAssetDef<CompositeWeaponData>)(object)def2).Asset?.Data; stringBuilder.AppendLine($" turret \"{text3}\" path={((ResourceAssetDef<CompositeWeaponData>)(object)def2).Path} guid={((ResourceAssetDef<CompositeWeaponData>)(object)def2).AssetGuid} core={((ResourceAssetRef)(val?.CoreElement?)).AssetGuid} " + $"pivot={((ResourceAssetRef)(val?.PivotElement?)).AssetGuid} casing={((ResourceAssetRef)(val?.CasingElement?)).AssetGuid} scope={((ResourceAssetRef)(val?.ScopeElement?)).AssetGuid}"); } } return stringBuilder.ToString(); } private static bool Matches(string value, string text) { if (!string.IsNullOrEmpty(value)) { return value.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static string SafeHeader(Func<string> header) { try { return header() ?? string.Empty; } catch { return string.Empty; } } private static string DescribeModel(string target) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (DroneKitbash.TryParseGuid(target, out var guid) && DroneKitbash.TryGetRecipe(guid, out var recipe)) { StringBuilder stringBuilder = new StringBuilder("Turret recipe " + target + " parts:\n"); (string, ResourceAssetRef)[] array = new(string, ResourceAssetRef)[4] { ("core", (ResourceAssetRef)(object)recipe.CoreElement), ("pivot", (ResourceAssetRef)(object)recipe.PivotElement), ("casing", (ResourceAssetRef)(object)recipe.CasingElement), ("scope", (ResourceAssetRef)(object)recipe.ScopeElement) }; for (int i = 0; i < array.Length; i++) { var (text, val) = array[i]; if (!(val == (ResourceAssetRef)null) && !val.IsNull) { string text2 = ((object)Unsafe.As<GUIDUnion, GUIDUnion>(ref val.AssetGuid)/*cast due to .constrained prefix*/).ToString(); stringBuilder.Append("--- " + text + " (source \"" + text2 + "\") ---\n"); stringBuilder.Append(DescribeModel(text2)); } } return stringBuilder.ToString(); } GameObject val2 = DroneKitbash.ResolvePrefab(target); if ((Object)(object)val2 == (Object)null) { return "Model \"" + target + "\": not found (use drone, bay, or a 32-character GUID from /drones find)"; } StringBuilder stringBuilder2 = new StringBuilder("Model " + ((Object)val2).name + " (paths are relative, ready for the layout file):\n"); for (int j = 0; j < val2.transform.childCount; j++) { AppendTree(stringBuilder2, val2.transform.GetChild(j), 0, ((Object)val2.transform.GetChild(j)).name); } return stringBuilder2.ToString(); } private static void AppendTree(StringBuilder sb, Transform node, int depth, string path) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(' ', 2 + depth * 2).Append(path); if (!((Component)node).gameObject.activeSelf) { stringBuilder.Append(" [inactive]"); } stringBuilder.Append($" pos={node.localPosition} rot={node.localEulerAngles} scale={node.localScale}"); MeshFilter component = ((Component)node).GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { stringBuilder.Append($" mesh={((Object)component.sharedMesh).name} ({component.sharedMesh.vertexCount} verts)"); } Renderer component2 = ((Component)node).GetComponent<Renderer>(); if ((Object)(object)component2 != (Object)null) { List<string> list = new List<string>(); Material[] sharedMaterials = component2.sharedMaterials; foreach (Material val in sharedMaterials) { list.Add(((Object)(object)val != (Object)null) ? ((Object)val).name : "none"); } stringBuilder.Append(" " + ((object)component2).GetType().Name + "[" + string.Join(", ", list) + "]"); } sb.AppendLine(stringBuilder.ToString()); for (int j = 0; j < node.childCount; j++) { AppendTree(sb, node.GetChild(j), depth + 1, path + "/" + ((Object)node.GetChild(j)).name); } } private static void DroneEffects(string argument) { DroneController droneController = null; foreach (DroneController value in DroneController.ByBay.Values) { if ((Object)(object)value != (Object)null) { droneController = value; break; } } if ((Object)(object)droneController == (Object)null) { Messaging.Echo("/drones fx: launch a drone first", true); return; } Renderer[] componentsInChildren = ((Component)droneController).GetComponentsInChildren<Renderer>(true); if (int.TryParse(argument, out var result)) { if (result < 0 || result >= componentsInChildren.Length) { Messaging.Echo($"/drones fx: pick 0-{componentsInChildren.Length - 1}", true); return; } Renderer val = componentsInChildren[result]; val.enabled = !val.enabled; object[] obj = new object[4] { result, ((Object)((Component)val).gameObject).name, ((object)val).GetType().Name, null }; Material sharedMaterial = val.sharedMaterial; obj[3] = ((sharedMaterial != null) ? ((Object)sharedMaterial).name : null); Messaging.Echo(string.Format("fx {0}: {1} ({2}, {3}) ", obj) + (val.enabled ? "ON" : "OFF"), true); return; } StringBuilder stringBuilder = new StringBuilder($"Drone renderers ({componentsInChildren.Length}):\n"); for (int i = 0; i < componentsInChildren.Length; i++) { Renderer val2 = componentsInChildren[i]; VisualEffect component = ((Component)val2).GetComponent<VisualEffect>(); object[] obj2 = new object[4] { i, ((Object)((Component)val2).gameObject).name, ((object)val2).GetType().Name, null }; Material sharedMaterial2 = val2.sharedMaterial; obj2[3] = ((sharedMaterial2 != null) ? ((Object)sharedMaterial2).name : null); string text = string.Format(" {0}: {1} {2} material={3} ", obj2); object obj3; if (component == null) { obj3 = null; } else { VisualEffectAsset visualEffectAsset = component.visualEffectAsset; obj3 = ((visualEffectAsset != null) ? ((Object)visualEffectAsset).name : null); } if (obj3 == null) { obj3 = "-"; } stringBuilder.AppendLine(text + $"vfx={obj3} enabled={val2.enabled}"); } Plugin.Log.LogInfo((object)stringBuilder.ToString()); Messaging.Echo($"/drones fx: {componentsInChildren.Length} renderers listed in the log; '/drones fx N' toggles one", true); } private static string DescribePlayerShip() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) ClientGame current = ClientGame.Current; PlayerControlledShip val = ((current != null) ? current.PlayerShip : null); if ((Object)(object)val == (Object)null) { return "No player ship"; } StringBuilder stringBuilder = new StringBuilder(); object[] obj = new object[4] { ((Object)val).name, ((OrbitObject)val).Faction, ((AbstractCloneStarObject)val).ContainerGuid, null }; Player owner = ((MonoBehaviourPun)val).photonView.Owner; obj[3] = ((owner != null) ? owner.NickName : null); stringBuilder.AppendLine(string.Format("Player ship {0} faction={1} guid={2} owner={3}", obj)); foreach (CellModule allModule in val.GetAllModules()) { stringBuilder.AppendLine($" module {((Object)allModule).name} type={((object)allModule).GetType().Name} guid={((AbstractCloneStarObject)allModule).ContainerGuid}"); } return stringBuilder.ToString(); } private static string DescribeNearby() { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) GameSessionSector activeSector = GameSessionManager.ActiveSector; if (activeSector == (GameSessionSector)null) { return "No active sector"; } StringBuilder stringBuilder = new StringBuilder(); Sector sectorAsset = activeSector.SectorAsset; stringBuilder.AppendLine($"Sector {((sectorAsset != null) ? ((Object)sectorAsset).name : null)}: {activeSector.OrbitObjects.Count} orbit objects"); foreach (OrbitObject item in new List<OrbitObject>(activeSector.OrbitObjects)) { SpaceCraft val = (SpaceCraft)(object)((item is SpaceCraft) ? item : null); if (val != null && (Object)(object)val != (Object)(object)ClientGame.Current.PlayerShip) { bool flag = (Object)(object)((Component)val).GetComponent<NpcAI>() != (Object)null; string text = $" {((Object)val).name} type={((object)val).GetType().Name} faction={((OrbitObject)val).Faction} size={val.Size} "; object arg = ((AbstractCloneStarObject)val).ContainerGuid; object arg2 = flag; Player owner = ((MonoBehaviourPun)val).photonView.Owner; stringBuilder.AppendLine(text + $"guid={arg} npcAI={arg2} owner={((owner != null) ? owner.NickName : null)}"); } } return stringBuilder.ToString(); } private static string DescribeWeapons() { ClientGame current = ClientGame.Current; PlayerControlledShip val = ((current != null) ? current.PlayerShip : null); if ((Object)(object)val == (Object)null) { return "No player ship"; } StringBuilder stringBuilder = new StringBuilder(); foreach (CompositeWeaponModule module in val.GetModules<CompositeWeaponModule>()) { bool flag = (Object)(object)((Component)module).GetComponent<DroneBayModule>() != (Object)null; stringBuilder.AppendLine(string.Format(" {0}{1} taken={2}: {3}", ((AbstractCloneStarObject)module).DisplayName, flag ? " [Drone Bay]" : "", module.IsTaken, DroneBayModule.DescribeStats(module))); } if (stringBuilder.Length <= 0) { return "No weapons on ship"; } return "Ship weapons:\n" + stringBuilder; } private static string DescribeShipPrefabs() { //IL_0103: 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) CloneStarObjectContainer instance = ResourceAssetContainer<CloneStarObjectContainer, AbstractCloneStarObject, CloneStarObjectDef>.Instance; string[] array = new string[6] { "Modules", "Carryable", "CompositeWeapons", "PlayerShip", "Cosmetic", "Hub" }; StringBuilder stringBuilder = new StringBuilder(); int num = 0; foreach (CloneStarObjectDef item in new List<CloneStarObjectDef>(((ResourceAssetContainer<CloneStarObjectContainer, AbstractCloneStarObject, CloneStarObjectDef>)(object)instance).AssetDescriptions)) { string path = ((ResourceAssetDef<AbstractCloneStarObject>)(object)item).Path ?? string.Empty; if (!Array.Exists(array, (string s) => path.Contains(s))) { AbstractCloneStarObject asset = ((ResourceAssetDef<AbstractCloneStarObject>)(object)item).Asset; SpaceCraft val = (SpaceCraft)(object)((asset is SpaceCraft) ? asset : null); if (val != null && !(val is PlayerControlledShip)) { bool flag = (Object)(object)((Component)val).GetComponent<NpcAI>() != (Object)null; stringBuilder.AppendLine($" {((Object)val).name} type={((object)val).GetType().Name} faction={((OrbitObject)val).Faction} size={val.Size} npcAI={flag} guid={((ResourceAssetDef<AbstractCloneStarObject>)(object)item).AssetGuid} path={path}"); num++; } } } return $"Spacecraft prefabs: {num}\n{stringBuilder}"; } private static string DescribeModuleContainer() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) ModuleContainer instance = ResourceAssetContainer<ModuleContainer, CellModule, ModuleDef>.Instance; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine($"ModuleContainer: {((ResourceAssetContainer<ModuleContainer, CellModule, ModuleDef>)(object)instance).AssetDescriptions.Count} modules"); foreach (ModuleDef assetDescription in ((ResourceAssetContainer<ModuleContainer, CellModule, ModuleDef>)(object)instance).AssetDescriptions) { stringBuilder.AppendLine($" {((ResourceAssetDef<CellModule>)(object)assetDescription).Path} guid={((ResourceAssetDef<CellModule>)(object)assetDescription).AssetGuid} category={assetDescription.Category}"); } return stringBuilder.ToString(); } } internal static class MyPluginInfo { public const string GUID = "VoidDrones"; public const string Name = "Void Drones"; public const string Version = "0.26.2"; } [BepInPlugin("VoidDrones", "Void Drones", "0.26.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry<Key> LaunchKey; internal static ConfigEntry<Key> KeyForward; internal static ConfigEntry<Key> KeyBack; internal static ConfigEntry<Key> KeyLeft; internal static ConfigEntry<Key> KeyRight; internal static ConfigEntry<Key> KeyUp; internal static ConfigEntry<Key> KeyDown; internal static ConfigEntry<Key> KeyRollLeft; internal static ConfigEntry<Key> KeyRollRight; internal static ConfigEntry<float> MouseSensitivity; internal static ConfigEntry<bool> InvertMouseY; internal static ConfigEntry<float> RollSpeed; internal static ConfigEntry<float> MinimumDroneSpeed; internal static ConfigEntry<float> SpeedMultiplier; internal static ConfigEntry<float> AccelerationTime; internal static ConfigEntry<float> TurnSmoothing; internal static ConfigEntry<float> MaxTurnRate; internal static ConfigEntry<float> RespawnDelay; internal static ConfigEntry<float> DroneScanRadius; internal static ConfigEntry<float> DroneHealthMultiplier; internal static ConfigEntry<float> EnginePitch; internal static ConfigEntry<float> MenuStatic; internal static ConfigEntry<float> BoostTrailBrightness; internal static ConfigEntry<float> CrystalSize; internal static ConfigEntry<float> CrystalDepth; internal static ConfigEntry<string> BackWallMaterials; internal static ConfigEntry<bool> MenuPreview; internal static ConfigEntry<bool> ControllerMonitor; internal static ConfigEntry<float> ControllerMonitorRange; internal static ConfigEntry<bool> ControllerMonitorFlipX; internal static ConfigEntry<bool> ControllerMonitorFlipY; internal static ConfigEntry<float> PreviewSpinSpeed; internal static ConfigEntry<float> PreviewZoom; internal static ConfigEntry<float> PreviewExposure; internal static ConfigEntry<float> PreviewLight; internal static ConfigEntry<float> CrosshairDistance; internal static ConfigEntry<float> ShipClearance; internal static ConfigEntry<float> AutopilotOrbitRadius; internal static ConfigEntry<float> AutopilotSpeed; internal static ConfigEntry<float> AutopilotFollowDistance; internal static ConfigEntry<float> AutopilotFollowRestart; internal static ConfigEntry<float> HiveMindTileSpacing; internal static ConfigEntry<float> AutopilotDodgeRange; internal static ConfigEntry<float> AutopilotDodgeMargin; internal static ConfigEntry<float> AutopilotJinkRange; internal static ConfigEntry<float> AutopilotJinkAimAngle; internal static ConfigEntry<float> AutopilotJinkStrength; internal static ConfigEntry<bool> AutopilotPing; internal static ConfigEntry<float> AutopilotPingInterval; internal static ConfigEntry<float> AutopilotPingRange; internal static ConfigEntry<bool> CockpitHud; internal static ConfigEntry<float> ReticleLag; internal static ConfigEntry<bool> LaunchSequence; internal static ConfigEntry<float> LaunchDelay; internal static ConfigEntry<float> RecallDelay; internal static ConfigEntry<bool> ControllerStyle; internal static ConfigEntry<float> EngineVolume; internal static ConfigEntry<Key> MineDropKey; internal static ConfigEntry<float> MineCooldown; internal static ConfigEntry<float> MineLifetime; internal static ConfigEntry<float> MineDropDistance; internal static ConfigEntry<float> MineHuntRange; internal static ConfigEntry<float> MineChaseSpeed; internal static ConfigEntry<float> MineChaseTime; internal static ConfigEntry<float> MineBeamInterval; internal static ConfigEntry<float> MineBeamDamage; internal static ConfigEntry<float> MineBeamRange; internal static ConfigEntry<int> MineBurstCount; internal static ConfigEntry<float> MineBurstDamage; internal static ConfigEntry<float> MineBurstSpeed; internal static ConfigEntry<float> AbsolverDamage; internal static ConfigEntry<float> BestowerDamage; internal static ConfigEntry<float> BestowerFireRate; internal static ConfigEntry<float> ConfessorAccuracy; internal static ConfigEntry<float> ConfessorFireRate; internal static ConfigEntry<float> ConfessorDamage; internal static ConfigEntry<float> RespawnHealthThreshold; internal static ConfigEntry<float> TierBonus; internal static ConfigEntry<bool> ListenFromDrone; internal static ConfigEntry<float> DroneTargetRange; internal static ConfigEntry<float> DroneTargetBias; internal static ConfigEntry<bool> HideHudWithoutDrone; internal static ConfigEntry<float> CameraHeight; internal static ConfigEntry<float> CameraDistance; internal static ConfigEntry<bool> FirstPersonDefault; internal static ConfigEntry<Key> CameraToggleKey; internal static ConfigEntry<float> StaticNearShip; internal static ConfigEntry<float> MaxRange; internal static ConfigEntry<float> WarningFraction; internal static ConfigEntry<float> NoiseCap; internal static ConfigEntry<float> NoiseCapFraction; internal static ConfigEntry<float> NoiseMax; internal static ConfigEntry<Key> KeyBoost; internal static ConfigEntry<float> StrafeSpeedMultiplier; internal static ConfigEntry<float> CollisionRadius; internal static ConfigEntry<int> CollisionLayerMask; internal static ConfigEntry<float> BoostSpeedMultiplier; internal static ConfigEntry<float> BoostDuration; internal static ConfigEntry<float> BoostCooldown; internal static ConfigEntry<float> BoostSteering; internal static ConfigEntry<float> BoostShake; internal static bool ChatOpen; private const int CurrentConfigVersion = 8; internal static bool InputBlocked { get { if (!ChatOpen) { return MenuScreenController.IsOpen(); } return true; } } private void Awake() { Log = ((BaseUnityPlugin)this).Logger; LaunchKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "LaunchDrone", (Key)26, "Launch or recall the drone while seated in a Drone Bay."); KeyForward = ((BaseUnityPlugin)this).Config.Bind<Key>("Flight", "Forward", (Key)37, ""); KeyBack = ((BaseUnityPlugin)this).Config.Bind<Key>("Flight", "Back", (Key)33, ""); KeyLeft = ((BaseUnityPlugin)this).Config.Bind<Key>("Flight", "StrafeLeft", (Key)15, ""); KeyRight = ((BaseUnityPlugin)this).Config.Bind<Key>("Flight", "StrafeRight", (Key)18, ""); KeyUp = ((BaseUnityPlugin)this).Config.Bind<Key>("Flight", "Up", (Key)1, "Ascend (same as the ship's helm)."); KeyDown = ((BaseUnityPlugin)this).Config.Bind<Key>("Flight", "Down", (Key)17, "Descend (same as the ship's helm)."); KeyBoost = ((BaseUnityPlugin)this).Config.Bind<Key>("Flight", "Boost", (Key)51, "Boost (same as the ship's helm)."); StrafeSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "StrafeSpeedMultiplier", 0.475f, "Left/right strafe speed relative to forward speed."); CollisionRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "CollisionRadius", 4f, "Radius (m) of the drone's collision sphere. 0 = no collision."); CollisionLayerMask = ((BaseUnityPlugin)this).Config.Bind<int>("Flight", "CollisionLayerMask", 13312, "Physics layers the drone collides with (default = the layers the game's weapons hit: ships, asteroids, structures)."); BoostSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Boost", "SpeedMultiplier", 1.5f, "Top speed multiplier while boosting."); BoostDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Boost", "Duration", 3f, "Seconds a boost lasts."); BoostCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Boost", "Cooldown", 10f, "Seconds after a boost ends before the next one is ready."); BoostSteering = ((BaseUnityPlugin)this).Config.Bind<float>("Boost", "SteeringMultiplier", 0.5f, "Mouse and roll sensitivity while boosting."); BoostShake = ((BaseUnityPlugin)this).Config.Bind<float>("Boost", "CameraShake", 0.35f, "Camera shake strength while boosting (m). 0 = off."); KeyRollLeft = ((BaseUnityPlugin)this).Config.Bind<Key>("Flight", "RollLeft", (Key)31, ""); KeyRollRight = ((BaseUnityPlugin)this).Config.Bind<Key>("Flight", "RollRight", (Key)19, ""); MouseSensitivity = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "MouseSensitivity", 0.0935f, "Degrees of turn per pixel of mouse movement."); MaxTurnRate = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "MaxTurnRate", 110f, "Fastest pitch/yaw turn (degrees per second), however fast the mouse moves. 0 = unlimited."); InvertMouseY = ((BaseUnityPlugin)this).Config.Bind<bool>("Flight", "InvertMouseY", false, ""); RollSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "RollSpeed", 99f, "Degrees per second."); MinimumDroneSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "MinimumSpeed", 80f, "Top speed floor (m/s) if the base ship's own top speed is lower."); SpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "SpeedMultiplier", 0.85f, "Multiplies the drone's top speed."); AccelerationTime = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "AccelerationTime", 1.21f, "Seconds to reach top speed from a standstill (and to stop again). Higher = more inertia."); TurnSmoothing = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "TurnSmoothing", 0.152f, "Turning inertia in seconds (time constant). 0 = instant. Try 0.2-0.4 for heavier handling."); HideHudWithoutDrone = ((BaseUnityPlugin)this).Config.Bind<bool>("DroneBay", "HideHudWithoutDrone", true, "Hide the turret HUD while seated in a Drone Bay until a drone is launched."); TierBonus = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "TierBonus", 0.05f, "Drone top speed and health bonus per controller upgrade (0.05 = +5% at MkII, +10% at MkIII)."); RespawnDelay = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "RespawnDelay", 30f, "Seconds before a controller can launch again after its drone was destroyed, or recalled below RespawnHealthThreshold. Host's setting applies. 0 = off."); RespawnHealthThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "RespawnHealthThreshold", 0.75f, "Recalling a drone with less than this fraction of its health (0.75 = 75%) starts the respawn delay."); MineDropKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Mine", "DropKey", (Key)21, "Drop a friendly hunting mine behind the drone while flying: a Beam Mine from Energy drones, a Burst Mine from Kinetic drones."); MineCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Mine", "Cooldown", 60f, "Seconds between mine drops, per controller. Host's setting applies."); MineLifetime = ((BaseUnityPlugin)this).Config.Bind<float>("Mine", "Lifetime", 180f, "A mine that hasn't exploded is removed after this many seconds. 0 = never. Host's setting applies."); MineDropDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Mine", "DropDistance", 15f, "How far behind the drone the mine appears (m)."); MineHuntRange = ((BaseUnityPlugin)this).Config.Bind<float>("Mine", "HuntRange", 1200f, "The mine locks onto the nearest enemy within this distance (m). Host's setting applies."); MineChaseSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Mine", "ChaseSpeed", 140f, "Top chase speed (m/s); the mine reaches it 1.5 s after locking on. Host's setting applies."); MineChaseTime = ((BaseUnityPlugin)this).Config.Bind<float>("Mine", "ChaseTime", 20f, "Seconds the mine chases a target before it self-destructs. Host's setting applies."); MineBeamInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Mine", "BeamInterval", 2.5f, "Seconds between the mine's shots at its target (Beam Mine: a Beamcaster ray; Burst Mine: a Litany burst). 0 = no shots. Host's setting applies."); MineBeamDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Mine", "BeamDamage", 0.12f, "Damage of each Beamcaster ray (Beam Mines, from Energy drones), as a fraction of the mine's blast damage. Host's setting applies."); MineBeamRange = ((BaseUnityPlugin)this).Config.Bind<float>("Mine", "BeamRange", 700f, "The mine fires only at targets within this distance (m). Host's setting applies."); MineBurstCount = ((BaseUnityPlugin)this).Config.Bind<int>("Mine", "BurstCount", 5, "Litany Minigun rounds per burst (Burst Mines, from Kinetic drones)."); MineBurstDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Mine", "BurstDamage", 0.03f, "Damage of each Litany round (Burst Mines), as a fraction of the mine's blast damage. Host's setting applies."); MineBurstSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Mine", "BurstSpeed", 500f, "Speed (m/s) of the Burst Mine's Litany rounds; they're aimed ahead of moving targets."); AbsolverDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "AbsolverLanceDamage", 0.75f, "Damage multiplier for the Absolver Lance on a drone. Every player should use the same balance values."); BestowerDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "BestowerFlakDamage", 0.85f, "Damage multiplier for the Bestower Flak Cannon on a drone."); BestowerFireRate = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "BestowerFlakFireRate", 0.85f, "Fire rate multiplier for the Bestower Flak Cannon on a drone."); ConfessorAccuracy = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "ConfessorCarronadeAccuracy", 1.8f, "Base accuracy multiplier for the Confessor Carronade on a drone (2 = half the spread)."); ConfessorFireRate = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "ConfessorCarronadeFireRate", 1.125f, "Fire rate multiplier for the Confessor Carronade on a drone."); ConfessorDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "ConfessorCarronadeDamage", 1.1f, "Damage multiplier for the Confessor Carronade on a drone."); ControllerStyle = ((BaseUnityPlugin)this).Config.Bind<bool>("DroneBay", "ControllerStyle", true, "Give installed controllers their own look: weapon machinery removed (seat and screen kept), silver panels, glow in the drone colour."); CrystalSize = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "CrystalSize", 1.2f, "Size (m) of the drone crystals on the controller's back wall."); CrystalDepth = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "CrystalDepth", 0.35f, "How far (m) in front of the back wall the crystals sit."); BackWallMaterials = ((BaseUnityPlugin)this).Config.Bind<string>("DroneBay", "BackWallMaterials", "Metal_GreyDark_Mat", "Materials of the controller's back frame (behind the canisters) painted black, comma-separated. The log's 'MK2 frame' line lists them."); MenuPreview = ((BaseUnityPlugin)this).Config.Bind<bool>("DroneBay", "MenuPreview", true, "Show a spinning model of the controller's drone at the top of the pre-launch weapon menu."); ControllerMonitor = ((BaseUnityPlugin)this).Config.Bind<bool>("DroneBay", "ControllerMonitor", true, "Mirror the pre-launch menu on the controller's own monitor while the controller is switched on, so it can be read from outside the seat."); ControllerMonitorRange = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "ControllerMonitorRange", 25f, "The controller monitor is only drawn within this distance of the camera (metres)."); ControllerMonitorFlipX = ((BaseUnityPlugin)this).Config.Bind<bool>("DroneBay", "ControllerMonitorFlipX", false, "Mirror the controller monitor's menu left-right (if it shows mirrored)."); ControllerMonitorFlipY = ((BaseUnityPlugin)this).Config.Bind<bool>("DroneBay", "ControllerMonitorFlipY", false, "Flip the controller monitor's menu upside down (if it shows upside down)."); PreviewZoom = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "PreviewZoom", 1.5f, "Zoom of the menu's drone model (1 = the whole model fits, 1.5 = 1.5x closer)."); PreviewSpinSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "PreviewSpinSpeed", 30f, "Turntable speed of the menu's drone model (degrees per second)."); PreviewExposure = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "PreviewExposure", 6f, "Exposure (EV100) of the menu's drone model: higher is darker."); PreviewLight = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "PreviewLight", 40000f, "Brightness of the lights on the menu's drone model."); LaunchSequence = ((BaseUnityPlugin)this).Config.Bind<bool>("DroneBay", "LaunchSequence", true, "Launch and recall sequence: link-up and signal screens, the drone warping in and out, the controller's lights reacting. Off = instant launch and recall. The host's setting decides the timing."); LaunchDelay = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "LaunchDelay", 0.8f, "Seconds between pressing launch and the drone appearing (the link-up). Host's setting applies."); RecallDelay = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "RecallDelay", 0.5f, "Seconds the drone spins down before warping out when recalled (void jump and range recalls use at most 0.3). Host's setting applies."); BoostTrailBrightness = ((BaseUnityPlugin)this).Config.Bind<float>("Boost", "TrailBrightness", 4f, "How much brighter the drone's exhaust trail glows while boosting (1 = no change). It also gets 50% wider."); MenuStatic = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "MenuStatic", 0.0765f, "Strength of the TV static on the pre-launch screen (0 = off, 1 = solid noise)."); EnginePitch = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "EnginePitch", 2f, "Pitch of the drone's engine, thrust and boost sounds (the ship's own sounds; 2 = one octave higher)."); EngineVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "EngineVolume", 1f, "Volume of the drone's engine, thrust and boost sounds (0-1+)."); DroneHealthMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("DroneBay", "HealthMultiplier", 0.5f, "Drone max health relative to the Hollow Morph it's built from (0.5 = half). Every player should use the same value."); DroneScanRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Range", "DroneScanRadius", 600f, "Drones passively scan objects within this distance (m), like the ship does around itself. 0 = off. Host's setting applies."); DroneTargetRange = ((BaseUnityPlugin)this).Config.Bind<float>("Enemies", "DroneTargetRange", 800f, "Enemies within this distance (m) of a drone may pick it as their target. Drones that shoot enemies also draw their aggro."); DroneTargetBias = ((BaseUnityPlugin)this).Config.Bind<float>("Enemies", "DroneTargetBias", 0.6f, "How strongly drones draw fire: an enemy targets a drone when its distance x this is closer than its current target. Lower = drones attract more fire."); ListenFromDrone = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "ListenFromDrone", true, "While flying, hear the game from the drone's camera instead of from the gunner seat on the ship."); ShipClearance = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "ShipClearance", 100f, "Drones can fly this close (m) to the ship's hull before its repulsion field pushes the ship away (and drops cruise mode / the Void Hive Mind)."); CameraHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Height", 7.7f, "Chase camera height above the drone (m)."); AutopilotOrbitRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "OrbitRadius", 500f, "Radius (m) of the circle flown around the active mission objective. Host's setting applies."); AutopilotSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "Speed", 0.5f, "Cruising speed while circling or following, as a fraction of the ship's top speed (0-1). Host's setting applies."); AutopilotFollowDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "FollowDistance", 300f, "The ship stays within this distance (m) of the deployed drones. Host's setting applies."); HiveMindTileSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "TileSpacing", 0.41f, "Distance between the Void Hive Mind's mode tile symbols, as a fraction of the tile panel's length (0.33 = even thirds). Raise it if the outer symbols sit too far in."); AutopilotFollowRestart = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "FollowRestart", 1.6f, "The ship only sets off again once the drones are this many times FollowDistance away (a dead zone, so it doesn't keep correcting). Host's setting applies."); AutopilotDodgeRange = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "DodgeRange", 1500f, "Incoming enemy missiles within this distance (m) are tracked for dodging. 0 = no dodging. Host's setting applies."); AutopilotDodgeMargin = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "DodgeMargin", 120f, "A missile that will pass closer than this (m) is dodged. Host's setting applies."); AutopilotJinkRange = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "JinkRange", 800f, "Enemies within this distance (m) that target the ship or point their nose at it make the autopilot jink (sidestep in changing directions) to throw off their aim. Evasive focus: 1.5x. 0 = no jinking. Host's setting applies."); AutopilotJinkAimAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "JinkAimAngle", 20f, "An enemy whose nose points within this angle (degrees) of the ship counts as aiming at it."); AutopilotJinkStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "JinkStrength", 0.8f, "Sidestep speed as a share of the ship's top speed (Evasive focus; other focuses use 60% of it)."); AutopilotPing = ((BaseUnityPlugin)this).Config.Bind<bool>("Autopilot", "AutoPing", true, "The Void Hive Mind scans and pings each enemy (strongest first) and mission item once, for the crew. Host's setting applies."); AutopilotPingInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "PingInterval", 6f, "Seconds between automatic pings. Host's setting applies."); AutopilotPingRange = ((BaseUnityPlugin)this).Config.Bind<float>("Autopilot", "PingRange", 1500f, "Only targets within this distance (m) of the ship are pinged. Host's setting applies."); CockpitHud = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "CockpitHud", true, "First person: fighter-style HUD in the drone's colour (flight-path marker, horizon and pitch ladder relative to your ship, speed and hull beside the crosshair)."); ReticleLag = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "ReticleLag", 1f, "How far the HUD lags behind turns before settling: the crosshair, the turret HUD and the info panel in both views, plus the first-person readouts (0 = fixed, 1 = default, 2 = double)."); CrosshairDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "CrosshairDistance", 500f, "Third person: the crosshair sits where the drone's shots are this far ahead (m), below the screen centre because the camera is above the drone. 0 = screen centre."); CameraDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Distance", 28f, "Chase camera distance behind the drone (m)."); FirstPersonDefault = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "FirstPersonDefault", false, "Start in first-person view (camera at the drone's nose)."); CameraToggleKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Camera", "ToggleViewKey", (Key)36, "Switch between chase and first-person view while flying."); StaticNearShip = ((BaseUnityPlugin)this).Config.Bind<float>("Range", "StaticNearShip", 0.1f, "Film-grain static right next to the ship (0-1). It rises to full at MaxRange."); MaxRange = ((BaseUnityPlugin)this).Config.Bind<float>("Range", "MaxRange", 2000f, "Control range (m) from the ship. The view fills with static towards it; beyond it the drone is recalled."); WarningFraction = ((BaseUnityPlugin)this).Config.Bind<float>("Range", "WarningFraction", 0.1f, "The flashing turn-back warning shows in the last part of MaxRange (0.1 = last 10%, i.e. 200 m at 2 km)."); NoiseCap = ((BaseUnityPlugin)this).Config.Bind<float>("Range", "NoiseCap", 0.2f, "Screen noise stays at or below this (0-1) until NoiseCapFraction of MaxRange."); NoiseCapFraction = ((BaseUnityPlugin)this).Config.Bind<float>("Range", "NoiseCapFraction", 0.9f, "Noise stays at or below NoiseCap until this fraction of MaxRange (0.9 = 1800 m at 2 km), then rises to NoiseMax at MaxRange."); NoiseMax = ((BaseUnityPlugin)this).Config.Bind<float>("Range", "NoiseMax", 0.9f, "Strongest screen noise (0-1), reached at MaxRange."); MigrateConfig(); ApplyPatches(); Log.LogInfo((object)"Void Drones 0.26.2 loaded. Hello, Void!"); } private void MigrateConfig() { ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>("Internal", "ConfigVersion", 0, "Used to update old default settings. Don't edit."); if (val.Value < 8) { Migrate(AccelerationTime, 1.05f); Migrate(TurnSmoothing, 0.132f); Migrate(MouseSensitivity, 0.1f); Migrate(CameraHeight, 9f); Migrate(StrafeSpeedMultiplier, 0.5f); Migrate(MouseSensitivity, 0.085f); Migrate(MaxTurnRate, 100f); Migrate(RollSpeed, 90f); Migrate(CameraHeight, 8.1f); Migrate(ConfessorAccuracy, 2f); Migrate(ConfessorFireRate, 1.25f); Migrate(MenuStatic, 0.12f); Migrate(MenuStatic, 0.09f); Migrate(HiveMindTileSpacing, 0.37f); val.Value = 8; ((BaseUnityPlugin)this).Config.Save(); } } private static void Migrate(ConfigEntry<float> entry, float oldDefault) { if (Mathf.Abs(entry.Value - oldDefault) < 0.0001f) { float num = (float)((ConfigEntryBase)entry).DefaultValue; Log.LogInfo((object)$"Config {((ConfigEntryBase)entry).Definition}: {entry.Value} -> {num} (new default)"); entry.Value = num; } } private static void ApplyPatches() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown Harmony val = new Harmony("VoidDrones"); int num = 0; Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0) { try { val.CreateClassProcessor(type).Patch(); } catch (Exception ex) { num++; Log.LogError((object)("Patch " + type.Name + " failed and was skipped: " + ex.GetBaseException().Message)); } } } if (num > 0) { Log.LogWarning((object)$"{num} patch(es) failed; related features won't work"); } } private void Start() { if (Events.Instance == null) { Log.LogWarning((object)"VoidManager events unavailable; drone keys will also fire while typing in chat"); return; } Events.Instance.ChatWindowOpened += delegate { ChatOpen = true; }; Events.Instance.ChatWindowClosed += delegate { ChatOpen = false; }; } } public class VoidManagerPlugin : VoidPlugin { public override MultiplayerType MPType => (MultiplayerType)30; public override string Author => "YourName"; public override string Description => "Player-controlled drones and hijack missiles."; } } namespace VoidDrones.Patches { [HarmonyPatch(typeof(CruiseControlModule), "FixedUpdate")] internal static class CruiseAutopilotPatch { private static void Postfix(CruiseControlModule __instance) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)DroneAutopilot.Engaged == (Object)null) && !((Object)(object)__instance.Engine == (Object)null) && __instance.Engine.ThrustInputs.ContainsKey("Cruise")) { __instance.Engine.ThrustInputs["Cruise"] = Vector3.zero; __instance.Engine.TorqueInputs["Cruise"] = Vector3.zero; } } } [HarmonyPatch(typeof(EvaHandler), "FixedUpdateEva")] internal static class DeserterWarningPatch { private static readonly FieldRef<EvaHandler, bool> IsRunningKillRoutine = AccessTools.FieldRefAccess<EvaHandler, bool>("_isRunningKillRoutine"); private static readonly MethodInfo EndKillRoutine = AccessTools.Method(typeof(EvaHandler), "EndKillRoutine", (Type[])null, (Type[])null); private static void Postfix(EvaHandler __instance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) LocalPlayer instance = LocalPlayer.Instance; if (!((Object)(object)instance == (Object)null) && IsRunningKillRoutine.Invoke(__instance) && (instance.IsOnPlayerShip() || (int)((Player)instance).State != 0)) { EndKillRoutine?.Invoke(__instance, null); Plugin.Log.LogInfo((object)"Cleared a stuck void jump deserter warning (player is on the ship)"); } } } [HarmonyPatch(typeof(CompositeWeaponModule), "SendInput")] internal static class DroneBayFirePatch { private static bool Prefix(CompositeWeaponModule __instance, WeaponActionType inputType, object data) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) bool flag = (int)inputType == 3; bool flag2 = default(bool); int num; if ((int)inputType == 0) { if (data is bool) { flag2 = (bool)data; num = 1; } else { num = 0; } } else { num = 0; } bool flag3 = (byte)((uint)num & (flag2 ? 1u : 0u)) != 0; if (!flag && !flag3) { return true; } if ((Object)(object)((Component)__instance).GetComponent<DroneBayModule>() == (Object)null) { return true; } if (flag) { return false; } if (DroneController.ByBay.TryGetValue(((MonoBehaviourPun)__instance).photonView.ViewID, out var value) && (Object)(object)value != (Object)null) { return !value.Recalling; } return false; } } [HarmonyPatch(typeof(DestroyableComponent), "ApplyRawDamage")] internal static class DronePartDamagePatch { private static readonly Dictionary<DestroyableComponent, DroneController> Owners = new Dictionary<DestroyableComponent, DroneController>(); private static bool Prefix(DestroyableComponent __instance, float damageGiven, OrbitObject attacker) { if (!Owners.TryGetValue(__instance, out var value)) { value = ((Component)__instance).GetComponentInParent<DroneController>(); Owners[__instance] = value; } if ((Object)(object)value == (Object)null) { return true; } if ((Object)(object)attacker != (Object)null && (Object)(object)value.Craft != (Object)null && attacker.Faction == ((OrbitObject)value.Craft).Faction) { return false; } if ((Object)(object)value.Craft != (Object)null && !((AbstractCloneStarObject)value.Craft).IsBeingDestroyed) { ((OrbitObject)value.Craft).ApplyRawDamage(damageGiven, attacker); } return false; } public static void Forget(DroneController drone) { List<DestroyableComponent> list = new List<DestroyableComponent>(); foreach (KeyValuePair<DestroyableComponent, DroneController> owner in Owners) { if ((Object)(object)owner.Key == (Object)null || (Object)(object)owner.Value == (Object)(object)drone) { list.Add(owner.Key); } } foreach (DestroyableComponent item in list) { Owners.Remove(item); } } } [HarmonyPatch(typeof(OrbitObject), "ApplyRawDamage")] internal static class DroneDamageLogPatch { private static readonly Dictionary<int, float> NextLog = new Dictionary<int, float>(); private static void Postfix(OrbitObject __instance, float damageGiven, OrbitObject attacker) { if (!(damageGiven <= 0f) && DroneController.IsDrone((Component)(object)__instance)) { int instanceID = ((Object)__instance).GetInstanceID(); if (!NextLog.TryGetValue(instanceID, out var value) || !(Time.time < value)) { NextLog[instanceID] = Time.time + 2f; ManualLogSource log = Plugin.Log; PhotonView photonView = ((MonoBehaviourPun)__instance).photonView; log.LogInfo((object)(string.Format("Drone {0} hit for {1:0.#} by {2}: ", (photonView != null) ? new int?(photonView.ViewID) : ((int?)null), damageGiven, ((Object)(object)attacker != (Object)null) ? ((Object)attacker).name : "unknown") + $"{__instance.HitPoints:0}/{((ModifiablePrimitive<float, FloatModifier>)(object)((__instance is SpaceCraft) ? __instance : null)?.MaxHitPoints).Value:0} HP")); } } } } [HarmonyPatch(typeof(AbstractOrbitObjectEffect), "SpawnFollowEffect")] internal static class DroneFollowEffectSpawnPatch { private static void Postfix(AbstractOrbitObjectEffect __instance, AbstractFollowTarget __result) { DroneController droneController = (((Object)(object)__result != (Object)null) ? ((Component)__instance).GetComponentInParent<DroneController>() : null); if ((Object)(object)droneController != (Object)null) { DroneVfxRecolor.Whiten(((Component)__result).gameObject); TrailRenderer[] componentsInChildren = ((Component)__result).GetComponentsInChildren<TrailRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.AddComponent<DroneTrailBoost>().Drone = droneController; } } } } [HarmonyPatch(typeof(AbstractOrbitObjectEffect), "SpawnVfxInOrbitSpace", new Type[] { typeof(GameObject), typeof(Transform) })] internal static class DroneOrbitVfxSpawnPatch { private static void Postfix(AbstractOrbitObjectEffect __instance, GameObject __result) { if ((Object)(object)__result != (Object)null && (Object)(object)((Component)__instance).GetComponentInParent<DroneController>() != (Object)null) { DroneVfxRecolor.Whiten(__result); } } } [HarmonyPatch(typeof(PlayerInput), "GetLookVector")] internal static class DroneLookLockPatch { private static void Postfix(ref Vector2 __result) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (DroneBayModule.LocalPlayerSeated) { __result = Vector2.zero; } } } [HarmonyPatch(typeof(ProjectileUtils), "DoExplosionDamage")] internal static class DroneMineExplosionPatch { private static readonly MethodInfo IsInBlastRadius = AccessTools.Method(typeof(ProjectileUtils), "IsInBlastRadius", (Type[])null, (Type[])null); private static bool Prefix(OrbitObject sourceOrbitObject, float explosionDamage, float radius, DamageType damageType, OrbitObject owner) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)sourceOrbitObject == (Object)null || (Object)(object)((Component)sourceOrbitObject).GetComponent<DroneMine>() == (Object)null || sourceOrbitObject.Sector == (GameSessionSector)null || IsInBlastRadius == null) { return true; } if ((Object)(object)owner == (Object)null) { owner = sourceOrbitObject; } List<OrbitObject> orbitObjects = sourceOrbitObject.Sector.OrbitObjects; for (int num = orbitObjects.Count - 1; num >= 0; num--) { OrbitObject val = orbitObjects[num]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)sourceOrbitObject) && val.Faction != 1 && !(val is IEnvironmentalObject) && !(val is Swarm) && (bool)IsInBlastRadius.Invoke(null, new object[3] { sourceOrbitObject, val, radius })) { val.ApplyHitDamage(explosionDamage, owner, damageType, ((AbstractCloneStarObject)sourceOrbitObject).WorldPosition, ((AbstractCloneStarObject)sourceOrbitObject).WorldRotation, false); } } return false; } } [HarmonyPatch(typeof(NpcAI), "FixedUpdate")] internal static class DroneMovementPatch { private static bool Prefix(NpcAI __instance) { DroneController component = ((Component)__instance).GetComponent<DroneController>(); if ((Object)(object)component == (Object)null) { return true; } component.MovementTick(__instance.Movement); return false; } } [HarmonyPatch(typeof(ObjectFactory), "DestroyCloneStarObject")] internal static class DroneDestroyOwnershipPatch { private static void Prefix(AbstractCloneStarObject cloneStarObject) { if (!PhotonNetwork.IsMasterClient || (Object)(object)cloneStarObject == (Object)null || cloneStarObject.DestroyRequested || (Object)(object)((Component)cloneStarObject).GetComponent<DroneController>() == (Object)null) { return; } int actorNumber = PhotonNetwork.LocalPlayer.ActorNumber; int num = 0; PhotonView[] componentsInChildren = ((Component)cloneStarObject).GetComponentsInChildren<PhotonView>(true); foreach (PhotonView val in componentsInChildren) { if (!val.IsMine) { val.OwnerActorNr = actorNumber; val.ControllerActorNr = actorNumber; num++; } } if (num > 0) { Plugin.Log.LogInfo((object)$"Drone {((MonoBehaviourPun)cloneStarObject).photonView.ViewID}: host reclaimed {num} views before removing it"); } } } [HarmonyPatch(typeof(OrbitObject), "OnPhotonSerializeView")] internal static class DroneHitPointsAuthorityPatch { private static void Prefix(OrbitObject __instance, PhotonStream stream, out float __state) { __state = __instance.HitPoints; } private static void Postfix(OrbitObject __instance, PhotonStream stream, float __state) { if (stream.IsReading && __instance.HitPoints != __state && DroneController.IsDrone((Component)(object)__instance)) { __instance.HitPoints = __state; } } } [HarmonyPatch(typeof(MovementController), "WriteData")] internal static class DroneSyncWritePatch { private static bool Prefix(MovementController __instance, PhotonStream stream) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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) DroneController droneController = (DroneController.IsDrone((Component)(object)__instance.Transform) ? ((Component)__instance.Transform).GetComponent<DroneController>() : null); if ((Object)(object)droneController == (Object)null) { return true; } stream.SendNext((object)true); stream.SendNext((object)__instance.Velocity); stream.SendNext((object)droneController.SimulatedPosition); stream.SendNext((object)droneController.SimulatedRotation); stream.SendNext((object)__instance.AngularVelocity); return false; } } [HarmonyPatch(typeof(MovementController), "ReadData")] internal static class DroneSyncReadPatch { private static readonly FieldRef<MovementController, Vector3> PositionOffset = AccessTools.FieldRefAccess<MovementController, Vector3>("positionOffset"); private static readonly FieldRef<MovementController, Quaternion> RotationOffset = AccessTools.FieldRefAccess<MovementController, Quaternion>("rotationOffset"); private static readonly FieldRef<MovementController, bool> InitialPositionSet = AccessTools.FieldRefAccess<MovementController, bool>("initialPositionSet"); private static bool Prefix(MovementController __instance, PhotonStream stream, PhotonMessageInfo info) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) DroneController droneController = (DroneController.IsDrone((Component)(object)__instance.Transform) ? ((Component)__instance.Transform).GetComponent<DroneController>() : null); if ((Object)(object)droneController == (Object)null) { return true; } if (!(bool)stream.ReceiveNext()) { return false; } __instance.Velocity = (Vector3)stream.ReceiveNext(); Vector3 val = (Vector3)stream.ReceiveNext(); Quaternion val2 = (Quaternion)stream.ReceiveNext(); __instance.AngularVelocity = (Vector3)stream.ReceiveNext(); float num = Mathf.Min(0.5f, Mathf.Abs((float)(PhotonNetwork.Time - ((PhotonMessageInfo)(ref info)).SentServerTime))); Quaternion val3 = val2 * Quaternion.Euler(__instance.AngularVelocity * num); Vector3 val4 = val + val2 * (__instance.Velocity * num); ref Vector3 reference = ref PositionOffset.Invoke(__instance); ref Quaternion reference2 = ref RotationOffset.Invoke(__instance); reference = val4 - droneController.SimulatedPosition; reference2 = Quaternion.Inverse(droneController.SimulatedRotation) * val3; ref bool reference3 = ref InitialPositionSet.Invoke(__instance); if (!reference3 || ((Vector3)(ref reference)).magnitude > 50f + 0.5f * ((Vector3)(ref __instance.Velocity)).magnitude || Quaternion.Angle(reference2, Quaternion.identity) > 30f) { reference3 = true; __instance.Position += reference; __instance.Rotation *= reference2; reference = Vector3.zero; reference2 = Quaternion.identity; } return false; } } internal static class DronePerspective { private static readonly MethodInfo Reference = AccessTools.PropertyGetter(typeof(DronePerspective), "ReferencePosition"); private static readonly MethodInfo GetTransform = AccessTools.PropertyGetter(typeof(Component), "transform"); private static readonly MethodInfo GetPosition = AccessTools.PropertyGetter(typeof(Transform), "position"); public static Vector3 ReferencePosition { get { //IL_0015: 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_002a: Unknown result type (might be due to invalid IL or missing references) DroneController localPiloted = DroneController.LocalPiloted; if ((Object)(object)localPiloted != (Object)null) { return ((Component)localPiloted).transform.position; } LocalPlayer instance = LocalPlayer.Instance; if (!((Object)(object)instance != (Object)null)) { return Vector3.zero; } return ((Component)instance).transform.position; } } public static IEnumerable<CodeInstruction> ReplacePlayerPosition(IEnumerable<CodeInstruction> instructions, MethodBase original) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); int num = 0; for (int i = 0; i + 2 < list.Count; i++) { if (list[i].opcode == OpCodes.Call && list[i].operand is MethodInfo methodInfo && methodInfo.DeclaringType == typeof(LocalPlayer) && (methodInfo.Name == "get_I" || methodInfo.Name == "get_Instance") && CodeInstructionExtensions.Calls(list[i + 1], GetTransform) && CodeInstructionExtensions.Calls(list[i + 2], GetPosition)) { list[i].operand = Reference; list[i + 1].opcode = OpCodes.Nop; list[i + 1].operand = null; list[i + 2].opcode = OpCodes.Nop; list[i + 2].operand = null; num++; } } if (num == 0) { Plugin.Log.LogWarning((object)("Drone perspective: no player position found in " + original.DeclaringType?.Name + "." + original.Name)); } return list; } } [HarmonyPatch] internal static class DroneMarkerDistancePatch { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(ObjectMarkerData), "UpdateDistance", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(ObjectMarkerViewer), "IsVisible", new Type[1] { typeof(ObjectMarkerData) }, (Type[])null); yield return AccessTools.Method(typeof(ObjectMarkerTooltip), "UpdateDistanceLabel", (Type[])null, (Type[])null); } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase __originalMethod) { return DronePerspective.ReplacePlayerPosition(instructions, __originalMethod); } } [HarmonyPatch(typeof(ScanComponent), "UpdatePassiveScan")] internal static class DroneScanPatch { private static readonly Action<ScanComponent, OrbitObject, OrbitObject, Vector3, float> PassiveScanObject = AccessTools.MethodDelegate<Action<ScanComponent, OrbitObject, OrbitObject, Vector3, float>>(AccessTools.Method(typeof(ScanComponent), "PassiveScanObject", (Type[])null, (Type[])null), (object)null, true); private static readonly List<DroneController> Drones = new List<DroneController>(); private static void Postfix(ScanComponent __instance) { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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) if (DroneController.ByBay.Count == 0 || Plugin.DroneScanRadius.Value <= 0f) { return; } Drones.Clear(); foreach (DroneController value in DroneController.ByBay.Values) { if ((Object)(object)value != (Object)null && (Object)(object)value.Craft != (Object)null && !((AbstractCloneStarObject)value.Craft).IsBeingDestroyed) { Drones.Add(value); } } if (Drones.Count == 0) { return; } ClientGame current2 = ClientGame.Current; OrbitObject val = (OrbitObject)(object)((current2 != null) ? current2.PlayerShip : null); foreach (OrbitObject activeOrbitObject in GameSessionManager.ActiveOrbitObjects) { if (!CGExtensions.Valid((IDamageable)(object)activeOrbitObject) || !activeOrbitObject.CanBeScanned || activeOrbitObject == val || DroneController.IsDrone((Component)(object)activeOrbitObject) || ((Enum)__instance.GetScanFlags(activeOrbitObject)).HasFlag((Enum)(object)(ScanFlags)4)) { continue; } foreach (DroneController drone in Drones) { PassiveScanObject(__instance, activeOrbitObject, (OrbitObject)(object)drone.Craft, drone.SimulatedPosition, Plugin.DroneScanRadius.Value); if (((Enum)__instance.GetScanFlags(activeOrbitObject)).HasFlag((Enum)(object)(ScanFlags)4)) { break; } } } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class DroneAggroSourcePatch { private static void Postfix(SignalHitFromSource __instance) { OrbitObject source = __instance.Source; CompositeWeaponModule val = (CompositeWeaponModule)(object)((source is CompositeWeaponModule) ? source : null); if (val != null && (Object)(object)((MonoBehaviourPun)val).photonView != (Object)null && DroneController.ByBay.TryGetValue(((MonoBehaviourPun)val).photonView.ViewID, out var value) && (Object)(object)value != (Object)null && (Object)(object)value.Craft != (Object)null && !((AbstractCloneStarObject)value.Craft).IsBeingDestroyed) { __instance.Source = (OrbitObject)(object)value.Craft; } } } [HarmonyPatch(typeof(TargetSelector), "GetClosestOpponent")] internal static class DroneTargetSelectionPatch { private static readonly FieldRef<TargetSelector, OrbitObject> Owner = AccessTools.FieldRefAccess<TargetSelector, OrbitObject>("_owner"); private static void Postfix(TargetSelector __instance, ref OrbitObject __result) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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) if (DroneController.ByBay.Count == 0) { return; } OrbitObject val = Owner.Invoke(__instance); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponent<DroneController>() != (Object)null) { return; } float num = (((Object)(object)__result != (Object)null) ? Mathf.Max(0f, Vector3.Distance(((AbstractCloneStarObject)__result).WorldPosition, ((AbstractCloneStarObject)val).WorldPosition) - __result.SignatureRadius) : float.MaxValue); float value = Plugin.DroneTargetRange.Value; float num2 = Mathf.Max(0.01f, Plugin.DroneTargetBias.Value); foreach (DroneController value2 in DroneController.ByBay.Values) { SpaceCraft val2 = (((Object)(object)value2 != (Object)null) ? value2.Craft : null); if (!((Object)(object)val2 == (Object)null) && !((AbstractCloneStarObject)val2).IsBeingDestroyed && ((OrbitObject)val2).IsTargetable && val.IsObjectFromEnemyFaction((IOrbitObject)(object)val2) && !(((OrbitObject)val2).Sector != val.Sector)) { float num3 = Vector3.Distance(((AbstractCloneStarObject)val2).WorldPosition, ((AbstractCloneStarObject)val).WorldPosition); if (num3 <= value && num3 * num2 < num) { num = num3 * num2; __result = (OrbitObject)(object)val2; } } } } } [HarmonyPatch(typeof(CraftData), "TryAddItem")] internal static class FabricatorVariantPatch { private static bool Prefix(GUIDUnion carryableGuid) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (DroneBayAssets.TryGetVariant(carryableGuid, out var variant)) { return variant.Offered; } return true; } } [HarmonyPatch(typeof(AutoMechanicAction), "FixedUpdate")] internal static class HiveMindActionPatch { private static readonly ConditionalWeakTable<AutoMechanicAction, CellModule> HiveMinds = new ConditionalWeakTable<AutoMechanicAction, CellModule>(); private static readonly ConditionalWeakTable<AutoMechanicAction, object> NotHiveMinds = new ConditionalWeakTable<AutoMechanicAction, object>(); private static bool Prefix(AutoMechanicAction __instance) { if (NotHiveMinds.TryGetValue(__instance, out var _)) { return true; } if (!HiveMinds.TryGetValue(__instance, out var value2)) { if ((Object)(object)((Component)__instance).GetComponentInParent<DroneAutopilot>() == (Object)null) { NotHiveMinds.Add(__instance, null); return true; } value2 = ((Component)__instance).GetComponentInParent<CellModule>(); HiveMinds.Add(__instance, value2); } if ((Object)(object)value2 != (Object)null && value2.IsPowered) { __instance.RemainingTime = 0f; __instance.OnVisualUpdate?.Invoke(); } return false; } } internal static class HiveMindSoundPatch { [HarmonyPatch(typeof(StudioEventEmitter), "PlayInstance")] internal static class EmitterPatch { private static void Postfix(StudioEventEmitter __instance) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (IsHiveMindLever((Component)(object)__instance)) { EventInstance eventInstance = __instance.EventInstance; if (((EventInstance)(ref eventInstance)).isValid()) { eventInstance = __instance.EventInstance; ((EventInstance)(ref eventInstance)).setPitch(0.75f); } } } } [HarmonyPatch(typeof(TriggeredSound), "PlayPrimarySound")] internal static class TriggeredPatch { private static readonly FieldRef<TriggeredSound, EventInstance> Instance = AccessTools.FieldRefAccess<TriggeredSound, EventInstance>("soundEventInstance"); private static void Postfix(TriggeredSound __instance) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (IsHiveMindLever((Component)(object)__instance)) { EventInstance val = Instance.Invoke(__instance); if (((EventInstance)(ref val)).isValid()) { ((EventInstance)(ref val)).setPitch(0.75f); } } } } internal const float Pitch = 0.75f; private const string LeverName = "Interactable_MultiSwitch"; private static readonly ConditionalWeakTable<Component, object> Lever = new ConditionalWeakTable<Component, object>(); private static readonly ConditionalWeakTable<Component, object> NotLever = new ConditionalWeakTable<Component, object>(); internal static bool IsHiveMindLever(Component component) { if ((Object)(object)component == (Object)null) { return false; } if (Lever.TryGetValue(component, out var value)) { return true; } if (NotLever.TryGetValue(component, out value)) { return false; } bool flag = false; Transform val = component.transform; while ((Object)(object)val != (Object)null) { if (((Object)val).name.StartsWith("Interactable_MultiSwitch")) { flag = true; break; } val = val.parent; } int num; if (flag) { num = (((Object)(object)component.GetComponentInParent<DroneAutopilot>() != (Object)null) ? 1 : 0); if (num != 0) { Lever.Add(component, null); return (byte)num != 0; } } else { num = 0; } NotLever.Add(component, null); return (byte)num != 0; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class PlayerShipSetPatch { private static void Postfix(PlayerControlledShip value) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)value == (Object)null) { Plugin.Log.LogInfo((object)"Player ship cleared"); } else { Plugin.Log.LogInfo((object)$"Player ship set: {((Object)value).name} (faction {((OrbitObject)value).Faction}, guid {((AbstractCloneStarObject)value).ContainerGuid})"); } } } [HarmonyPatch(typeof(RuntimeAssetLoadingService), "Initialize")] internal static class RuntimeAssetLoadingPatch { private static void Postfix(ref IEnumerator __result) { __result = RunThenRegister(__result); } private static IEnumerator RunThenRegister(IEnumerator original) { while (original.MoveNext()) { yield return original.Current; } try { DroneBayAssets.Register(); } catch (Exception arg) { Plugin.Log.LogError((object)string.Format("Failed to register {0}: {1}", "Void Drone Controller", arg)); } try { DroneAssets.Register(); } catch (Exception arg2) { Plugin.Log.LogError((object)string.Format("Failed to register {0}: {1}", "Drone", arg2)); } try { DroneMineAssets.Register(); } catch (Exception arg3) { Plugin.Log.LogError((object)$"Failed to register the drone mine: {arg3}"); } try { AutopilotAssets.Register(DroneBayAssets.GetFabricatorLists()); } catch (Exception arg4) { Plugin.Log.LogError((object)string.Format("Failed to register the {0}: {1}", "Void Hive Mind", arg4)); } DroneLoot.MirrorEndlessRewards(); } } [HarmonyPatch] internal static class SilverCratePatch { private static readonly Color Silver = new Color(0.8f, 0.82f, 0.86f, 1f); private static readonly HashSet<string> Logged = new HashSet<string>(); private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(CompositeWeaponBuildBox), "OnPhotonInstantiate", (Type[])null, (Type[])null); yield return AccessTools.PropertySetter(typeof(CompositeWeaponBuildBox), "ExtraJData"); yield return AccessTools.Method(typeof(BuildBoxActor), "Start", (Type[])null, (Type[])null); } private static void Postfix(MonoBehaviour __instance) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) CompositeWeaponBuildBox val = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponent<CompositeWeaponBuildBox>() : null); if ((Object)(object)val == (Object)null || (ResourceAssetRef)(object)val.WeaponDataRef == (ResourceAssetRef)null || ((ResourceAssetRef)val.WeaponDataRef).IsNull || !DroneBayAssets.TryGetVariant(((ResourceAssetRef)val.WeaponDataRef).AssetGuid, out var variant)) { return; } Color strongTint = variant.Type.Palette.StrongTint; int num = 0; List<string> list = new List<string>(); Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if (val2 is ParticleSystemRenderer || val2 is TrailRenderer || val2 is LineRenderer || (Object)(object)((Component)val2).GetComponent<VisualEffect>() != (Object)null) { continue; } Material[] materials = val2.materials; foreach (Material val3 in materials) { string text = Describe(val3); bool flag = (Object)(object)val3 != (Object)null && ((Object)val3).name.IndexOf("Diode", StringComparison.OrdinalIgnoreCase) < 0 && (((Object)val3).name.IndexOf("Lamp", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)val3).name.IndexOf("Emissive", StringComparison.OrdinalIgnoreCase) >= 0); bool flag2 = !flag && ControllerStyle.MakeSilver(val3, killGlow: true); if (flag) { ControllerStyle.MakeGlow(val3, strongTint, emissionOnly: true); } if (flag2 || flag) { num++; } list.Add(((Object)val2).name + ": " + text + (flag ? " -> drone colour" : (flag2 ? " -> silver" : " (kept)"))); } } if (Logged.Add(((Object)val).name + "/" + ((object)__instance).GetType().Name)) { Plugin.Log.LogInfo((object)($"Controller crate {((Object)val).name} ({((object)__instance).GetType().Name}): {num} materials made silver. " + "Materials: " + string.Join("; ", list))); } } private static string Describe(Material material) { //IL_0049: 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 ((Object)(object)material == (Object)null) { return "null"; } string text = ((Object)material).name + " [" + ((Object)material.shader).name + "]"; if (material.HasProperty("_BaseColor")) { text += string.Format(" base={0}", material.GetColor("_BaseColor")); } if (material.HasProperty("_EmissiveColor")) { text += string.Format(" glow={0}", material.GetColor("_EmissiveColor")); } return text; } } public class SilverCrateMarker : MonoBehaviour { } [HarmonyPatch(typeof(VoidJumpAligning), "OnEnter")] internal static class VoidJumpAligningRecallPatch { private static void Postfix() { DroneLauncher.RecallAll("void jump started"); } } [HarmonyPatch(typeof(VoidJumpSpinningUp), "OnEnter")] internal static class VoidJumpSpinningUpRecallPatch { private static void Postfix() { DroneLauncher.RecallAll("void jump started"); } } } namespace VoidDrones.Content { internal static class AutopilotAssets { public static readonly GUIDUnion AutopilotGuid = new GUIDUnion("b7e3d1a04c5f4e2a9d16f0c8a2e5b341"); public static readonly GUIDUnion BoxGuid = new GUIDUnion("b7e3d1a04c5f4e2a9d16f0c8a2e5b342"); public const string DisplayName = "Void Hive Mind"; private const string Description = "A drone-linked brain module wired into the helm. While cruise mode is engaged it flies the ship: it keeps close to your deployed drones, circles the active mission objective, dodges incoming missiles and pings enemies, crates and mission items for the crew. Any helm input takes back control."; private static bool registered; public static readonly string[] FocusNames = new string[3] { "Objectives", "Drones", "Evasive" }; private static readonly string[] FocusDescriptions = new string[3] { "Focus: OBJECTIVES - circle the mission objective, then follow drones", "Focus: DRONES - stay with the drones, then the objective", "Focus: EVASIVE - dodge first, from further out" }; public static void Register(List<(string mode, int tier, CraftableDataList list)> fabricatorLists) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: 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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown //IL_0167: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Expected O, but got Unknown //IL_01a4: Expected O, but got Unknown //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Expected O, but got Unknown //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) if (registered) { return; } ModuleContainer instance = ResourceAssetContainer<ModuleContainer, CellModule, ModuleDef>.Instance; List<ModuleDef> list = ((ResourceAssetContainer<ModuleContainer, CellModule, ModuleDef>)(object)instance).AssetDescriptions.Where((ModuleDef def) => ((ResourceAssetDef<CellModule>)(object)def)?.Asset is AutoMechanicModule).ToList(); if (list.Count == 0) { Plugin.Log.LogError((object)"No Auto-Mechanic module found in the game data; the Void Hive Mind is not registered"); return; } ModuleDef val = list.OrderBy((ModuleDef def) => ((Object)((ResourceAssetDef<CellModule>)(object)def).Asset).name.Length).First(); AutoMechanicModule val2 = (AutoMechanicModule)((ResourceAssetDef<CellModule>)(object)val).Asset; GameObject val3 = PrefabCloner.Clone(((Component)val2).gameObject, "Module_VoidDrones_Autopilot", AutopilotGuid); string text = RelabelLever(val3); string text2 = "colours " + HiveMindVisuals.ApplyColours(val3) + "; " + HiveMindVisuals.AddCrystals(val3) + "; " + RemoveEnhancementPanel(val3); val3.AddComponent<HiveMindLever>(); val3.AddComponent<DroneAutopilot>(); VirtualResources.Add(AutopilotGuid, (Object)(object)val3); RuntimeAssetsRegister.Instance.RegisterAsset(AutopilotGuid, (Object)(object)val3, (SessionModificationEffect)2, new RuntimeAssetInfo { Name = ((Object)val3).name, DisplayName = "Void Hive Mind" }); CloneStarObjectContainer instance2 = ResourceAssetContainer<CloneStarObjectContainer, AbstractCloneStarObject, CloneStarObjectDef>.Instance; Sprite val4 = IconFactory.HiveMindIcon(); GUIDUnion autopilotGuid = AutopilotGuid; CloneStarObjectDef val5 = new CloneStarObjectDef(); ((ResourceAssetDef<AbstractCloneStarObject>)val5).Ref = (ResourceAssetRef)new CloneStarObjectRef { AssetGuid = AutopilotGuid }; val5.ContextInfo = (IResourceAssetContextInfo)(object)ContextInfo.Create(val4, "Void Hive Mind", "A drone-linked brain module wired into the helm. While cruise mode is engaged it flies the ship: it keeps close to your deployed drones, circles the active mission objective, dodges incoming missiles and pings enemies, crates and mission items for the crew. Any helm input takes back control."); ((ResourceAssetContainer<CloneStarObjectContainer, AbstractCloneStarObject, CloneStarObjectDef>)(object)instance2).RegisterRuntimeAsset(autopilotGuid, val5); GUIDUnion autopilotGuid2 = AutopilotGuid; ModuleDef val6 = new ModuleDef(); ((ResourceAssetDef<CellModule>)val6).Ref = (ResourceAssetRef)new ModuleRef { AssetGuid = AutopilotGuid }; val6.Category = val.Category; ((ResourceAssetContainer<ModuleContainer, CellModule, ModuleDef>)(object)instance).RegisterRuntimeAsset(autopilotGuid2, val6); string text3 = RegisterBuildBox((CellModule)(object)val2, val3, fabricatorLists, val4); registered = true; Plugin.Log.LogInfo((object)(string.Format("Registered {0} {1} from {2} ({3}, category {4}; ", "Void Hive Mind", AutopilotGuid, ((Object)val2).name, ((ResourceAssetDef<CellModule>)(object)val).AssetGuid, val.Category) + "lever: " + text + "; " + text3 + "). Icons: " + text2 + ". Auto-Mechanics: " + string.Join(", ", list.Select((ModuleDef def) => ((Object)((ResourceAssetDef<CellModule>)(object)def).Asset).name)))); } private static string RegisterBuildBox(CellModule baseModule, GameObject moduleTemplate, List<(string mode, int tier, CraftableDataList list)> fabricatorLists, Sprite icon) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010a: 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_0119: Expected O, but got Unknown //IL_0119: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_0134: 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_013a: 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) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_014f: Expected O, but got Unknown //IL_0151: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0170: 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_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown //IL_018b: Expected O, but got Unknown //IL_018d: Expected O, but got Unknown //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0213: 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_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) GUIDUnion val = (GUIDUnion)(((ResourceAssetRef)(object)baseModule.BuildBoxRef != (ResourceAssetRef)null) ? ((ResourceAssetRef)baseModule.BuildBoxRef).AssetGuid : default(GUIDUnion)); CarryableContainer instance = ResourceAssetContainer<CarryableContainer, CarryableObject, CarryableDef>.Instance; CarryableDef val2 = default(CarryableDef); if (((ResourceAssetContainer<CarryableContainer, CarryableObject, CarryableDef>)(object)instance).TryGetByGuid(val, ref val2)) { CarryableObject asset = ((ResourceAssetDef<CarryableObject>)(object)val2).Asset; BuildBox val3 = (BuildBox)(object)((asset is BuildBox) ? asset : null); if (val3 != null) { GameObject val4 = PrefabCloner.Clone(((Component)val3).gameObject, "BuildBox_VoidDrones_HiveMind", BoxGuid); val4.GetComponent<BuildBox>().moduleRef = new CloneStarObjectRef { AssetGuid = AutopilotGuid }; moduleTemplate.GetComponent<CellModule>().BuildBoxRef = new CloneStarObjectRef { AssetGuid = BoxGuid }; VirtualResources.Add(BoxGuid, (Object)(object)val4); RuntimeAssetsRegister.Instance.RegisterAsset(BoxGuid, (Object)(object)val4, (SessionModificationEffect)2, new RuntimeAssetInfo { Name = ((Object)val4).name, DisplayName = "Void Hive Mind" }); CloneStarObjectContainer instance2 = ResourceAssetContainer<CloneStarObjectContainer, AbstractCloneStarObject, CloneStarObjectDef>.Instance; GUIDUnion boxGuid = BoxGuid; CloneStarObjectDef val5 = new CloneStarObjectDef(); ((ResourceAssetDef<AbstractCloneStarObject>)val5).Ref = (ResourceAssetRef)new CloneStarObjectRef { AssetGuid = BoxGuid }; val5.ContextInfo = (IResourceAssetContextInfo)(object)ContextInfo.Create(icon, "Void Hive Mind", "A drone-linked brain module wired into the helm. While cruise mode is engaged it flies the ship: it keeps close to your deployed drones, circles the active mission objective, dodges incoming missiles and pings enemies, crates and mission items for the crew. Any helm input takes back control."); ((ResourceAssetContainer<CloneStarObjectContainer, AbstractCloneStarObject, CloneStarObjectDef>)(object)instance2).RegisterRuntimeAsset(boxGuid, val5); CarryableDef val6 = new CarryableDef(); ((ResourceAssetDef<CarryableObject>)val6).Ref = (ResourceAssetRef)new CarryableRef { AssetGuid = BoxGuid }; CarryableDef val7 = val6; ((PurchasableResourceAssetDef<CarryableObject>)(object)val7).SetPurchaseCategory(((PurchasableResourceAssetDef<CarryableObject>)(object)val2).Category); ((ResourceAssetContainer<CarryableContainer, CarryableObject, CarryableDef>)(object)instance).RegisterRuntimeAsset(BoxGuid, val7); CraftingDataContainer instance3 = ResourceAssetContainer<CraftingDataContainer, Object, CraftableItemDef>.Instance; CraftableItemDef val8 = new CraftableItemDef(); ((ResourceAssetDef<Object>)val8).Ref = (ResourceAssetRef)new CraftableItemRef { AssetGuid = BoxGuid }; CraftableItemDef val9 = val8; CraftableItemDef val10 = default(CraftableItemDef); bool flag = ((ResourceAssetContainer<CraftingDataContainer, Object, CraftableItemDef>)(object)instance3).TryGetByGuid(val, ref val10); val9.SetCraftingRules((CraftingRules)(flag ? val10.CraftingRules : new CraftingRules { CanBeRecycled = true, CraftingMethod = (CraftMethod)2, Creation = new ResourceCurrency((ResourceType)2, 300), Recycle = new ResourceCurrency((ResourceType)2, 150) })); ((ResourceAssetContainer<CraftingDataContainer, Object, CraftableItemDef>)(object)instance3).RegisterRuntimeAsset(BoxGuid, val9); DroneBayAssets.RegisterAlwaysUnlocked(BoxGuid, val); DroneBayAssets.RegisterAlwaysUnlocked(AutopilotGuid, ((AbstractCloneStarObject)baseModule).ContainerGuid); DroneBayAssets.AddToFabricator(fabricatorLists, val, val, BoxGuid, "Void Hive Mind"); DroneLoot.AddMirror(val, BoxGuid); return string.Format("build box {0} from {1} ({2}, purchase category {3}, crafting rules {4})", BoxGuid, ((Object)val3).name, val, ((PurchasableResourceAssetDef<CarryableObject>)(object)val2).Category, flag ? "copied" : "fallback"); } } Plugin.Log.LogError((object)string.Format("The Auto-Mechanic's build box ({0}) wasn't found; {1} can't be built", val, "Void Hive Mind")); return "no build box"; } private static string RemoveEnhancementPanel(GameObject template) { Transform[] componentsInChildren = template.GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name == "Enhancement_StandingPanel") { ((Component)val).gameObject.SetActive(false); return "enhancement panel switched off"; } } return "enhancement panel not found"; } private static string RelabelLever(GameObject template) { int num = 0; List<string> list = new List<string>(); MultiOptionClicker[] componentsInChildren = template.GetComponentsInChildren<MultiOptionClicker>(true); foreach (MultiOptionClicker val in componentsInChildren) { list.Add(((object)val).GetType().Name + " " + ((Object)val).name); Traverse val2 = Traverse.Create((object)val).Field("interactionInfos"); InteractionInfo[] array = val2.GetValue<InteractionInfo[]>(); if (array == null || array.Length == 0) { InteractionInfo value = Traverse.Create((object)val).Field("interactionInfo").GetValue<InteractionInfo>(); array = (InteractionInfo[])(object)((!((Object)(object)value != (Object)null)) ? null : new InteractionInfo[3] { value, value, value }); } if (array == null) { continue; } InteractionInfo[] array2 = (InteractionInfo[])(object)new InteractionInfo[array.Length]; for (int j = 0; j < array.Length; j++) { if ((Object)(object)array[j] == (Object)null) { continue; } InteractionInfo val3 = Object.Instantiate<InteractionInfo>(array[j]); ((Object)val3).name = ((Object)array[j]).name + "_HiveMind"; ((Object)val3).hideFlags = (HideFlags)32; string text = ((j < FocusDescriptions.Length) ? FocusDescriptions[j] : "Hive Mind focus"); foreach (InteractionDescription item in val3.Interactions ?? new List<InteractionDescription>()) { item.Description = Fixed(text); } array2[j] = val3; num++; } val2.Se