TheMaul Posted January 23, 2016 Share Posted January 23, 2016 Hey guys. I'm starting mod development and I'd like to know if there are very simple mods I can download to start looking into the code. I've already downloaded some but they are too complex to start with (even Chatterer is already several k-lines of code). Thanks ! Quote Link to comment Share on other sites More sharing options...
Crzyrndm Posted January 23, 2016 Share Posted January 23, 2016 Anything in particular you're trying to do? I have/know a couple of small ones (KSPAddon, Part Module), but they won't be of much use if you're doing something entirely different Quote Link to comment Share on other sites More sharing options...
TheMaul Posted January 24, 2016 Share Posted January 24, 2016 I plan to make a sort of gravity viewing tool, so a simple GUI and drawing lines on the map view Quote Link to comment Share on other sites More sharing options...
Crzyrndm Posted January 24, 2016 Share Posted January 24, 2016 [KSPAddon(KSPAddon.Startup.Flight, false)] public class DrawGravity : MonoBehaviour { public bool inMapView; public void Start() { GameEvents.OnMapEntered.Add(enteredMapView); GameEvents.OnMapExited.Add(exitedMapView); } public void enteredMapView() { inMapView = true; } public void exitedMapView() { inMapView = false; } public void OnDestroy() { GameEvents.OnMapEntered.Remove(enteredMapView); GameEvents.OnMapExited.Remove(exitedMapView); } public void OnGUI() { if (!inMapView) return; // stuff for drawing UI elements // look up Unity's GUI or GUILayout classes } } Should be a fairly good starting point Quote Link to comment Share on other sites More sharing options...
TheMaul Posted January 24, 2016 Share Posted January 24, 2016 Should be a fairly good answer, thanks. I'll try that. Quote Link to comment Share on other sites More sharing options...
Warzouz Posted January 30, 2016 Share Posted January 30, 2016 Hi, I've a very newbee question I want to look at plugins devs, I used a lot VB.Net few years ago. I just went through a C# tutorial to freshen up my syntax. I'm installing VS 2015 (cummunity version). My question is : As I want to create some "window" oriented plugin and not "part" oriented plugins, what version of Unity do I need to install ? Thx Quote Link to comment Share on other sites More sharing options...
Crzyrndm Posted January 30, 2016 Share Posted January 30, 2016 (edited) None. Window oriented plugin you're looking at something very similar to what I posted 2 above your post. KSPAddon attribute on a monobehaviour, window drawn in OnGUI, lookup Unity GUI or GUILayout classes for documentation NOTE: Unity's new GUI system isn't particularly plugin friendly, so you'll probably want the editor to play with that. However I'm under the impression that requires loading asset bundles which I don't believe are currently directly loadable by KSP Edited January 30, 2016 by Crzyrndm Quote Link to comment Share on other sites More sharing options...
sarbian Posted January 30, 2016 Share Posted January 30, 2016 You can load them, but you need Unity Pro to make them for Unity 4.x Quote Link to comment Share on other sites More sharing options...
Warzouz Posted January 30, 2016 Share Posted January 30, 2016 Thx. Where can I find a basic template source for a plugins project ? Quote Link to comment Share on other sites More sharing options...
TheMaul Posted January 31, 2016 Share Posted January 31, 2016 Hi, is there a way to debug plugins without restarting the game every time ? Quote Link to comment Share on other sites More sharing options...
JPLRepo Posted January 31, 2016 Share Posted January 31, 2016 3 hours ago, TheMaul said: Hi, is there a way to debug plugins without restarting the game every time ? Until 1.1 comes out which is supposed to support dynamic dll loading you could try this. But it has it's limitations. Otherwise, restarting is the only way to do it. Quote Link to comment Share on other sites More sharing options...
sarbian Posted January 31, 2016 Share Posted January 31, 2016 Or you could do real debugging : http://forum.kerbalspaceprogram.com/index.php?/topic/102909-ksp-plugin-debugging-for-visual-studio-and-monodevelop-on-all-os/ Quote Link to comment Share on other sites More sharing options...
hab136 Posted January 31, 2016 Share Posted January 31, 2016 On 1/30/2016 at 2:02 PM, Warzouz said: Thx. Where can I find a basic template source for a plugins project ? Check out "01-SimplePartlessPlugin" in https://github.com/taraniselsu/TacExamples Quote Link to comment Share on other sites More sharing options...
xEvilReeperx Posted January 31, 2016 Share Posted January 31, 2016 4 hours ago, sarbian said: Or you could do real debugging : http://forum.kerbalspaceprogram.com/index.php?/topic/102909-ksp-plugin-debugging-for-visual-studio-and-monodevelop-on-all-os/ AssemblyReloader supports this btw in case it wasn't clear, so you can reload and debug your iterations. Most of its limitations are because I haven't needed that functionality and nobody's asked for it Quote Link to comment Share on other sites More sharing options...
sarbian Posted February 1, 2016 Share Posted February 1, 2016 10 hours ago, xEvilReeperx said: AssemblyReloader supports this btw in case it wasn't clear, so you can reload and debug your iterations. Most of its limitations are because I haven't needed that functionality and nobody's asked for it Oh, I ll have to look into it more then Quote Link to comment Share on other sites More sharing options...
JPLRepo Posted February 1, 2016 Share Posted February 1, 2016 10 hours ago, xEvilReeperx said: AssemblyReloader supports this btw in case it wasn't clear, so you can reload and debug your iterations. Most of its limitations are because I haven't needed that functionality and nobody's asked for it Sorry dude, I just meant it doesn't cover everything. My mods all have parts, contracts or internal models, so it's not much use to me personally. Quote Link to comment Share on other sites More sharing options...
xEvilReeperx Posted February 1, 2016 Share Posted February 1, 2016 I was referring to the debugging support Contracts are a problem (because unimplemented) but most people don't use a custom Part-derived type in their plugins and custom InternalModules are pretty rare in my experience as well... Quote Link to comment Share on other sites More sharing options...
sarbian Posted February 1, 2016 Share Posted February 1, 2016 Custom Part-derived type are the kind of things I clearly don't want to see in any mod... Quote Link to comment Share on other sites More sharing options...
ve2dmn Posted February 14, 2016 Share Posted February 14, 2016 I wrote my own code to detect which asteroid are heading for kerbin and when. That bit is working great and It auto-add the SOI change to KAC. The part that is not working is making custom contracts based on that information. Because the orbits are only available during the FLIGHT and TRACKSTATION GameScenes, I have my code try to generate a custom contract and add it to the current ones. Problem is, it doesn't seems to do anything. The contracts doesn't show up, even in the debug menu. Here is the code: private void AddContract(String vID) { //Add Contract if possible Debug.Log ("Try to find Contract for " + vID); Debug.Log ("number of Contracts to check : " + ContractSystem.Instance.Contracts.Count ()); Debug.Log ("Status of Contract system: " + (ContractSystem.Instance == null)); Debug.Log ("ContractSystem.Instance.enabled: " + ContractSystem.Instance.enabled); Debug.Log ("Generating new Contract "); AsteroidRedirectContract GeneratedContractType = new AsteroidRedirectContract (); Contract GeneratedContract = null; Debug.Log ("Generating Contract of Type:" + GeneratedContractType.GetType ()); GeneratedContract = ContractSystem.Instance.GenerateContract (0, Contract.ContractPrestige.Trivial, GeneratedContractType.GetType ()); if (GeneratedContract != null) { GeneratedContract.AddParameter (new AsteroidRedirectAltitudeParameters (vID)); GeneratedContract.AddParameter (new AsteroidRedirectDockingParameters (vID)); } if (!ContractSystem.Instance.Contracts.Contains(GeneratedContract)) { //Generate new Contract GeneratedContract.Accept (); ContractSystem.Instance.Contracts.Add (GeneratedContract); Debug.Log ("Generated Contract:" + GeneratedContract.ToString ()); } } Now, I am obvious not a C# or Unity developper, so I have no clue if I'm doing something that is obviously wrong.... I've tried to debug this for hours trying various way and none seems to work, which is why I am posting here... ContractSystem.Instance.Contracts.Count (), keeps going up with every contract that I Add(). So that seems to be working. Except, it doesn't do anything. Any Ideas? Quote Link to comment Share on other sites More sharing options...
TheMightySpud Posted February 15, 2016 Share Posted February 15, 2016 Hi all, I really really really really really really (yes, really :-P) Hope someone can see where I'm going wrong on this...... What I'm trying to do is spawn a vessel (loaded from an existing Craft file) at startup, using KSPAddon to trigger the spawning when you enter the space center from the main menu, when I've got it working there will be a check to see if the vessel already exists, but for now I just want to get it to spawn. I've got it triggering the code, but then something weird is happening and it's driving me nuts. Any time after a certain point that I try to do anything with the _newVessel I get an exception and it breaks. The Exception (from the log) is Quote [EXC 20:13:37.146] NullReferenceException: Object reference not set to an instance of an object Kerbal_Stargate.VesselSpawner.SpawnVessel (System.String vesselName, .ShipConstruct _shipConstruct, Vector3 _spawnOffset) Kerbal_Stargate.VesselSpawner.SpawnVessel () Kerbal_Stargate.TMS_Module_001.Awake () UnityEngine.GameObject:AddComponent(Type) AddonLoader:StartAddon(LoadedAssembly, Type, KSPAddon, Startup) AddonLoader:StartAddons(Startup) AddonLoader:OnLevelWasLoaded(Int32) The code (below) is a modified version of KSPSmelter by @TAz00, which in turn is a modified bit of code from KAS. The biggest problem has been converting the code to spawn at a specific point in the 'universe' from spawning based on the position of a Part, so I think I've broken something somewhere. The actual spawn location isn't important at the moment, I'll be translating save game position data to place the object once I have this part working properly. I've been staring/fiddling/kicking this code for almost two days solid so I really do hope someone can help out. Code for creating/spawning the vessel. using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace TMS_Module_001 { /// <summary> /// This class is pretty much built on what KAS uses to pull parts out of containers /// All credit to https://github.com/KospY/KAS /// https://github.com/KospY/KAS/blob/master/LICENSE.md /// </summary> public class VesselSpawner { const string PluginPath = "\\GameData\\TMSOrbitalMechanics\\PluginData\\"; private HideConfigNode _OldVabShip; private string _craftFile = ""; private string vesselName = ""; private Vector3 vesselPosition = new Vector3(0.0f, 0.0f, 0.0f); private CelestialBody bodyKerbin = null; /// <summary> /// /// </summary> /// <param name="_craftFile">Craft file name as it appears in the PluginPath folder</param> /// <param name="_srcPart">Source part to spawn relative to</param> /// <param name="_spawnOffset">Offset spawn from Source part position</param> //public VesselSpawner(string _craftFile, Vector3 _spawnOffset) public VesselSpawner(string _craftFile, string vesselName, Vector3 vesselPosition, CelestialBody bodyKerbin) { //Store paths this._craftFile = _craftFile; this.vesselPosition = vesselPosition; this.vesselName = vesselName; this.bodyKerbin = bodyKerbin; } /// <summary> /// Spawns the vessel /// </summary> public void SpawnVessel() { Debug.Log("SpawnVessel"); //Load craft file ShipConstruct _ship = LoadVessel(this._craftFile); if (_ship != null) { SpawnVessel(this.vesselName, _ship, this.vesselPosition); } else { Debug.Log("Failed to load the vessel"); } } /// <summary> /// Attempt vessel load /// </summary> /// <param name="_craftFile"></param> /// <returns></returns> private ShipConstruct LoadVessel(string _craftFile) { Debug.Log("ConstructVessel"); //Get path to vessel Debug.Log("Loading the craft file"); string BasePath = Environment.CurrentDirectory + PluginPath; string path = BasePath + _craftFile; Debug.Log(path); //Save old ship for later, else player will see it in the VAB _OldVabShip = new HideConfigNode(ShipConstruction.ShipConfig); //Load craft file ShipConstruct _shipConstruct = ShipConstruction.LoadShip(path); //Check load Debug.Log("Checking if its loaded"); if (_shipConstruct == null) { // Restore ShipConstruction ship, otherwise player sees loaded craft in VAB ShipConstruction.ShipConfig = _OldVabShip.GetConfigNode(); return null; //Fail } Debug.Log("Sending it back"); return _shipConstruct; } /// <summary> /// Spawn ship construct /// https://github.com/KospY/KAS/blob/master/Plugin/KAS_Shared.cs /// </summary> /// <param name="_shipConstruct">Shipconstruct to spawn</param> /// <param name="_srcPart">Source part to spawn relative to</param> /// <param name="_spawnOffset">Offset spawn from Source part position</param> private void SpawnVessel(string vesselName, ShipConstruct _shipConstruct, Vector3 _spawnOffset) { Debug.Log("PrivateSpawnVessel"); //Store construct root Part _newConstructRootPart = _shipConstruct.parts[0]; Debug.Log("Doing something with the Root"); //Center rootpart Vector3 offset = _newConstructRootPart.transform.localPosition; _newConstructRootPart.transform.Translate(-offset); Debug.Log("Setting Root position or something"); //Get launch spawn point. GameObject launchPos = new GameObject(); launchPos.transform.position = vesselPosition; //Store our launch / spawn position Transform launchTransform = launchPos.transform; //Kill original object launchPos.DestroyGameObject(); //Set rootpart origin _shipConstruct.Parts[0].localRoot.transform.Translate(launchPos.transform.position, Space.World); //Position float angle; Vector3 axis; //Extract ToAngleAxis data from selected spawning location launchTransform.rotation.ToAngleAxis(out angle, out axis); //TRANSFORM Rotate localRootPart in relation to root _shipConstruct.Parts[0].localRoot.transform.RotateAround(launchTransform.position, axis, angle); //Create vessel object Debug.Log("CreateVesselObject"); Vessel _newVessel = _newConstructRootPart.localRoot.gameObject.AddComponent<Vessel>(); Debug.Log("Adding all the info to the ship"); //Attach vessel information _newVessel.id = Guid.NewGuid(); _newVessel.name = vesselName; //_newVessel.Landed = true; _newVessel.Splashed = false; _newVessel.landedAt = string.Empty; _newVessel.situation = Vessel.Situations.LANDED; _newVessel.vesselType = VesselType.Base; //Init from VAB _newVessel.Initialize(true); //_newVessel.vesselName = _srcPart.vessel.vesselName + " - " + _shipConstruct.shipName; //_newVessel.landedAt = _srcPart.vessel.vesselName; //Store backup ShipConstruction.CreateBackup(_shipConstruct); Debug.Log("MissionIDStuff"); //Set Orbit InitiateOrbit(vesselPosition, _newVessel); //Set Mission info Debug.Log("Set Mission ID"); uint missionId = (uint)Guid.NewGuid().GetHashCode(); //string flagUrl = _srcPart.flagURL; Debug.Log("Set Launch ID"); uint launchId = HighLogic.CurrentGame.launchID++; //Set part mission info for (int i = 0; i < _newVessel.parts.Count; i++) { Debug.Log(_newVessel.parts.Count); Debug.Log("Loop through parts"); Part part = _newVessel.parts[i]; Debug.Log(part.name); part.flightID = ShipConstruction.GetUniqueFlightID(FlightDriver.FlightStateCache.flightState); Debug.Log("Done it Once"); part.launchID = launchId; part.missionID = missionId; } Debug.Log("Finished Mission Stuff"); //Generate staging //Staging.beginFlight(); //_newConstructRootPart.vessel.ResumeStaging(); //Staging.GenerateStagingSequence(_newConstructRootPart.localRoot); //Staging.RecalculateVesselStaging(_newConstructRootPart.vessel); //Set position, again _newVessel.SetPosition(launchTransform.position); _newVessel.SetRotation(launchTransform.rotation); //Get all the parts, does it even matter since we launch from VAB? for (int i = 0; i < _newVessel.parts.Count; i++) { // Solar panels from containers (we dont have no bloody containers here tho) don't work otherwise for (int j = 0; j < _newVessel.parts[i].Modules.Count; j++) { ConfigNode node = new ConfigNode(); node.AddValue("name", _newVessel.parts[i].Modules[j].moduleName); _newVessel.parts[i].LoadModule(node, ref j); } } Debug.Log("ProtoVesselStuff"); //Save Protovessel ProtoVessel _newProto = new ProtoVessel(_newVessel); Debug.Log("Defined ProtoVessel"); if (_newProto == null) { Debug.Log("Nope"); } else { Debug.Log("If Statement if not failed"); //Kill and remove spawned vessel, had some serious problems with spawn position warping/glitching // Debug.Log("_newVessel Die"); _newVessel.Die(); Debug.Log("New Vessel Dead"); Debug.Log(launchPos.transform.position); //Set the protovessels position to the relative one we found, maybe redundant Debug.Log("Move ProtoVessel"); _newProto.position = launchPos.transform.position; //If you check this value, you will see the height change from launch scene to resume scene, extra dafuq float height = _newProto.height; if (FlightDriver.StartupBehaviour == FlightDriver.StartupBehaviours.RESUME_SAVED_FILE || FlightDriver.StartupBehaviour == FlightDriver.StartupBehaviours.RESUME_SAVED_CACHE) { //Odd behaviour with positioning during different flight scenes, workaround awaaaay //_newProto.height = TrueAlt(launchTransform.position, _newProto.height); //} //Load Protovessel Debug.Log("ProtoVessel Load"); _newProto.Load(HighLogic.CurrentGame.flightState); // Restore ShipConstruction ship, otherwise player sees loaded craft in VAB ShipConstruction.ShipConfig = _OldVabShip.GetConfigNode(); } } } /// <summary> /// http://forum.kerbalspaceprogram.com/threads/111116-KSP-Altitude-Calculation-Inquiry /// </summary> /// <returns></returns> //private float TrueAlt(Vector3 _LauncPos, Vessel _srcVessel) //{ // Debug.Log("Altitude Stuff?"); // //Vector3 pos = _srcPart.transform.position; //or this.vessel.GetWorldPos3D() // float ASL = FlightGlobals.getAltitudeAtPos(_LauncPos); // if (_srcVessel.mainBody.pqsController == null) { return ASL; } // float terrainAlt = Convert.ToSingle(_srcVessel.pqsAltitude); // if (_srcVessel.mainBody.ocean && _srcVessel.heightFromTerrain <= 0) { return ASL; } //Checks for oceans // return ASL - terrainAlt; //} /// <summary> /// https://github.com/taniwha-qf/Extraplanetary-Launchpads/blob/master/Source/BuildControl.cs /// https://github.com/taniwha-qf/Extraplanetary-Launchpads/blob/master/License.txt /// </summary> /// <param name="_newVessel"></param> /// <param name="_srcVessel"></param> private void InitiateOrbit(Vector3 vesselPosition, Vessel _newVessel) { Debug.Log("More OrbitStuff"); var mode = OrbitDriver.UpdateMode.UPDATE; _newVessel.orbitDriver.SetOrbitMode(mode); var craftCoM = GetVesselWorldCoM(_newVessel); //var vesselCoM = _newVessel.findWorldCenterOfMass; var uTime = Planetarium.GetUniversalTime(); var vesselCoM = vesselPosition; var offset = (Vector3d.zero + craftCoM - vesselCoM).xzy; _newVessel.orbit.Init(); _newVessel.orbit.StartUT = uTime; _newVessel.orbit.referenceBody = bodyKerbin; //_newVessel.orbit.pos = vesselPosition; //_newVessel.orbit.vel = new Vector3d(0, 0, 0); //_newVessel.angularMomentum = Vector3.zero; //_newVessel.angularVelocity = Vector3.zero; _newVessel.latitude = -1.0f; _newVessel.longitude = 1.0f; _newVessel.heightFromTerrain = 0.0f; //_newVessel.SetRotation(0,0); //_newVessel.altitude = 70.8178020151099; var corb = _newVessel.orbit; corb.UpdateFromStateVectors(corb.pos + offset, _newVessel.orbit.vel, bodyKerbin, uTime); Debug.Log(String.Format("[EL] {0} {1}", "This is Orbit Info", corb.pos)); } public Vector3 GetVesselWorldCoM(Vessel v) { var com = v.findLocalCenterOfMass(); return v.rootPart.partTransform.TransformPoint(com); } } } The trouble starts when I hit the line..... part.flightID = ShipConstruction.GetUniqueFlightID(FlightDriver.FlightStateCache.flightState); Just as an excersize I commented out that line, and then it threw the exception at Debug.Log("_newVessel Die"); _newVessel.Die(); Debug.Log("New Vessel Dead"); leading me to think that it's something to do with the way I've created/modified the vessel. :-/ Code for calling the spawn...... using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace TMS_Module_001 { [KSPAddon(KSPAddon.Startup.SpaceCentre, true)] public class TMS_Stargate : MonoBehaviour { public CelestialBody bodyMun; public CelestialBody bodyKerbin; public void Awake() { string vesselName = "Module 001"; //string celestialBody = "Kerbin"; //CelestialBody celestialBody = new CelestialBody(); foreach (CelestialBody targetBody in FlightGlobals.Bodies) { if (targetBody.name == "Kerbin") bodyKerbin = targetBody; } //string targetBody = celestialBody.name; Vector3 vesselPosition = new Vector3(5f, 0f, 5f); VesselSpawner TMS_Module_001 = new VesselSpawner("TMS_Module_001.craft", vesselName, vesselPosition, bodyKerbin); Debug.Log("Spawn the Ship"); TMS_Module_001.SpawnVessel(); Debug.Log("Ship has Spawned"); } } } So again, I really hope someone can shed some light on this, even if it's a case of pointing me in the right direction of what to look at Thanks TheMightySpud Quote Link to comment Share on other sites More sharing options...
ShadyAct Posted February 16, 2016 Share Posted February 16, 2016 Will a 32-bit plugin run any differently on 64-bit KSP if it's compiled with x64 assemblies? (UnityEngine, etc.) Quote Link to comment Share on other sites More sharing options...
hab136 Posted February 16, 2016 Share Posted February 16, 2016 11 hours ago, TheMightySpud said: Hi all, I really really really really really really (yes, really :-P) Hope someone can see where I'm going wrong on this...... What I'm trying to do is spawn a vessel (loaded from an existing Craft file) at startup, using KSPAddon to trigger the spawning when you enter the space center from the main menu, when I've got it working there will be a check to see if the vessel already exists, but for now I just want to get it to spawn. I've got it triggering the code, but then something weird is happening and it's driving me nuts. Any time after a certain point that I try to do anything with the _newVessel I get an exception and it breaks. The Exception (from the log) is The code (below) is a modified version of KSPSmelter by @TAz00, which in turn is a modified bit of code from KAS. The biggest problem has been converting the code to spawn at a specific point in the 'universe' from spawning based on the position of a Part, so I think I've broken something somewhere. The actual spawn location isn't important at the moment, I'll be translating save game position data to place the object once I have this part working properly. I've been staring/fiddling/kicking this code for almost two days solid so I really do hope someone can help out. Code for creating/spawning the vessel. using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace TMS_Module_001 { /// <summary> /// This class is pretty much built on what KAS uses to pull parts out of containers /// All credit to https://github.com/KospY/KAS /// https://github.com/KospY/KAS/blob/master/LICENSE.md /// </summary> public class VesselSpawner { const string PluginPath = "\\GameData\\TMSOrbitalMechanics\\PluginData\\"; private HideConfigNode _OldVabShip; private string _craftFile = ""; private string vesselName = ""; private Vector3 vesselPosition = new Vector3(0.0f, 0.0f, 0.0f); private CelestialBody bodyKerbin = null; /// <summary> /// /// </summary> /// <param name="_craftFile">Craft file name as it appears in the PluginPath folder</param> /// <param name="_srcPart">Source part to spawn relative to</param> /// <param name="_spawnOffset">Offset spawn from Source part position</param> //public VesselSpawner(string _craftFile, Vector3 _spawnOffset) public VesselSpawner(string _craftFile, string vesselName, Vector3 vesselPosition, CelestialBody bodyKerbin) { //Store paths this._craftFile = _craftFile; this.vesselPosition = vesselPosition; this.vesselName = vesselName; this.bodyKerbin = bodyKerbin; } /// <summary> /// Spawns the vessel /// </summary> public void SpawnVessel() { Debug.Log("SpawnVessel"); //Load craft file ShipConstruct _ship = LoadVessel(this._craftFile); if (_ship != null) { SpawnVessel(this.vesselName, _ship, this.vesselPosition); } else { Debug.Log("Failed to load the vessel"); } } /// <summary> /// Attempt vessel load /// </summary> /// <param name="_craftFile"></param> /// <returns></returns> private ShipConstruct LoadVessel(string _craftFile) { Debug.Log("ConstructVessel"); //Get path to vessel Debug.Log("Loading the craft file"); string BasePath = Environment.CurrentDirectory + PluginPath; string path = BasePath + _craftFile; Debug.Log(path); //Save old ship for later, else player will see it in the VAB _OldVabShip = new HideConfigNode(ShipConstruction.ShipConfig); //Load craft file ShipConstruct _shipConstruct = ShipConstruction.LoadShip(path); //Check load Debug.Log("Checking if its loaded"); if (_shipConstruct == null) { // Restore ShipConstruction ship, otherwise player sees loaded craft in VAB ShipConstruction.ShipConfig = _OldVabShip.GetConfigNode(); return null; //Fail } Debug.Log("Sending it back"); return _shipConstruct; } /// <summary> /// Spawn ship construct /// https://github.com/KospY/KAS/blob/master/Plugin/KAS_Shared.cs /// </summary> /// <param name="_shipConstruct">Shipconstruct to spawn</param> /// <param name="_srcPart">Source part to spawn relative to</param> /// <param name="_spawnOffset">Offset spawn from Source part position</param> private void SpawnVessel(string vesselName, ShipConstruct _shipConstruct, Vector3 _spawnOffset) { Debug.Log("PrivateSpawnVessel"); //Store construct root Part _newConstructRootPart = _shipConstruct.parts[0]; Debug.Log("Doing something with the Root"); //Center rootpart Vector3 offset = _newConstructRootPart.transform.localPosition; _newConstructRootPart.transform.Translate(-offset); Debug.Log("Setting Root position or something"); //Get launch spawn point. GameObject launchPos = new GameObject(); launchPos.transform.position = vesselPosition; //Store our launch / spawn position Transform launchTransform = launchPos.transform; //Kill original object launchPos.DestroyGameObject(); //Set rootpart origin _shipConstruct.Parts[0].localRoot.transform.Translate(launchPos.transform.position, Space.World); //Position float angle; Vector3 axis; //Extract ToAngleAxis data from selected spawning location launchTransform.rotation.ToAngleAxis(out angle, out axis); //TRANSFORM Rotate localRootPart in relation to root _shipConstruct.Parts[0].localRoot.transform.RotateAround(launchTransform.position, axis, angle); //Create vessel object Debug.Log("CreateVesselObject"); Vessel _newVessel = _newConstructRootPart.localRoot.gameObject.AddComponent<Vessel>(); Debug.Log("Adding all the info to the ship"); //Attach vessel information _newVessel.id = Guid.NewGuid(); _newVessel.name = vesselName; //_newVessel.Landed = true; _newVessel.Splashed = false; _newVessel.landedAt = string.Empty; _newVessel.situation = Vessel.Situations.LANDED; _newVessel.vesselType = VesselType.Base; //Init from VAB _newVessel.Initialize(true); //_newVessel.vesselName = _srcPart.vessel.vesselName + " - " + _shipConstruct.shipName; //_newVessel.landedAt = _srcPart.vessel.vesselName; //Store backup ShipConstruction.CreateBackup(_shipConstruct); Debug.Log("MissionIDStuff"); //Set Orbit InitiateOrbit(vesselPosition, _newVessel); //Set Mission info Debug.Log("Set Mission ID"); uint missionId = (uint)Guid.NewGuid().GetHashCode(); //string flagUrl = _srcPart.flagURL; Debug.Log("Set Launch ID"); uint launchId = HighLogic.CurrentGame.launchID++; //Set part mission info for (int i = 0; i < _newVessel.parts.Count; i++) { Debug.Log(_newVessel.parts.Count); Debug.Log("Loop through parts"); Part part = _newVessel.parts[i]; Debug.Log(part.name); part.flightID = ShipConstruction.GetUniqueFlightID(FlightDriver.FlightStateCache.flightState); Debug.Log("Done it Once"); part.launchID = launchId; part.missionID = missionId; } Debug.Log("Finished Mission Stuff"); //Generate staging //Staging.beginFlight(); //_newConstructRootPart.vessel.ResumeStaging(); //Staging.GenerateStagingSequence(_newConstructRootPart.localRoot); //Staging.RecalculateVesselStaging(_newConstructRootPart.vessel); //Set position, again _newVessel.SetPosition(launchTransform.position); _newVessel.SetRotation(launchTransform.rotation); //Get all the parts, does it even matter since we launch from VAB? for (int i = 0; i < _newVessel.parts.Count; i++) { // Solar panels from containers (we dont have no bloody containers here tho) don't work otherwise for (int j = 0; j < _newVessel.parts[i].Modules.Count; j++) { ConfigNode node = new ConfigNode(); node.AddValue("name", _newVessel.parts[i].Modules[j].moduleName); _newVessel.parts[i].LoadModule(node, ref j); } } Debug.Log("ProtoVesselStuff"); //Save Protovessel ProtoVessel _newProto = new ProtoVessel(_newVessel); Debug.Log("Defined ProtoVessel"); if (_newProto == null) { Debug.Log("Nope"); } else { Debug.Log("If Statement if not failed"); //Kill and remove spawned vessel, had some serious problems with spawn position warping/glitching // Debug.Log("_newVessel Die"); _newVessel.Die(); Debug.Log("New Vessel Dead"); Debug.Log(launchPos.transform.position); //Set the protovessels position to the relative one we found, maybe redundant Debug.Log("Move ProtoVessel"); _newProto.position = launchPos.transform.position; //If you check this value, you will see the height change from launch scene to resume scene, extra dafuq float height = _newProto.height; if (FlightDriver.StartupBehaviour == FlightDriver.StartupBehaviours.RESUME_SAVED_FILE || FlightDriver.StartupBehaviour == FlightDriver.StartupBehaviours.RESUME_SAVED_CACHE) { //Odd behaviour with positioning during different flight scenes, workaround awaaaay //_newProto.height = TrueAlt(launchTransform.position, _newProto.height); //} //Load Protovessel Debug.Log("ProtoVessel Load"); _newProto.Load(HighLogic.CurrentGame.flightState); // Restore ShipConstruction ship, otherwise player sees loaded craft in VAB ShipConstruction.ShipConfig = _OldVabShip.GetConfigNode(); } } } /// <summary> /// http://forum.kerbalspaceprogram.com/threads/111116-KSP-Altitude-Calculation-Inquiry /// </summary> /// <returns></returns> //private float TrueAlt(Vector3 _LauncPos, Vessel _srcVessel) //{ // Debug.Log("Altitude Stuff?"); // //Vector3 pos = _srcPart.transform.position; //or this.vessel.GetWorldPos3D() // float ASL = FlightGlobals.getAltitudeAtPos(_LauncPos); // if (_srcVessel.mainBody.pqsController == null) { return ASL; } // float terrainAlt = Convert.ToSingle(_srcVessel.pqsAltitude); // if (_srcVessel.mainBody.ocean && _srcVessel.heightFromTerrain <= 0) { return ASL; } //Checks for oceans // return ASL - terrainAlt; //} /// <summary> /// https://github.com/taniwha-qf/Extraplanetary-Launchpads/blob/master/Source/BuildControl.cs /// https://github.com/taniwha-qf/Extraplanetary-Launchpads/blob/master/License.txt /// </summary> /// <param name="_newVessel"></param> /// <param name="_srcVessel"></param> private void InitiateOrbit(Vector3 vesselPosition, Vessel _newVessel) { Debug.Log("More OrbitStuff"); var mode = OrbitDriver.UpdateMode.UPDATE; _newVessel.orbitDriver.SetOrbitMode(mode); var craftCoM = GetVesselWorldCoM(_newVessel); //var vesselCoM = _newVessel.findWorldCenterOfMass; var uTime = Planetarium.GetUniversalTime(); var vesselCoM = vesselPosition; var offset = (Vector3d.zero + craftCoM - vesselCoM).xzy; _newVessel.orbit.Init(); _newVessel.orbit.StartUT = uTime; _newVessel.orbit.referenceBody = bodyKerbin; //_newVessel.orbit.pos = vesselPosition; //_newVessel.orbit.vel = new Vector3d(0, 0, 0); //_newVessel.angularMomentum = Vector3.zero; //_newVessel.angularVelocity = Vector3.zero; _newVessel.latitude = -1.0f; _newVessel.longitude = 1.0f; _newVessel.heightFromTerrain = 0.0f; //_newVessel.SetRotation(0,0); //_newVessel.altitude = 70.8178020151099; var corb = _newVessel.orbit; corb.UpdateFromStateVectors(corb.pos + offset, _newVessel.orbit.vel, bodyKerbin, uTime); Debug.Log(String.Format("[EL] {0} {1}", "This is Orbit Info", corb.pos)); } public Vector3 GetVesselWorldCoM(Vessel v) { var com = v.findLocalCenterOfMass(); return v.rootPart.partTransform.TransformPoint(com); } } } The trouble starts when I hit the line..... part.flightID = ShipConstruction.GetUniqueFlightID(FlightDriver.FlightStateCache.flightState); Just as an excersize I commented out that line, and then it threw the exception at Debug.Log("_newVessel Die"); _newVessel.Die(); Debug.Log("New Vessel Dead"); leading me to think that it's something to do with the way I've created/modified the vessel. :-/ Code for calling the spawn...... using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace TMS_Module_001 { [KSPAddon(KSPAddon.Startup.SpaceCentre, true)] public class TMS_Stargate : MonoBehaviour { public CelestialBody bodyMun; public CelestialBody bodyKerbin; public void Awake() { string vesselName = "Module 001"; //string celestialBody = "Kerbin"; //CelestialBody celestialBody = new CelestialBody(); foreach (CelestialBody targetBody in FlightGlobals.Bodies) { if (targetBody.name == "Kerbin") bodyKerbin = targetBody; } //string targetBody = celestialBody.name; Vector3 vesselPosition = new Vector3(5f, 0f, 5f); VesselSpawner TMS_Module_001 = new VesselSpawner("TMS_Module_001.craft", vesselName, vesselPosition, bodyKerbin); Debug.Log("Spawn the Ship"); TMS_Module_001.SpawnVessel(); Debug.Log("Ship has Spawned"); } } } So again, I really hope someone can shed some light on this, even if it's a case of pointing me in the right direction of what to look at Thanks TheMightySpud The most obvious thing to check is that bodyKerbin in not null; it's not guaranteed to be set by your loop through FlightGlobal.Bodies. You should check right after the loop if it is null. I'm not sure if FlightGlobals will work in the main menu; it might work only in flight. For debugging, a thing I often do is check if each variable I'm about to pass is null (vesselName, vesselPosition, bodyKerbin) and print a message and return if it is, and print the value if it's not null (so I know I'm passing the right values). Then disable the printing for the release version. You can wrap the debugging in #if DEBUG / #endif so that it only is compiled for the debug version 6 hours ago, ShadyAct said: Will a 32-bit plugin run any differently on 64-bit KSP if it's compiled with x64 assemblies? (UnityEngine, etc.) My gut says it should work, but it's not a great idea. I keep a totally separate copy of KSP for development, with the sound off and all the graphics set to "terrible but fast", and only the mods needed for testing (if any). It makes loading a whole lot faster than trying to load my "real" copy of the copy. (You don't need to buy the game again, just copy the directory) Quote Link to comment Share on other sites More sharing options...
sarbian Posted February 16, 2016 Share Posted February 16, 2016 7 hours ago, ShadyAct said: Will a 32-bit plugin run any differently on 64-bit KSP if it's compiled with x64 assemblies? (UnityEngine, etc.) KSP plugin works fine on both unless they use native code (most don't) or where specifically build to use an architecture (which is not the default) Quote Link to comment Share on other sites More sharing options...
ShadyAct Posted February 17, 2016 Share Posted February 17, 2016 15 hours ago, sarbian said: KSP plugin works fine on both unless they use native code (most don't) or where specifically build to use an architecture (which is not the default) Could you give me an example of native code? Quote Link to comment Share on other sites More sharing options...
jkortech Posted February 17, 2016 Share Posted February 17, 2016 18 hours ago, ShadyAct said: Could you give me an example of native code? Most of Principia is written in native code (C++) except for a little C# for integrating it into KSP. That's the only one I know. It happens rarely because it is more hassle than it's worth unless you need the speed improvements afforded by having some native code. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.