/// <summary> /// Static constructor - go find which plugins are installed. /// </summary> static MASIdEngine() { ajePropellerAPI_t = Utility.GetExportedType("AJE", "AJE.ModuleEnginesAJEPropeller"); ajeJetAPI_t = Utility.GetExportedType("AJE", "AJE.ModuleEnginesAJEJet"); if (ajePropellerAPI_t != null && ajeJetAPI_t != null) { FieldInfo propRPM_t = ajePropellerAPI_t.GetField("propRPM", BindingFlags.Instance | BindingFlags.Public); if (propRPM_t == null) { Utility.LogStaticError("propRPM_t is null"); return; } getPropRPM = DynamicMethodFactory.CreateGetField <object, float>(propRPM_t); FieldInfo propPitch_t = ajePropellerAPI_t.GetField("propPitch", BindingFlags.Instance | BindingFlags.Public); if (propPitch_t == null) { Utility.LogStaticError("propPitch_t is null"); return; } getPropPitch = DynamicMethodFactory.CreateGetField <object, float>(propPitch_t); FieldInfo propThrust_t = ajePropellerAPI_t.GetField("propThrust", BindingFlags.Instance | BindingFlags.Public); if (propThrust_t == null) { Utility.LogStaticError("propThrust_t is null"); return; } getPropThrust = DynamicMethodFactory.CreateGetField <object, float>(propThrust_t); FieldInfo manifoldPressure_t = ajePropellerAPI_t.GetField("manifoldPressure", BindingFlags.Instance | BindingFlags.Public); if (manifoldPressure_t == null) { Utility.LogStaticError("manifoldPressure_t is null"); return; } getManifoldPressure = DynamicMethodFactory.CreateGetField <object, float>(manifoldPressure_t); FieldInfo chargeAirTemp_t = ajePropellerAPI_t.GetField("chargeAirTemp", BindingFlags.Instance | BindingFlags.Public); if (chargeAirTemp_t == null) { Utility.LogStaticError("chargeAirTemp_t is null"); return; } getChargeAirTemp = DynamicMethodFactory.CreateGetField <object, float>(chargeAirTemp_t); FieldInfo netExhaustThrust_t = ajePropellerAPI_t.GetField("netExhaustThrust", BindingFlags.Instance | BindingFlags.Public); if (netExhaustThrust_t == null) { Utility.LogStaticError("netExhaustThrust_t is null"); return; } getNetExhaustThrust = DynamicMethodFactory.CreateGetField <object, float>(netExhaustThrust_t); FieldInfo netMeredithEffect_t = ajePropellerAPI_t.GetField("netMeredithEffect", BindingFlags.Instance | BindingFlags.Public); if (netMeredithEffect_t == null) { Utility.LogStaticError("netMeredithEffect_t is null"); return; } getNetMeredithEffect = DynamicMethodFactory.CreateGetField <object, float>(netMeredithEffect_t); FieldInfo brakeShaftPower_t = ajePropellerAPI_t.GetField("brakeShaftPower", BindingFlags.Instance | BindingFlags.Public); if (brakeShaftPower_t == null) { Utility.LogStaticError("brakeShaftPower_t is null"); return; } getBrakeShaftPower = DynamicMethodFactory.CreateGetField <object, float>(brakeShaftPower_t); FieldInfo boost_t = ajePropellerAPI_t.GetField("boost", BindingFlags.Instance | BindingFlags.Public); if (boost_t == null) { Utility.LogStaticError("boost_t is null"); return; } getBoost = DynamicMethodFactory.CreateGetField <object, float>(boost_t); setBoost = DynamicMethodFactory.CreateSetField <object, float>(boost_t); FieldInfo rpmLever_t = ajePropellerAPI_t.GetField("rpmLever", BindingFlags.Instance | BindingFlags.Public); if (rpmLever_t == null) { Utility.LogStaticError("rpmLever_t is null"); return; } getRpmLever = DynamicMethodFactory.CreateGetField <object, float>(rpmLever_t); setRpmLever = DynamicMethodFactory.CreateSetField <object, float>(rpmLever_t); FieldInfo mixture_t = ajePropellerAPI_t.GetField("mixture", BindingFlags.Instance | BindingFlags.Public); if (mixture_t == null) { Utility.LogStaticError("mixture_t is null"); return; } getMixture = DynamicMethodFactory.CreateGetField <object, float>(mixture_t); setMixture = DynamicMethodFactory.CreateSetField <object, float>(mixture_t); FieldInfo coreThrottle_t = ajeJetAPI_t.GetField("actualCoreThrottle", BindingFlags.Instance | BindingFlags.Public); if (coreThrottle_t == null) { Utility.LogStaticError("coreThrottle_t is null"); return; } getCoreThrottle = DynamicMethodFactory.CreateGetField <object, float>(coreThrottle_t); FieldInfo afterburnerThrottle_t = ajeJetAPI_t.GetField("actualABThrottle", BindingFlags.Instance | BindingFlags.Public); if (afterburnerThrottle_t == null) { Utility.LogStaticError("afterburnerThrottle_t is null"); return; } getAfterburnerThrottle = DynamicMethodFactory.CreateGetField <object, float>(afterburnerThrottle_t); FieldInfo maxEngineTemp_t = ajeJetAPI_t.GetField("maxEngineTemp", BindingFlags.Instance | BindingFlags.Public); if (maxEngineTemp_t == null) { Utility.LogStaticError("maxEngineTemp_t is null"); return; } getMaxJetTemp = DynamicMethodFactory.CreateGetField <object, double>(maxEngineTemp_t); FieldInfo currentEngineTemp_t = ajeJetAPI_t.GetField("engineTempString", BindingFlags.Instance | BindingFlags.Public); if (currentEngineTemp_t == null) { Utility.LogStaticError("currentEngineTemp_t is null"); return; } getCurrentJetTemp = DynamicMethodFactory.CreateGetField <object, string>(currentEngineTemp_t); ajeInstalled = true; } }
static MASIVTOL() { wbiVtolManager_t = Utility.GetExportedType("KerbalActuators", "KerbalActuators.WBIVTOLManager"); if (wbiVtolManager_t != null) { // Init MethodInfo FindControllers_t = wbiVtolManager_t.GetMethod("FindControllers", BindingFlags.Instance | BindingFlags.Public); if (FindControllers_t == null) { Utility.LogStaticError("Didn't find FindControllers"); return; } wbiFindControllers = DynamicMethodFactory.CreateAction <object, Vessel>(FindControllers_t); // Capabilities MethodInfo AirParkControllerActive_t = wbiVtolManager_t.GetMethod("AirParkControllerActive", BindingFlags.Instance | BindingFlags.Public); if (AirParkControllerActive_t != null) { wbiAirParkAvailable = DynamicMethodFactory.CreateFunc <object, bool>(AirParkControllerActive_t); } else { Utility.LogStaticError("Didn't find AirParkControllerActive"); return; } MethodInfo HoverControllerActive_t = wbiVtolManager_t.GetMethod("HoverControllerActive", BindingFlags.Instance | BindingFlags.Public); if (HoverControllerActive_t != null) { wbiHoverControllerAvailable = DynamicMethodFactory.CreateFunc <object, bool>(HoverControllerActive_t); } else { Utility.LogStaticError("Didn't find HoverControllerActive"); return; } MethodInfo HasRotationControllers_t = wbiVtolManager_t.GetMethod("HasRotationControllers", BindingFlags.Instance | BindingFlags.Public); if (HasRotationControllers_t != null) { wbiRotationControllerAvailable = DynamicMethodFactory.CreateFunc <object, bool>(HasRotationControllers_t); } else { Utility.LogStaticError("Didn't find HasRotationControllers"); return; } MethodInfo ThrustVectorControllerActive_t = wbiVtolManager_t.GetMethod("ThrustVectorControllerActive", BindingFlags.Instance | BindingFlags.Public); if (ThrustVectorControllerActive_t != null) { wbiThrustControllerAvailable = DynamicMethodFactory.CreateFunc <object, bool>(ThrustVectorControllerActive_t); } else { Utility.LogStaticError("Didn't find ThrustVectorControllerActive"); return; } // Air Park MethodInfo IsParked_t = wbiVtolManager_t.GetMethod("IsParked", BindingFlags.Instance | BindingFlags.Public); if (IsParked_t == null) { Utility.LogStaticError("Didn't find IsParked"); return; } wbiGetParkActive = DynamicMethodFactory.CreateFunc <object, bool>(IsParked_t); MethodInfo TogglePark_t = wbiVtolManager_t.GetMethod("TogglePark", BindingFlags.Instance | BindingFlags.Public); if (TogglePark_t == null) { Utility.LogStaticError("Didn't find TogglePark"); return; } wbiTogglePark = DynamicMethodFactory.CreateAction <object>(TogglePark_t); // Hover MethodInfo EnginesAreActive_t = wbiVtolManager_t.GetMethod("EnginesAreActive", BindingFlags.Instance | BindingFlags.Public); if (EnginesAreActive_t == null) { Utility.LogStaticError("Didn't find EnginesAreActive"); return; } wbiEnginesAreActive = DynamicMethodFactory.CreateFunc <object, bool>(EnginesAreActive_t); MethodInfo StartEngines_t = wbiVtolManager_t.GetMethod("StartEngines", BindingFlags.Instance | BindingFlags.Public); if (StartEngines_t == null) { Utility.LogStaticError("Didn't find StartEngines"); return; } wbiStartEngines = DynamicMethodFactory.CreateAction <object>(StartEngines_t); MethodInfo StopEngines_t = wbiVtolManager_t.GetMethod("StopEngines", BindingFlags.Instance | BindingFlags.Public); if (StopEngines_t == null) { Utility.LogStaticError("Didn't find StopEngines"); return; } wbiStopEngines = DynamicMethodFactory.CreateAction <object>(StopEngines_t); FieldInfo HoverActive_t = wbiVtolManager_t.GetField("hoverActive", BindingFlags.Instance | BindingFlags.Public); if (HoverActive_t == null) { Utility.LogStaticError("Didn't find hoverActive"); return; } wbiGetHoverActive = DynamicMethodFactory.CreateGetField <object, bool>(HoverActive_t); MethodInfo ToggleHover_t = wbiVtolManager_t.GetMethod("ToggleHover", BindingFlags.Instance | BindingFlags.Public); if (ToggleHover_t == null) { Utility.LogStaticError("Didn't find ToggleHover"); return; } wbiToggleHover = DynamicMethodFactory.CreateAction <object>(ToggleHover_t); // Rotation MethodInfo CanRotateMax_t = wbiVtolManager_t.GetMethod("CanRotateMax", BindingFlags.Instance | BindingFlags.Public); if (CanRotateMax_t == null) { Utility.LogStaticError("Didn't find CanRotateMax"); return; } wbiCanRotateMax = DynamicMethodFactory.CreateFunc <object, bool>(CanRotateMax_t); MethodInfo CanRotateMin_t = wbiVtolManager_t.GetMethod("CanRotateMin", BindingFlags.Instance | BindingFlags.Public); if (CanRotateMin_t == null) { Utility.LogStaticError("Didn't find CanRotateMin"); return; } wbiCanRotateMin = DynamicMethodFactory.CreateFunc <object, bool>(CanRotateMin_t); MethodInfo RotateToMax_t = wbiVtolManager_t.GetMethod("RotateToMax", BindingFlags.Instance | BindingFlags.Public); if (RotateToMax_t == null) { Utility.LogStaticError("Didn't find RotateToMax"); return; } wbiRotateMax = DynamicMethodFactory.CreateAction <object>(RotateToMax_t); MethodInfo RotateToMin_t = wbiVtolManager_t.GetMethod("RotateToMin", BindingFlags.Instance | BindingFlags.Public); if (RotateToMin_t == null) { Utility.LogStaticError("Didn't find RotateToMin"); return; } wbiRotateMin = DynamicMethodFactory.CreateAction <object>(RotateToMin_t); MethodInfo RotateToNeutral_t = wbiVtolManager_t.GetMethod("RotateToNeutral", BindingFlags.Instance | BindingFlags.Public); if (ToggleHover_t == null) { Utility.LogStaticError("Didn't find RotateToNeutral"); return; } wbiRotateNeutral = DynamicMethodFactory.CreateAction <object>(RotateToNeutral_t); MethodInfo IncreaseRotationAngle_t = wbiVtolManager_t.GetMethod("IncreaseRotationAngle", BindingFlags.Instance | BindingFlags.Public); if (IncreaseRotationAngle_t == null) { Utility.LogStaticError("Didn't find IncreaseRotationAngle"); return; } wbiIncreaseRotationAngle = DynamicMethodFactory.CreateAction <object, float>(IncreaseRotationAngle_t); MethodInfo DecreaseRotationAngle_t = wbiVtolManager_t.GetMethod("DecreaseRotationAngle", BindingFlags.Instance | BindingFlags.Public); if (DecreaseRotationAngle_t == null) { Utility.LogStaticError("Didn't find DecreaseRotationAngle"); return; } wbiDecreaseRotationAngle = DynamicMethodFactory.CreateAction <object, float>(DecreaseRotationAngle_t); MethodInfo GetMaxRotation_t = wbiVtolManager_t.GetMethod("GetMaxRotation", BindingFlags.Instance | BindingFlags.Public); if (GetMaxRotation_t == null) { Utility.LogStaticError("Didn't find GetMaxRotation"); return; } wbiGetMaxRotation = DynamicMethodFactory.CreateFunc <object, float>(GetMaxRotation_t); MethodInfo GetMinRotation_t = wbiVtolManager_t.GetMethod("GetMinRotation", BindingFlags.Instance | BindingFlags.Public); if (GetMinRotation_t == null) { Utility.LogStaticError("Didn't find GetMinRotation"); return; } wbiGetMinRotation = DynamicMethodFactory.CreateFunc <object, float>(GetMinRotation_t); MethodInfo GetCurrentRotation_t = wbiVtolManager_t.GetMethod("GetCurrentRotation", BindingFlags.Instance | BindingFlags.Public); if (GetCurrentRotation_t == null) { Utility.LogStaticError("Didn't find GetCurrentRotation"); return; } wbiGetCurrentRotation = DynamicMethodFactory.CreateFunc <object, float>(GetCurrentRotation_t); // VSpd MethodInfo KillVerticalSpeed_t = wbiVtolManager_t.GetMethod("KillVerticalSpeed", BindingFlags.Instance | BindingFlags.Public); if (KillVerticalSpeed_t == null) { Utility.LogStaticError("Didn't find KillVerticalSpeed"); return; } wbiKillVerticalSpeed = DynamicMethodFactory.CreateAction <object>(KillVerticalSpeed_t); MethodInfo IncreaseVerticalSpeed_t = wbiVtolManager_t.GetMethod("IncreaseVerticalSpeed", BindingFlags.Instance | BindingFlags.Public); if (IncreaseVerticalSpeed_t == null) { Utility.LogStaticError("Didn't find IncreaseVerticalSpeed"); return; } wbiIncreaseVerticalSpeed = DynamicMethodFactory.CreateAction <object, float>(IncreaseVerticalSpeed_t); MethodInfo DecreaseVerticalSpeed_t = wbiVtolManager_t.GetMethod("DecreaseVerticalSpeed", BindingFlags.Instance | BindingFlags.Public); if (DecreaseVerticalSpeed_t == null) { Utility.LogStaticError("Didn't find DecreaseVerticalSpeed"); return; } wbiDecreaseVerticalSpeed = DynamicMethodFactory.CreateAction <object, float>(DecreaseVerticalSpeed_t); // Thrust mode FieldInfo ThrustMode_t = wbiVtolManager_t.GetField("thrustMode", BindingFlags.Instance | BindingFlags.Public); if (ThrustMode_t == null) { Utility.LogStaticError("Didn't find thrustMode"); return; } wbiGetThrustMode = DynamicMethodFactory.CreateGetField <object, object>(ThrustMode_t); MethodInfo SetForwardThrust_t = wbiVtolManager_t.GetMethod("SetForwardThrust", BindingFlags.Instance | BindingFlags.Public); if (SetForwardThrust_t == null) { Utility.LogStaticError("Didn't find SetForwardThrust"); return; } wbiSetForwardThrust = DynamicMethodFactory.CreateAction <object>(SetForwardThrust_t); MethodInfo SetReverseThrust_t = wbiVtolManager_t.GetMethod("SetReverseThrust", BindingFlags.Instance | BindingFlags.Public); if (SetReverseThrust_t == null) { Utility.LogStaticError("Didn't find SetReverseThrust"); return; } wbiSetReverseThrust = DynamicMethodFactory.CreateAction <object>(SetReverseThrust_t); MethodInfo SetVTOLThrust_t = wbiVtolManager_t.GetMethod("SetVTOLThrust", BindingFlags.Instance | BindingFlags.Public); if (SetVTOLThrust_t == null) { Utility.LogStaticError("Didn't find SetVTOLThrust"); return; } wbiSetVTOLThrust = DynamicMethodFactory.CreateAction <object>(SetVTOLThrust_t); FieldInfo VerticalSpeed_t = wbiVtolManager_t.GetField("verticalSpeed", BindingFlags.Instance | BindingFlags.Public); if (VerticalSpeed_t == null) { Utility.LogStaticError("Didn't find verticalSpeed"); return; } wbiGetVerticalSpeed = DynamicMethodFactory.CreateGetField <object, float>(VerticalSpeed_t); wbiWBIGraviticEngine_t = Utility.GetExportedType("FlyingSaucers", "WildBlueIndustries.WBIGraviticEngine"); if (wbiWBIGraviticEngine_t != null) { MethodInfo IsCrazyModeUnlocked_t = wbiWBIGraviticEngine_t.GetMethod("IsCrazyModeUnlocked", BindingFlags.Instance | BindingFlags.Public); if (IsCrazyModeUnlocked_t == null) { Utility.LogStaticError("Didn't find IsCrazyModeUnlocked"); return; } wbiCrazyModeUnlocked = DynamicMethodFactory.CreateFunc <object, bool>(IsCrazyModeUnlocked_t); MethodInfo IsActive_t = wbiWBIGraviticEngine_t.GetMethod("IsActive", BindingFlags.Instance | BindingFlags.Public); if (IsActive_t == null) { Utility.LogStaticError("Didn't find IsActive"); return; } wbiCrazyModeIsActive = DynamicMethodFactory.CreateFunc <object, bool>(IsActive_t); MethodInfo GetWarpDirection_t = wbiWBIGraviticEngine_t.GetMethod("GetWarpDirection", BindingFlags.Instance | BindingFlags.Public); if (GetWarpDirection_t == null) { Utility.LogStaticError("Didn't find GetWarpDirection"); return; } wbiGetWarpDirection = DynamicMethodFactory.CreateFunc <object, object>(GetWarpDirection_t); MethodInfo SetWarpDirection_t = wbiWBIGraviticEngine_t.GetMethod("SetWarpDirection", BindingFlags.Instance | BindingFlags.Public); if (SetWarpDirection_t == null) { Utility.LogStaticError("Didn't find SetWarpDirection"); return; } wbiSetWarpDirection = DynamicMethodFactory.CreateAction <object, int>(SetWarpDirection_t); } wbivtolInstalled = true; } }
internal MASPageRpmModule(ConfigNode config, InternalProp prop, MASFlightComputer comp, MASMonitor monitor, Transform pageRoot, float depth) : base(config, prop, comp) { this.comp = comp; Vector2 position = Vector2.zero; if (!config.TryGetValue("position", ref position)) { position = Vector2.zero; } Vector2 size = Vector2.zero; if (!config.TryGetValue("size", ref size)) { size = monitor.screenSize; } string variableName = string.Empty; if (config.TryGetValue("variable", ref variableName)) { variableName = variableName.Trim(); } displayTexture = new RenderTexture(((int)size.x) >> MASConfig.CameraTextureScale, ((int)size.y) >> MASConfig.CameraTextureScale, 24, RenderTextureFormat.ARGB32); displayTexture.Create(); string moduleNameString = string.Empty; if (!config.TryGetValue("moduleName", ref moduleNameString)) { throw new ArgumentException("Unable to find 'moduleName' in RPM_MODULE " + name); } bool moduleFound = false; int numModules = prop.internalModules.Count; int moduleIndex; for (moduleIndex = 0; moduleIndex < numModules; ++moduleIndex) { if (prop.internalModules[moduleIndex].ClassName == moduleNameString) { moduleFound = true; break; } } if (moduleFound) { rpmModule = prop.internalModules[moduleIndex]; Type moduleType = prop.internalModules[moduleIndex].GetType(); string renderMethodName = string.Empty; if (config.TryGetValue("renderMethod", ref renderMethodName)) { MethodInfo method = moduleType.GetMethod(renderMethodName); if (method != null && method.GetParameters().Length == 2 && method.GetParameters()[0].ParameterType == typeof(RenderTexture) && method.GetParameters()[1].ParameterType == typeof(float)) { renderMethod = DynamicMethodFactory.CreateFunc <object, RenderTexture, float, object>(method); } if (renderMethod != null) { Vector2 renderSize = Vector2.zero; if (!config.TryGetValue("renderSize", ref renderSize)) { renderSize = size; } if (renderSize != size) { renderTexture = new RenderTexture((int)renderSize.x, (int)renderSize.y, 24, RenderTextureFormat.ARGB32); renderTexture.Create(); } } else { throw new ArgumentException("Unable to initialize 'renderMethod' " + renderMethodName + " in RPM_MODULE " + name); } } string pageActiveMethodName = string.Empty; if (config.TryGetValue("pageActiveMethod", ref pageActiveMethodName)) { MethodInfo method = moduleType.GetMethod(pageActiveMethodName); if (method != null && method.GetParameters().Length == 2 && method.GetParameters()[0].ParameterType == typeof(bool) && method.GetParameters()[1].ParameterType == typeof(int)) { pageActiveMethod = DynamicMethodFactory.CreateFunc <object, bool, int, object>(method); } else { throw new ArgumentException("Unable to initialize 'pageActiveMethod' " + pageActiveMethodName + " in RPM_MODULE " + name); } } string buttonClickMethodName = string.Empty; if (config.TryGetValue("buttonClickMethod", ref buttonClickMethodName)) { MethodInfo method = moduleType.GetMethod(buttonClickMethodName); if (method != null && method.GetParameters().Length == 1 && method.GetParameters()[0].ParameterType == typeof(int)) { buttonClickMethod = DynamicMethodFactory.CreateDynFunc <object, int, object>(method); } } } else { string textureName = string.Empty; if (config.TryGetValue("texture", ref textureName)) { Texture missingTexture = GameDatabase.Instance.GetTexture(textureName, false); if (missingTexture != null) { Graphics.Blit(missingTexture, displayTexture); } } } // Set up our surface. imageObject = new GameObject(); imageObject.name = Utility.ComposeObjectName(pageRoot.gameObject.name, this.GetType().Name, name, (int)(-depth / MASMonitor.depthDelta)); imageObject.layer = pageRoot.gameObject.layer; imageObject.transform.parent = pageRoot; imageObject.transform.position = pageRoot.position; imageObject.transform.Translate(monitor.screenSize.x * -0.5f + position.x + size.x * 0.5f, monitor.screenSize.y * 0.5f - position.y - size.y * 0.5f, depth); // add renderer stuff MeshFilter meshFilter = imageObject.AddComponent <MeshFilter>(); meshRenderer = imageObject.AddComponent <MeshRenderer>(); Mesh mesh = new Mesh(); mesh.vertices = new[] { new Vector3(-0.5f * size.x, 0.5f * size.y, depth), new Vector3(0.5f * size.x, 0.5f * size.y, depth), new Vector3(-0.5f * size.x, -0.5f * size.y, depth), new Vector3(0.5f * size.x, -0.5f * size.y, depth), }; mesh.uv = new[] { new Vector2(0.0f, 1.0f), Vector2.one, Vector2.zero, new Vector2(1.0f, 0.0f), }; mesh.triangles = new[] { 0, 1, 2, 1, 3, 2 }; mesh.RecalculateBounds(); mesh.UploadMeshData(true); meshFilter.mesh = mesh; imageMaterial = new Material(MASLoader.shaders["MOARdV/Monitor"]); imageMaterial.mainTexture = displayTexture; meshRenderer.material = imageMaterial; RenderPage(false); if (!string.IsNullOrEmpty(variableName)) { // Disable the mesh if we're in variable mode imageObject.SetActive(false); variableRegistrar.RegisterVariableChangeCallback(variableName, VariableCallback); } else { currentState = true; imageObject.SetActive(true); } if (renderMethod != null) { comp.StartCoroutine(QueryModule()); } }
/// <summary> /// Rebuild the action array. /// </summary> /// <param name="parts"></param> internal void Rebuild(List <Part> parts) { List <MASAction> newAction = new List <MASAction>(); //Utility.LogMessage(this, "Rebuild AG {0}", actionGroupId); //foreach (var aPart in parts) //{ // Utility.LogMessage(this, "... {0}", aPart.name); //} // I'm pretty sure this isn't the most efficient way to do this... int numTemplates = actionTemplate.Length; for (int templateIdx = 0; templateIdx < numTemplates; ++templateIdx) { // This is kind-of lame. The part name for the root part has " (vesselName)" tacked to the end of it // (ie, "SomePart (Untitled Craft)"), so I can't do a simple string comparison. string templateName = actionTemplate[templateIdx].partName; List <Part> relevantParts = parts.FindAll((Part x) => { int idxSpace = x.name.IndexOf(' '); if (idxSpace > 0) { return(x.name.Substring(0, idxSpace) == templateName); } else { return(x.name == templateName); } }); //Utility.LogMessage(this, "Found {0} parts of name {1}", relevantParts.Count, actionTemplate[templateIdx].partName); if (relevantParts.Count > 0) { bool warned = false; string[] reflectedAction = actionTemplate[templateIdx].module.Split('.'); foreach (Part p in relevantParts) { switch (actionTemplate[templateIdx].module) { case "ModuleAnimateGeneric": List <ModuleAnimateGeneric> mag = p.FindModulesImplementing <ModuleAnimateGeneric>(); //Utility.LogMessage(this, "Found {0} ModuleAnimateGeneric", mag.Count); foreach (ModuleAnimateGeneric magx in mag) { newAction.Add(new MASActionModuleAnimateGeneric(magx, actionTemplate[templateIdx].action)); } break; case "ModuleDecouple": List <ModuleDecouple> md = p.FindModulesImplementing <ModuleDecouple>(); //Utility.LogMessage(this, "Found {0} ModuleDecouple", md.Count); foreach (ModuleDecouple mdx in md) { newAction.Add(new MASActionModuleDecouple(mdx, actionTemplate[templateIdx].action)); } break; case "ModuleEngines": List <ModuleEngines> me = p.FindModulesImplementing <ModuleEngines>(); //Utility.LogMessage(this, "Found {0} ModuleEngines", me.Count); foreach (ModuleEngines mex in me) { newAction.Add(new MASActionModuleEngines(mex, actionTemplate[templateIdx].action)); } break; case "ModuleLight": List <ModuleLight> ml = p.FindModulesImplementing <ModuleLight>(); //Utility.LogMessage(this, "Found {0} ModuleLight", ml.Count); foreach (ModuleLight mlx in ml) { newAction.Add(new MASActionModuleLight(mlx, actionTemplate[templateIdx].action)); } break; case "ModuleRCS": List <ModuleRCS> mr = p.FindModulesImplementing <ModuleRCS>(); //Utility.LogMessage(this, "Found {0} ModuleRCS", mr.Count); foreach (ModuleRCS mrx in mr) { newAction.Add(new MASActionModuleRCS(mrx, actionTemplate[templateIdx].action)); } break; default: if (reflectedAction.Length != 2) { if (!warned) { Utility.LogWarning(this, "Found unrecognized module \"{0}\" for MAS_ACTION_GROUP {1}", actionTemplate[templateIdx].module, name); warned = true; } } else if (p.Modules.Contains(reflectedAction[0])) { PartModule mod = p.Modules[reflectedAction[0]]; Type t = mod.GetType(); MethodInfo mi = t.GetMethod(reflectedAction[1]); if (mi == null || mi.GetParameters().Length > 0) { if (!warned) { Utility.LogWarning(this, "Did not find method \"{3}\" with 0 parameters in module \"{0}\" in part \"{2}\" for MAS_ACTION_GROUP {1}", reflectedAction[0], name, p.name, reflectedAction[1]); warned = true; } } else { Action <object> theAction = DynamicMethodFactory.CreateAction <object>(mi); newAction.Add(new MASActionGeneric(mod, theAction, actionTemplate[templateIdx].action)); } } else { if (!warned) { Utility.LogWarning(this, "Did not find module \"{0}\" in part \"{2}\" for MAS_ACTION_GROUP {1}", reflectedAction[0], name, p.name); warned = true; } } break; } } } } action = newAction.ToArray(); //Utility.LogMessage(this, "Ended up with {0} entries in action.", action.Length); }