-
Posts
24,969 -
Joined
-
Last visited
Content Type
Profiles
Forums
Developer Articles
KSP2 Release Notes
Everything posted by linuxgurugamer
-
[1.12.x] Toolbar Controller (for modders)
linuxgurugamer replied to linuxgurugamer's topic in KSP1 Mod Releases
New minor release, 0.1.6.16: Fixed harmless nullref which was occuring in a very few mods at initialization -
[1.9.x] Hangar Extender Extended
linuxgurugamer replied to linuxgurugamer's topic in KSP1 Mod Releases
And, these two dependencies should be kept up-to-date at all times -
Remapping screenshots folder
linuxgurugamer replied to Klapaucius's topic in KSP1 Technical Support (PC, unmodded installs)
yes -
Remapping screenshots folder
linuxgurugamer replied to Klapaucius's topic in KSP1 Technical Support (PC, unmodded installs)
The game does not remember numbers. You can do this using symbolic links, this article will explain it: https://www.techrepublic.com/article/how-to-take-advantage-of-symbolic-links-in-window-10/ -
Did you install the dependencies as listed in the OP? New Dependency Click Through Blocker ToolbarController
-
[1.12.x] Smart Parts Continued
linuxgurugamer replied to linuxgurugamer's topic in KSP1 Mod Releases
It is possible, but not at the present time. Also, that is getting more into the realm of an autopilot, which I'm avoiding. edit: Before I rule this out, can you explain what it is you are looking for? -
For many reasons, it’s not a good idea to put programs on the desktop. Assuming Windows 10, I would suggest the following setup for a one-drive system: In the command entry at the bottom left, type: c:\ This will open up an Explorer window on the C drive Find the folder labeled: Users. and double click it Now find the folder which is your Windows user, I’ll assume it is the same as your user name here: Double click on the folder labeled: ble210 This will open into your home directory. Right click on in the window on a blank space, and select New folder Label the new folder, I usually call it Games Double click on the new folder Copy the entire KSP folder into this new folder Now, double click on the KSP folder Find the KSP executable, right click and hold on it, and then drag that to your desktop. This will create a shortcut to the game
-
The basic idea is to allow the player to place a geocache part anywhere they want. So putting it in the air was a first step. I looked at the Vessel Mover code, and was able to incorporate it into my code, with minor modifications. This actually does what I want, so I'll be moving ahead with this. I learned a lot, thanks for your help
-
Did you try the demo first or buy the game?
linuxgurugamer replied to fyrgeit's topic in KSP1 Discussion
I saw this on twitch, and decided to buy it at that time. that was almost 4 years ago -
[1.12.x] Filter Extensions (No localization)
linuxgurugamer replied to linuxgurugamer's topic in KSP1 Mod Releases
Appreciated, I'll take a look at it later -
The current working code (except for the positioning in the air) is here: partial class GeoCacheDriver { const string VesselName = "GeoCache"; public class HideConfigNode { private ConfigNode node = null; public HideConfigNode(ConfigNode node) { this.SetConfigNode(node); } public HideConfigNode() { } public void SetConfigNode(ConfigNode node) { this.node = node; } public void SetValue(string name, string value) { node.SetValue(name, value); } public ConfigNode GetConfigNode() { return this.node; } } /// <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/KSPGeoCaching/PluginData/Ships/"; private HideConfigNode _OldVabShip; private string _craftFile = ""; private Part _srcPart = null; private Vector3 _spawnOffset = new Vector3(0, 0, 0); /// <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, Part _srcPart, Vector3 _spawnOffset) { //Store paths this._craftFile = _craftFile; this._srcPart = _srcPart; this._spawnOffset = _spawnOffset; if (this._srcPart == null) Debug.Log("Relative source part can't be null"); if ((_craftFile != String.Empty)) Debug.Log("Source part path can't be null"); } /// <summary> /// Spawns the vessel /// </summary> public void SpawnVessel() { Log.Info("SpawnVessel"); //Load craft file ShipConstruct _ship = LoadVessel(this._craftFile); if (_ship != null) SpawnVessel(_ship, this._srcPart, this._spawnOffset); else Debug.Log("Failed to load the vessel"); } /// <summary> /// Attempt vessel load /// </summary> /// <param name="_craftFile"></param> /// <returns></returns> private ShipConstruct LoadVessel(string _craftFile) { //Get path to vessel string BasePath = Environment.CurrentDirectory + PluginPath; string path = BasePath + _craftFile; Log.Info("LoadVessel, full path: " + 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 if (_shipConstruct == null) { // Restore ShipConstruction ship, otherwise player sees loaded craft in VAB ShipConstruction.ShipConfig = _OldVabShip.GetConfigNode(); Log.Info("vessel not loaded"); return null; //Fail } 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(ShipConstruct _shipConstruct, Part _srcPart, Vector3 _spawnOffset) { //Store construct root Part _newConstructRootPart = _shipConstruct.parts[0]; //Center rootpart Vector3 offset = _newConstructRootPart.transform.localPosition; _newConstructRootPart.transform.Translate(-offset); //Get launch spawn point, relative to part Transform t = _srcPart.transform; GameObject launchPos = new GameObject(); launchPos.transform.parent = _srcPart.transform; launchPos.transform.position = t.position; launchPos.transform.position += t.TransformDirection(_spawnOffset); launchPos.transform.rotation = t.rotation; //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 Vessel _newVessel = _newConstructRootPart.localRoot.gameObject.AddComponent<Vessel>(); //Attach vessel information _newVessel.id = Guid.NewGuid(); _newVessel.vesselName = _srcPart.vessel.vesselName + " - " + _shipConstruct.shipName; _newVessel.landedAt = _srcPart.vessel.vesselName; //Store backup ShipConstruction.CreateBackup(_shipConstruct); //Init from VAB _newVessel.Initialize(true); //Set Landed _newVessel.Landed = true; //Set Orbit InitiateOrbit(launchTransform.position, _srcPart.vessel, _newVessel); //Set Mission info uint missionId = (uint)Guid.NewGuid().GetHashCode(); string flagUrl = _srcPart.flagURL; uint launchId = HighLogic.CurrentGame.launchID++; //Set part mission info for (int i = 0; i < _newVessel.parts.Count; i++) { Part part = _newVessel.parts[i]; part.flightID = ShipConstruction.GetUniqueFlightID(FlightDriver.FlightStateCache.flightState); part.flagURL = flagUrl; part.launchID = launchId; part.missionID = missionId; } //Generate staging KSP.UI.Screens.StageManager.BeginFlight(); _newConstructRootPart.vessel.ResumeStaging(); KSP.UI.Screens.StageManager.GenerateStagingSequence(_newConstructRootPart.localRoot); KSP.UI.Screens.StageManager.RecalculateVesselStaging(_newConstructRootPart.vessel); //Set position, again _newVessel.SetPosition(launchTransform.position); _newVessel.SetRotation(launchTransform.rotation); ////Get allll 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); // } //} //Save Protovessel ProtoVessel _newProto = new ProtoVessel(_newVessel); //Kill and remove spawned vessel, had some serious problems with spawn position warping/glitching _newVessel.Die(); //Set the protovessels position to the relative one we found, maybe redundant _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, _srcPart.vessel); } _newProto.altitude += 10; _newProto.height += 10; //Load Protovessel _newProto.Load(HighLogic.CurrentGame.flightState); // Restore ShipConstruction ship, otherwise player sees loaded craft in VAB ShipConstruction.ShipConfig = _OldVabShip.GetConfigNode(); //Fix Control Lock FlightInputHandler.ResumeVesselCtrlState(FlightGlobals.ActiveVessel); //Fix active vessel staging FlightGlobals.ActiveVessel.ResumeStaging(); } /// <summary> /// http://forum.kerbalspaceprogram.com/threads/111116-KSP-Altitude-Calculation-Inquiry /// </summary> /// <returns></returns> private float TrueAlt(Vector3 _LauncPos, Vessel _srcVessel) { //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 _spawnPoint, Vessel _srcVessel, Vessel _newVessel) { var mode = OrbitDriver.UpdateMode.UPDATE; _newVessel.orbitDriver.SetOrbitMode(mode); var craftCoM = GetVesselWorldCoM(_newVessel); var vesselCoM = _spawnPoint; var offset = (Vector3d.zero + craftCoM - vesselCoM).xzy; var corb = _newVessel.orbit; var orb = _srcVessel.orbit; var UT = Planetarium.GetUniversalTime(); var body = orb.referenceBody; corb.UpdateFromStateVectors(orb.pos + offset, orb.vel, body, UT); Debug.Log(String.Format("[EL] {0} {1}", "orb", orb.pos)); Debug.Log(String.Format("[EL] {0} {1}", "corb", corb.pos)); } public Vector3 GetVesselWorldCoM(Vessel v) { var com = v.CoM; return v.rootPart.partTransform.TransformPoint(com); } } } @taniwha Any ideas?
-
Oh, the activate toggle will be on all engines. The deactivate will only be on active engines. I was referring to the possibility that the activate toggle will be there all the time, even if some engines are activated. I've solved this by having a coroutine with a 1 second sleep, so the menu will be updated once a second for this. Minimal impact to the game, but full functionality for what I want
-
I started with that, but it has some issues. I've rewritten what I have using code from an old mod KSP-Smelter. It's working much better, the only thing that is still not working properly is this: The new vessel gets created where I expect, but then (maybe when physics kicks in) instantly is on the ground I want the new vessel to be created in the air and offset from the vessel
-
I'm trying to create a vessel from a part, and have it created about 10-20m in the air, and about 10m away from the current vessel. I have it creating the vessel, but with problems: Modules aren't initialized Additional vessels created will always be created at the same location, even if the current active vessel moves away The new vessel gets created where I expect, but then (maybe when physics kicks in) instantly is on the ground I've been looking at a number of mods which create vessels, and have so far been unable to figure this out. Pinging @nightingale @RoverDude @taniwha since I've been looking at your mods for help. Thanks in advance The code is here: using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; using KSP; using System.Collections; namespace KSPGeoCaching { public static class LocationUtil { public static double TerrainHeight(double latitude, double longitude, CelestialBody body) { // Sun and Jool - bodies without terrain if (body.pqsController == null) { return 0; } // Figure out the terrain height double latRads = Math.PI / 180.0 * latitude; double lonRads = Math.PI / 180.0 * longitude; Vector3d radialVector = new Vector3d(Math.Cos(latRads) * Math.Cos(lonRads), Math.Sin(latRads), Math.Cos(latRads) * Math.Sin(lonRads)); return Math.Max(body.pqsController.GetSurfaceHeight(radialVector) - body.pqsController.radius, 0.0); } } partial class GeoCacheDriver : Monobehaviour { const string VesselName = "GeoCache"; internal class KD { internal double altitude; public double latitude = 0.0; public double longitude = 0.0; public CelestialBody body = null; public Orbit orbit = null; public bool landed = false; //public float heading; public AvailablePart craftPart; public KD() { latitude = FlightGlobals.ActiveVessel.latitude; longitude = FlightGlobals.ActiveVessel.longitude; body = FlightGlobals.ActiveVessel.mainBody; orbit = FlightGlobals.ActiveVessel.orbit; landed = FlightGlobals.ActiveVessel.Landed; altitude = FlightGlobals.ActiveVessel.altitude; // LocationUtil.TerrainHeight(latitude, longitude, body); // heading = FlightGlobals.ActiveVessel.head Log.Info("Creation Latitude: " + latitude + ", Longitude: " + longitude); } } internal void Spawn() { KD kd = new KD(); Log.Info("Spawning a GeoCache" ); // Set additional info for landed if (kd.landed) { Vector3d pos = kd.body.GetWorldSurfacePosition(kd.latitude, kd.longitude, kd.altitude); kd.orbit = new Orbit(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, kd.body); kd.orbit.UpdateFromStateVectors(pos, kd.body.getRFrmVel(pos), kd.body, Planetarium.GetUniversalTime()); } else { // Update the reference body in the orbit kd.orbit.referenceBody = kd.body; } uint flightId = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); kd.craftPart = PartLoader.getPartInfoByName("geocache"); // Create part nodes ConfigNode[] partNodes = new ConfigNode[1]; partNodes[0] = ProtoVessel.CreatePartNode(kd.craftPart.name, flightId, null); // Create additional nodes ConfigNode[] additionalNodes = new ConfigNode[0]; // Create the config node representation of the ProtoVessel ConfigNode protoVesselNode = ProtoVessel.CreateVesselNode(VesselName, VesselType.Probe, kd.orbit, 0, partNodes); // Additional seetings for a landed vessel if (kd.landed) { bool splashed = kd.altitude < 0.001 && kd.body.ocean; // Add a bit of height for landed if (!splashed) { kd.altitude += 40.2; Log.Info("Adding 40.2 to altitude"); } //Guid vesselId = vessel.id; // Figure out the appropriate rotation Vector3d norm = kd.body.GetRelSurfaceNVector(kd.latitude, kd.longitude); double terrainHeight = 0.0; if (kd.body.pqsController != null) { terrainHeight = kd.body.pqsController.GetSurfaceHeight(norm) - kd.body.pqsController.radius; } // Create the config node representation of the ProtoVessel protoVesselNode.SetValue("sit", (splashed ? Vessel.Situations.SPLASHED : Vessel.Situations.LANDED).ToString()); protoVesselNode.SetValue("landed", (!splashed).ToString()); protoVesselNode.SetValue("splashed", splashed.ToString()); protoVesselNode.SetValue("lat", kd.latitude); protoVesselNode.SetValue("lon", kd.longitude); protoVesselNode.SetValue("alt", kd.altitude); protoVesselNode.SetValue("landedAt", kd.body.name); float lowest = float.MaxValue; foreach (Collider collider in kd.craftPart.partPrefab.GetComponentsInChildren<Collider>()) { if (collider.gameObject.layer != 21 && collider.enabled) { lowest = Mathf.Min(lowest, collider.bounds.min.y); } } if (Mathf.Approximately(lowest, float.MaxValue)) { lowest = 0; } float hgt = kd.craftPart.partPrefab.localRoot.attPos0.y - lowest; hgt += 10; protoVesselNode.SetValue("hgt", hgt); // Set the normal vector relative to the surface Quaternion normal = Quaternion.LookRotation(new Vector3((float)norm.x, (float)norm.y, (float)norm.z)); Quaternion rotation = Quaternion.identity; rotation = rotation * Quaternion.FromToRotation(Vector3.up, Vector3.back); Vector3 nrm = (rotation * Vector3.forward); protoVesselNode.SetValue("prst", false.ToString()); protoVesselNode.SetValue("nrm", nrm.x + "," + nrm.y + "," + nrm.z); } ProtoVessel protoVessel = HighLogic.CurrentGame.AddVessel(protoVesselNode); //protoVessel.Load(HighLogic.CurrentGame.flightState); protoVessel.vesselName = VesselName; vessel = protoVessel.vesselRef; if (vessel != null) { //var mode = OrbitDriver.UpdateMode.UPDATE; //vessel.orbitDriver.SetOrbitMode(mode); vessel.Load(); launchPoint = vessel.GetWorldPos3D(); // Offset the position by 10m in y and z to have it created away from the current vessel launchPoint.y += 10; launchPoint.z += 10; StartCoroutine("SpawnCoRoutine"); } } Vessel vessel; Vector3 launchPoint; IEnumerator SpawnCoRoutine() { if ((vessel.Parts[0] != null) && (vessel.Parts[0].Rigidbody != null)) { vessel.Parts[0].Rigidbody.isKinematic = true; } //vessel.GoOnRails(); while ((vessel.packed) && (vessel.acceleration.magnitude == 0)) { vessel.SetPosition(launchPoint); yield return null; } while (true) { bool partsInitialized = true; foreach (Part p in vessel.parts) { if (!p.started) { partsInitialized = false; break; } } vessel.SetPosition(launchPoint, true); //vessel.SetWorldVelocity(Vector3d.up * 0); if (partsInitialized) { break; } OrbitPhysicsManager.HoldVesselUnpack(2); yield return null; } vessel.GoOffRails(); //flare.IgnoreGForces(250); Log.Info("Final Latitude: " + vessel.latitude + ", Longitude: " + vessel.longitude); } } }
-
I've gotten both of these implemented, but a question: For engines which are not in the current stage, I currently have it so that if no engines are activated, the action to enable all engines in the current stage is shown. In order to not have that message shown when engines are activated, I need to check all parts of a vessel. This can be quite a performance impactor, so I'm considering one of the following: Make the checks for this action much slower, about 1x/second Ignore the fact that the message will be shown on engines which are not in the current stage. I don't imagine it would be that often that someone will right-click an engine in a stage which is not activated. Comments?
-
For Questions That Don't Merit Their Own Thread
linuxgurugamer replied to Skyler4856's topic in Science & Spaceflight
New York state wildlife expert Richard Thomas found that a woodchuck could (and does) chuck around 35 cubic feet of dirt in the course of digging a burrow. Thomas reasoned that if a woodchuck could chuck wood, he would chuck an amount equivalent to the weight of the dirt, or 700 pounds. https://mylandplan.org/content/how-much-wood-would-woodchuck-chuck-if-woodchuck-could-chuck-wood -
[1.5.1] Cacteye Optics Community Takeover
linuxgurugamer replied to icedown's topic in KSP1 Mod Releases
@icedown is working on a major rewrite of this mod, read back a page or so to see some details -
New release, 0.7.17.1: Thanks to user @Bogen for this: Make parts repairable after reload
-
@5thHorseman Always appreciate input from the original author. And I wasn't aware that X deactived all engines in the current stage. And, regarding the earlier comment about RCS, it is a lot harder to balance a vessel by turning various rcs on and off than it is to simply change the thrust limiter. So, I'm not sure I'm going to go ahead with this, unless a compelling case could be made.
-
To continue the discussion, what exactly would you want this to do? My ideas are: Activate all engines Activate all engines in current stage Activate all engines connected to part Deactivate all engines Deactivate all engines in current stage Deactivate all engines connected to part Activate all RCS Deactivate all RCS Activate all RCS connected to part Deactivate all RCS connected to part
-
[1.11.1] Hullcam VDS Continued
linuxgurugamer replied to linuxgurugamer's topic in KSP1 Mod Releases
You probably could, and yes, I believe the cameramode would do it