![](https://forum.kerbalspaceprogram.com/uploads/set_resources_17/84c1e40ea0e759e3f1505eb1788ddf3c_pattern.png)
![](https://forum.kerbalspaceprogram.com/uploads/set_resources_17/84c1e40ea0e759e3f1505eb1788ddf3c_default_photo.png)
notfirestorm
Members-
Posts
22 -
Joined
-
Last visited
Reputation
0 NeutralProfile Information
-
About me
Bottle Rocketeer
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
-
I've played Space Engineers, and while I know what you're trying to do, I would advise against it. Two reasons: -In SE, if you build a ship with 100 blocks, you still have only one physics object the engine has to worry about. In KSP, you'll have 100 physics parts, so even a small ship will destroy your CPU -You can't have multi node connection points in KSP, so if you try to make a 5x5 grid of cubes, you'll really have a weird conga line of blocks. You could fix this by programmatically adding struts in the connection directions, but that will multiply your part count, which will destroy your CPU If you're still keen on trying this, it probably would be possible. Check out KAS to see how they handle part addition via EVA. Then you just have to make your own PartModules to do the piece-by-piece constriction of the parts.
-
Question or Idea... if you're simulating a leak in a tank, why wouldn't you want to take fuel from the stack? In real life, if fuel is flowing from one tank to another before being sent to an engine, a leak in the middle tank won't prevent fuel from leaking from the first if it flows through that tank. As long as you're doing the request resource for stuff that is flow type of STACK_PRIORITY_SEARCH, it should only drain from that part or above.
-
The question is not whether I can save from ScenarioModule, but if I can do game update logic from there; all the examples I've seen only do loading & saving from their ScenarioModule. Ah well, might as well see if it will work the same way I see if my rockets will fly... with lots and lots of explosions. And yes, I do mean Update() and not OnUpdate(). Sorry, too used to PartModules (Interesting to note that even in the ScenarioModule, it will be Update() & FixedUpdate(), but OnLoad() & OnSave(). "I don't always think of being consistent, but when I do, I light up an SRB instead")
-
A quick question on ScenarioModules & persistence. I'm looking into adding persistence to my mod, and was looking into ScenarioModule. I found it also extends from MonoBehavior, meaning it can also handle OnUpdate & OnFixedUpdate. However, I've noticed alot of the other plugins out there separate their game logic in a MonoBehavior, and their persistence in a different ScenarioModule. Is there a reason for this? If I were to do both game updates and saving/loading from the same class, will I be doing something that will summon the Kraken to destroy my Config nodes?
-
I know there's been tons of discussion on how to enable scanning while Away-From-Vessel, and I know the difficulties of working with hexagonal coordinate systems in 2D space, much less 3D space. However, I think there might be a relatively simple solution available if it is easy to convert Latitude & Longitude to a hex, and we are willing to sacrifice accuracy for the accessibility of AFV scans... Short Version: Why not just randomly discover hexes based upon the orbital characteristics of the vessel? Inclination determines the max. latitude you will pass over, so with that constraint, you can use the hex diameter and the average surface velocity along with the time spent away from vessel to uncover that number of hexes within the max. latitude. Detailed Version: The short version gives a basic idea of what this suggestion is about, but here's more detail on how to derive some of the numbers, the algorithm, etc. Again, this is assuming there is an easy conversion or lookup from Lat & Long to hex (I make this assumption because there is a Center Lat. & Long. displayed when you hover your cursor over a hex) Deriving the maximum latitude for a vessel is probably one of the easier calculations here, just normalize vessel.inclination to be between 0 & 90. if Math.abs(vessel.inclination) > 90 ) max_lat = 180 - (Math.abs( vessel.inclination) ) else max_lat = Math.abs( vessel.inclination ) Getting the average surface speed is a bit trickier. I don't know of a good way to calculate it, but I think it should be possible to ask for it while the vessel is active. Then you can have a limitation that to enable AFV scanning, you must activate the scanner and then complete an orbit (pass apoapsis twice) without running out of power or going above scanning altitude, and while doing that you can sample the surface velocity to get an average (or just find the minimum... we are sacrificing accuracy here, why not make things simple and not have to worry about time warp when trying to calculate the average?) Feel free to suggest better alternatives here, I imagine someone with an astrophysics degree could do better calculating it. Next, hex diameter. This may already be known to Kethane, but if not, here's how I would derive it. Figure out the surface area of the body (4 * pi * CelestialBody.radius^2 ), divide the total surface area by the number of hexes to get an approx. surface area per hex. You can approximate a hex with a circle, so use the area of a circle formula (Area = Pi * radius^2) to solve for the radius and also, hex diameter. The simplified version should look something like this: (note that the two Pi cancel) hex_diameter = 2 * Math.sqrt( 4 * CelestialBody.Radius^2 / number_hexes ) You can get the time spent away from vessel by comparing the universal time when you unfocus the vessel and when you reload it. Using that time diff, the hex diameter, and the surface speed, it should be simple to get the number of hexes to unveil: time_away * surface_speed / hex_diameter. After this, its a simple loop: for (int i = 0; i < num_hexes_to_unveil ; i++) { latitude = RandomFloat( -max_lat , max_lat); longitude = RandomFloat( -180.0, 180.0); uncoverHexAt( latitude, longitude); } Note that alot of this is psudocode, but I think it gets the point across. Yes, there are some tricks and mathematical hand-waving, but remember that the whole point of this approach is to sacrifice accuracy for accessibility, so I'm trying to make simplifying assumptions.
-
Depending how crazy and complicated you want to get, you could go all the way into Control Theory (http://en.wikipedia.org/wiki/Control_theory) and utilize feedback loops, PID Controllers, error signals, critically damped systems, and so on. The math can get crazy, and I forgot most of it years ago. Or, depending what you're attempting, you could go much simpler. If you're trying to do an autopilot type thing in space, when there are no other forces acting on your ship, you could just figure out where you're pointing, where you want to point, and the path you will trace out trying to get to where you want to point. Then, using that traced path, find two points on that path equidistant from the halfway point (like the 25% way there and 75% way there points). Then you can just torque towards the end position until you past the 25% point, stop torquing until you hit the 75% point, then start torquing in the reverse direction until you hit your target position. If you're not doing anything else while doing this rotation (like pumping, burning, or jettisoning fuel) this works surprisingly well for how simple it is, since you'll spend the same amount of time accelerating and decelerating your angular momentum
-
[Showcase] 0.23.5 Lifter Designs
notfirestorm replied to ScottyDoesKnow's topic in KSP1 The Spacecraft Exchange
This looks like a good place for this. So, with the new stability enhancements and the giant new SLS Rocket parts, I wondered just how crazy I could get. I wondered if I could 'Whackjob' something. I wondered if I could build something that would rival a Class E Asteroid. Apparently. On the Launchpad, it masses 6118.78 with only 747 parts (at least according to the vessel info screen on the Map view). And this: is what remains when its achieved orbit. I'd tell you what it masses in orbit, but then I'd ruin the answer to this question: What do you think masses more? This, or some random Class E Asteroid I (barely) managed to capture previously? Some other interesting stats: The Quad NERVA setup shown has enough fuel to burn for approx. 1 hour 20 minutes. If you swap out the NERVAs for the large Kerbodyne engine, you can achieve Kerbol escape velocity while inside the Kerbin system. The thing that really scares me is this: As a complete noob to 'Whackjobbing' stuff, I did this. What could Whackjob, the master himself do once his computer is fixed? -
So I've been looking through alot of examples and answers posted here on the forums (by the way, thanks for all the help everyone, whether you know it or not! ) and much of the code I've seen has been using LINQ, where you can do stuff like Collection.Where(i => i.equals(something)); or SelectAll(i => {someList.Add(new Object(i));} instead of classic for and while loops. However, when I attempt to use this style syntax, explosions of Kerbal proportions happen in my code (MissingMethodException, TypeLoadException, etc.), whereas classic foreach loops work like a charm. The latest example of this was me attempting to use Reflection to create some objects. moduleList = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(assembly => assembly.GetTypes().Where(type => type.IsSubclassOf(typeof(SubterraneanBaseModule)))) .Select(type => { return (SubterraneanBaseModule)Activator.CreateInstance(type); }).ToList<SubterraneanBaseModule>(); Blows up horrifically, failing to load the types from my .dll foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (Type t in assembly.GetTypes()) { if (t.IsSubclassOf(typeof(SubterraneanBaseModule))) { moduleList.Add(Activator.CreateInstance(t) as SubterraneanBaseModule); } } } This however, works perfectly. While I can deal with doing stuff the classic way, it makes me wonder if I've not set up my IDE correctly to build things properly for Unity to handle LINQ properly. What is everyone else doing to set up their environments that I omitted?
-
Thanks for the info and code. It does seem odd though that ActiveResources() always seems to return resources on the vessel that flow everywhere, whether they're in use or not. Looping through the parts to get the storage does seem a more reliable way of getting resources, so I'll go with that. Thanks again.
-
Hey all, I'm running into a problem I thought would be simple to solve. I want to try to grab all the resource types a vessel might have / have storage for. I thought vessel.GetActiveResources() would give me what I wanted, but it only gives me resources that flow everywhere (stuff like ElectricCharge & MonoPropellent, but not LiquidFuel or Oxidizer). Here's the code I used: GUILayout.BeginVertical(); foreach (Vessel.ActiveResource resource in vessel.GetActiveResources()) { GUILayout.BeginHorizontal(); GUILayout.Label(resource.info.name); GUILayout.EndHorizontal(); } GUILayout.EndVertical(); Y'all have any insights or suggestions?
-
Adding an EVENT to a part in code
notfirestorm replied to codepoet's topic in KSP1 C# Plugin Development Help and Support
Alright, but a problem you'll probably hit trying to make right click buttons for every crew currently in the part is that 1) you are going to be forcing all parts of your type to have that number of crew capacity, and 2) I don't think you'll be able to change the name of the events to match the Kerbal's name currently in that seat, the events will be like "Change Kerbal's socks in Seat 1" I applaud you trying not to resort to a popup window though, because they are annoying, but sometimes you don't have a choice. EDIT: Actually I take #2 back. I think you can edit the text on the fly in the OnUpdate() override method: if (part.protoModuleCrew.Count >= 1) { Events["ChangeKerbalsSocksInSeat1"].active = true; Events["ChangeKerbalsSocksInSeat1"].guiText = "Change " + part.protoModuleCrew[0].name + "'s socks"; } -
Adding an EVENT to a part in code
notfirestorm replied to codepoet's topic in KSP1 C# Plugin Development Help and Support
Question: is the events you're trying to code time-critical (like you need to toggle your air intakes on an SSTO), or are they more 'do it when you're safely in orbit'? If it's the latter, you might have more options available to you... If you don't mind learning how to make GUIs, you could make an event that shows/hides a window where you control the GUI and can loop through each crew in the part and display a button for them to change their socks. And... if there is a case where you need to change socks in an emergency, you could make two events, one that hides/shows the custom GUI window, and the other 'Emergency Change All Crew Socks' that just changes all the crews socks. Give me a few minutes to dig through my code that does stuff like this and I'll post it here. EDIT: Code followeth. This may not compile, so be warned private Boolean showingCrewSockUi = false; private Rect crewSockUiWindow= new Rect(100f, 100f, 250f, 400f); private Vector2 crewSockScrollPosition = new Vector2(0.0f, 0.0f); [KSPEvent(guiActive=true, guiName="Manage Crew Socks")] public void ManageCrewSocks() { if (!showingCrewSockUi ) { RenderingManager.AddToPostDrawQueue(0, drawCrewSocks); showingCrewSockUi = true; } } [KSPAction("Manage Crew Socks")] public void ManageCrewSocksAction(KSPActionParam param) { ManageCrewSocks(); } public void drawCrewSocks() { if (showingCrewSockUi ) { crewSockUiWindow= GUILayout.Window(424242, crewSockUiWindow, drawCrewSocksWindow, "Manage Crew Socks"); } } private void drawCrewSocksWindow(int id) { GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); GUILayout.Label("Click on a crew to change their socks!"); GUILayout.EndHorizontal(); crewSockScrollPosition = GUILayout.BeginScrollView(crewSockScrollPosition); foreach (ProtoCrewMember kerbal in part.protoModuleCrew) { GUILayout.BeginHorizontal(); if (GUILayout.Button("Change Socks of "+kerbal.name)) { ChangeCrewsSocks(kerbal); // Your internal change sock function goeth here } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Close") { RenderingManager.RemoveFromPostDrawQueue(0, drawCrewSocks); showingCrewSockUi = false; } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUI.DragWindow(); } Basically what this *should* do is give you a right click menu option that when clicked, pops up a window that should show all the kerbals currently in that part, and if you click on their names, it will change their socks, and if you click on the close button, it closes the popup window. -
Spawning ship and
notfirestorm replied to kiwiak's topic in KSP1 C# Plugin Development Help and Support
Disclaimer: I have not played with the Kethane API, so you can discard anything I say... BUT, if I was faced with this problem, what I would do is make a detector module (I think the Kethane API has interfaces/abstract classes for the detectors & extractors that you're supposed to implement/extend) and make it so the start detector event was only enabled if the vessel was landed (vessel.Landed). That way you at the very least have to be on the surface to scan, while technically you could be on a rover moving around that's probably not too big of a deal considering how big the land masses are. You could also have a bit on either the OnUpdate or OnFixedUpdate method that turns off the scanner if the vessel.Landed ever turns false (turn off the scanner if the ship takes off again) EDIT: Also, re-reading what you're asking... you could make use of the Science Experiment system to unlock the extractor, or possibly your own custom MonoBehavior to store global state if one of your detectors have successfully done some action on the planet's surface. -
Changing part behaviour
notfirestorm replied to Vertibirdo's topic in KSP1 C# Plugin Development Help and Support
Are you familiar with the creation of new PartModules in plugins? It sounds like you'd have to make a new RetractableWing part module, and in your code, when the extract wing event is fired, not only would you trigger the animation, but you'd also play with the drag and lift. (Alternatively, in the onFixedUpdate() method, check if the wing is retracted or not, and set the drag and lift accordingly) I haven't done anything with lift, but for drag, you can modify the maximum_drag property on the reference to the part to dynamically change the drag of your part.