Jump to content

TheDog

Members
  • Posts

    165
  • Joined

Everything posted by TheDog

  1. I had a request to share my updated DLL, and I thought of this solution: I have a temporary, unofficial patch release of my updates here: https://github.com/TheDogKSP/XanderTek_XTLandertron/releases (patched DLL and source only - you still need to download from the front page here first, then replace the DLL!) **This will get pulled once XanderTek updates his release, so his release (and this thread) remains the "single version of the truth"** This will also get pulled should XanderTek disapprove of this unofficial patch distribution.
  2. Pull request has been sent to LordFjord! Hope he can integrate this for a new release soon. (this has cost be 2 hours of my life now... either I am too stupid for github, or I really need a good tutorial about forking, cloning, ....)
  3. CHeck you dont have a blank line somewhere (e.g. at the end of the file) - blank line matches everything, thus all files would be excepted...
  4. good news: I have fixed the toolbar problem (multiple copies, unresponsive button) here locally. IntakebuildAid now works here for KSP 1.0.2. Only little code changes for the Applauncher registration/deregistration is needed. LordFjord, this is the updated IntakeBuildAid.cs (sorry, I have no clue how to get this as a pull request to the githb repo): using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace IntakeBuildAid { [KSPAddon( KSPAddon.Startup.EditorAny, false )] public class IntakeBuildAid : MonoBehaviour { private EditorLogic _editor; private static Material _material; // shader to highlight stuff // highlight colors private static Color _selectedIntakeColor = new Color( 0f, 0.2f, 1f, 1f ); private static Color _selectedEngineIntakeColor = new Color( 0f, 0.2f, 1f, 1f ); // todo: pick better colors... private static Color _selectedEngineColor = new Color( 1f, 0f, 0f, 1f ); private static Color _selectedIntakeEngineColor = new Color( 1f, 0f, 0f, 1f ); // todo: pick better colors... // used for highlighting intakes and engines private static Dictionary<Part, List<SavedMaterial>> _managedParts; private static Part _mouseOverPart; // used to manually select and assign intakes to engines private static List<Part> _manualAssignedList; // from settings private static bool _useCustomShader; private static KeyCode _keyHighlight = KeyCode.F6; private static KeyCode _keyBalanceIntakes = KeyCode.F7; private static KeyCode _keyManualAssign = KeyCode.F8; // toolbar private ApplicationLauncherButton _launcherButton = null; // toolbar private bool _guiVisible; private Rect _guiRect; public void Start() { _material = new Material( global::IntakeBuildAid.Resource.OutlineShaderContents ); _managedParts = new Dictionary<Part, List<SavedMaterial>>(); _manualAssignedList = new List<Part>(); GameEvents.onPartAttach.Add( OnPartAttach ); _useCustomShader = false; LoadSettings(); _editor = EditorLogic.fetch; // init GUI //GameEvents.onGUIApplicationLauncherReady.Add( OnGUIApplicationLauncherReady ); OnGUIApplicationLauncherReady(); _guiRect = new Rect( ( Screen.width ) / 4, Screen.height / 2, 300, 100 ); _guiVisible = false; Utils.DebugLog( "IntakeBuildAid Start() finished" ); } private void LoadSettings() { ConfigNode config = ConfigNode.Load( KSPUtil.ApplicationRootPath + "GameData/IntakeBuildAid/settings.cfg" ); if ( config == null ) { Utils.Log( "Failed to load settings.cfg" ); } else { ConfigNode rootNode = config.GetNode( "IntakeBuildAid" ); if ( rootNode != null ) { _useCustomShader = rootNode.GetValue( "useCustomShader" ) == "true"; _keyHighlight = (KeyCode)Enum.Parse( typeof( KeyCode ), rootNode.GetValue( "keyHighlight" ) ); _keyBalanceIntakes = (KeyCode)Enum.Parse( typeof( KeyCode ), rootNode.GetValue( "keyBalanceIntakes" ) ); _keyManualAssign = (KeyCode)Enum.Parse( typeof( KeyCode ), rootNode.GetValue( "keyManualAssign" ) ); } } } public void OnPartAttach( GameEvents.HostTargetAction<Part, Part> eventData ) { PartType partType = GetPartType( eventData.host ); if ( partType == PartType.AirBreatherEngine || partType == PartType.Intake || partType == PartType.IntakeAndEngine ) { eventData.host.AddOnMouseEnter( OnMouseEnter ); eventData.host.AddOnMouseExit( OnMouseExit ); Utils.DebugLog( "Added events for part: {0}", eventData.host.name ); } } public void OnPartDetach( GameEvents.HostTargetAction<Part, Part> eventData ) { ResetAllColors(); } private void OnMouseExit( Part p ) { _mouseOverPart = null; } private void OnMouseEnter( Part p ) { _mouseOverPart = p; } private void Update() { if ( !HighLogic.LoadedSceneIsEditor ) { Destroy( this ); return; } if ( Input.GetKeyDown( _keyHighlight ) ) { #region Highlight intakes and engines if ( _mouseOverPart != null ) { ResetAllColors(); // mouse is over a part // check if part is intake PartType partType = this.GetPartType( _mouseOverPart ); if ( partType == PartType.Intake ) { Utils.DebugLog( "Intake found: {0}", _mouseOverPart.name ); ColorPart( _mouseOverPart, _selectedIntakeColor ); // find engine and set color Part intakeEngine = FindEngineOfIntake( _mouseOverPart ); if ( intakeEngine != null ) { ColorPart( intakeEngine, _selectedIntakeEngineColor ); } return; } // check if part is engine else if ( partType == PartType.AirBreatherEngine || partType == PartType.IntakeAndEngine ) { Utils.DebugLog( "Engine found: {0}", _mouseOverPart.name ); ColorPart( _mouseOverPart, _selectedEngineColor ); List<Part> engineIntakes = FindIntakesOfEngine( _mouseOverPart ); Utils.DebugLog( "Intakes found: {0}", string.Join( ", ", engineIntakes.Select( x => x.name ).ToArray() ) ); foreach ( Part part in engineIntakes ) { ColorPart( part, _selectedEngineIntakeColor ); } return; } ResetAllColors(); return; } else { ResetAllColors(); } #endregion Highlight intakes and engines } else if ( Input.GetKeyDown( _keyManualAssign ) && _mouseOverPart != null ) { #region Manual assign intakes to engines // get type of part PartType partType = GetPartType( _mouseOverPart ); if ( partType == PartType.Intake ) { if ( !_manualAssignedList.Contains( _mouseOverPart ) ) { // add part to manually assigned list _manualAssignedList.Add( _mouseOverPart ); ColorPart( _mouseOverPart, _selectedIntakeColor ); Utils.Log( "Part {0} added to manual assigned list.", _mouseOverPart.name ); } else { // remove part from manually assigned list _manualAssignedList.Remove( _mouseOverPart ); ResetColor( _mouseOverPart ); Utils.Log( "Part {0} removed from manual assigned list.", _mouseOverPart.name ); } } else if ( partType == PartType.AirBreatherEngine || partType == PartType.IntakeAndEngine ) { // end manual assignment once an engine is selected // add engine to manual list _manualAssignedList.Add( _mouseOverPart ); // now turn off all coloring foreach ( Part part in _manualAssignedList ) { ResetColor( part ); } // remove these parts from the ship _editor.ship.Parts.RemoveAll( x => _manualAssignedList.Contains( x ) ); // re-add parts to ship, these now are in a proper order _editor.ship.Parts.AddRange( _manualAssignedList ); Utils.Log( "Finished manual intake-engine assignment: {0}", string.Join( ", ", _manualAssignedList.Select( x => x.name ).ToArray() ) ); _manualAssignedList.Clear(); // reset list } #endregion Manual assign intakes to engines } else if ( Input.GetKeyDown( _keyBalanceIntakes ) ) // key triggers { #region Balance intakes to engines // order intakes desceding by intake area BalanceIntakes(); #endregion Balance intakes to engines } #region Debug stuff #if DEBUG else if ( Input.GetKeyDown( KeyCode.F11 ) ) { Utils.DebugLog( "Ship partList:\r\n {0}", string.Join( "\r\n ", _editor.ship.parts.Select( x => x.name ).ToArray() ) ); // dump some logs if ( _managedParts != null && _managedParts.Count > 0 ) { Utils.DebugLog( "ManagedParts: {0}", string.Join( ", ", _managedParts.Select( x => x.Key.name ).ToArray() ) ); } if ( _manualAssignedList != null && _manualAssignedList.Count > 0 ) { Utils.DebugLog( "ManualList: {0}", string.Join( ", ", _manualAssignedList.Select( x => x.name ).ToArray() ) ); } } #endif #endregion Debug stuff } public void OnDestroy() { Utils.DebugLog( "OnDestroy" ); if ( _managedParts != null ) { foreach ( KeyValuePair<Part, List<SavedMaterial>> kvp in _managedParts ) { ResetColor( kvp.Key ); } } _managedParts.Clear(); _manualAssignedList.Clear(); //TheDog, 03.05.2015: FIXED for KSP 1.0.2 if (_launcherButton != null) { ApplicationLauncher.Instance.RemoveModApplication( _launcherButton ); //GameEvents.onGUIApplicationLauncherReady.Remove( OnGUIApplicationLauncherReady ); Destroy( this ); _launcherButton = null; } } #region Helpers private void BalanceIntakes() { Queue<Part> intakeQueue = new Queue<Part>( _editor.ship.Parts.Where( x => GetPartType( x ) == PartType.Intake ) // do not treat intakeandengine parts as intake but as engine .OrderByDescending( x => x.Modules.OfType<ModuleResourceIntake>().First().area ) ); // queue is easier to handle when distributing items to engines - this makes sure we can only handle a part once Utils.Log( "Intakes found: {0}", string.Join( ", ", intakeQueue.Select( x => x.partInfo.title + ": " + x.Modules.OfType<ModuleResourceIntake>().First().area ).ToArray() ) ); List<WeightedPartList> totalPartList = new List<WeightedPartList>(); // so far all jets have intakeair ratio of 15, so we treat jets, turbos and rapiers alike // TODO for future: take intakeair ratio into account. how exactly? I donno // handle engines grouped by type, so far its by placement order foreach ( Part part in _editor.ship.parts ) { if ( GetPartType( part ) == PartType.AirBreatherEngine ) { WeightedPartList wpl = new WeightedPartList(); wpl.AddPart( part ); totalPartList.Add( wpl ); } else if ( GetPartType( part ) == PartType.IntakeAndEngine ) { WeightedPartList wpl = new WeightedPartList(); wpl.IntakeAreaSum = part.Modules.OfType<ModuleResourceIntake>().First().area; // add intake area of part that has both intake and engine in one wpl.AddPart( part ); totalPartList.Add( wpl ); } } Utils.Log( "Jets found: {0}", string.Join( ", ", totalPartList.Select( x => x.PartList.First().partInfo.title ).ToArray() ) ); if ( intakeQueue.Count > 0 && totalPartList.Count > 0 ) { // strip ship from intakes and jets _editor.ship.parts.RemoveAll( x => intakeQueue.Contains( x ) ); Utils.Log( "removed intakes temporarily" ); _editor.ship.parts.RemoveAll( x => totalPartList.Select( y => y.PartList.First() ).Contains( x ) ); Utils.Log( "removed jets temporarily" ); int intakeCount = intakeQueue.Count; for ( int i = 0; i < intakeCount; i++ ) { Part part = intakeQueue.Dequeue(); totalPartList.Where( x => x.IntakeAreaSum == totalPartList.Min( y => y.IntakeAreaSum ) ).First().AddPart( part ); // WeightedPartList with the least IntakeAreaSum will get the next intake assigned } // go through all part lists, reverse them and add them back to ship foreach ( WeightedPartList partList in totalPartList ) { partList.PartList.Reverse(); _editor.ship.parts.AddRange( partList.PartList ); // add parts for engine and its intakes back to ship Utils.Log( "Intake/engine set: {0}, total intake area: {1}", string.Join( ", ", partList.PartList.Select( x => x.name ).ToArray() ), partList.IntakeAreaSum ); } Utils.Log( "Finished intakes - jets balance" ); } else { Utils.Log( "There are either no intakes or no engines" ); } } private void ColorPart( Part part, Color color ) { if ( !_managedParts.ContainsKey( part ) ) { if ( _useCustomShader ) { List<SavedMaterial> savedMaterials = new List<SavedMaterial>(); Renderer[] renderers = part.FindModelComponents<Renderer>(); if ( renderers.Length > 0 ) { for ( int i = 0; i < renderers.Length; ++i ) { savedMaterials.Insert( i, new SavedMaterial() { Shader = renderers[i].sharedMaterial.shader, Color = renderers[i].sharedMaterial.GetColor( "_Color" ) } ); renderers[i].sharedMaterial.shader = _material.shader; renderers[i].sharedMaterial.SetColor( "_Color", color ); } _managedParts.Add( part, savedMaterials ); } } else { part.SetHighlight( true, false ); part.SetHighlightColor( color ); part.SetHighlightType( Part.HighlightType.AlwaysOn ); } } } private void ResetColor( Part part ) { if ( _useCustomShader ) { if ( _managedParts.ContainsKey( part ) ) { List<SavedMaterial> savedMaterials = _managedParts[part]; if ( savedMaterials.Count == 0 ) { _managedParts.Remove( part ); return; } Renderer[] renderers = part.FindModelComponents<Renderer>(); if ( renderers.Length > 0 ) { for ( int i = 0; i < renderers.Length; ++i ) { renderers[i].sharedMaterial.shader = savedMaterials[i].Shader; renderers[i].sharedMaterial.SetColor( "_Color", savedMaterials[i].Color ); } } if ( _managedParts.ContainsKey( part ) ) { _managedParts.Remove( part ); } } } else { part.SetHighlight( false, true ); if ( _managedParts.ContainsKey( part ) ) { _managedParts.Remove( part ); } } } private void ResetAllColors() { foreach ( Part part in _editor.ship.parts ) { ResetColor( part ); } _managedParts.Clear(); } private void OnGUIApplicationLauncherReady() { //TheDog, 03.05.2015: FIXED for KSP 1.0.2 if (_launcherButton != null) { return; } // Create the button in the KSP AppLauncher Utils.DebugLog( "Adding toolbar icon" ); _launcherButton = ApplicationLauncher.Instance.AddModApplication( ToggleGUI, ToggleGUI, null, null, null, null, ApplicationLauncher.AppScenes.SPH | ApplicationLauncher.AppScenes.VAB, GameDatabase.Instance.GetTexture( "IntakeBuildAid/icons/Toolbar", false ) ); _launcherButton.toggleButton.startTrue = true; //TheDog, 03.05.2015: FIXED for KSP 1.0.2 //GameEvents.onGUIApplicationLauncherReady.Remove (OnGUIApplicationLauncherReady); } private Part FindEngineOfIntake( Part intakePart ) { if ( GetPartType( intakePart ) != PartType.Intake ) { return null; } int startIndex = _editor.ship.Parts.IndexOf( intakePart ); for ( int i = startIndex; i <= _editor.ship.Parts.Count - 1; i++ ) { if ( GetPartType( _editor.ship.Parts[i] ) == PartType.AirBreatherEngine || GetPartType( _editor.ship.Parts[i] ) == PartType.IntakeAndEngine ) { return _editor.ship.Parts[i]; } // handle loop overflow if ( i == _editor.ship.Parts.Count - 1 ) { i = 0; } if ( i == startIndex - 1 ) { break; // no engines found } } return null; } private List<Part> FindIntakesOfEngine( Part enginePart ) { PartType enginePartType = GetPartType( enginePart ); if ( !(enginePartType == PartType.AirBreatherEngine || enginePartType == PartType.IntakeAndEngine ) ) { Utils.DebugLog("Part is no engine, cant find its intakes."); return null; } List<Part> intakes = new List<Part>(); int startIndex = _editor.ship.Parts.IndexOf( enginePart ); // find index of engine in the part list for ( int i = startIndex - 1; i >= 0; i-- ) // iterate backwards from the engine, find all intakes { PartType partType = GetPartType( _editor.ship.Parts[i] ); if ( partType == PartType.AirBreatherEngine || partType == PartType.IntakeAndEngine ) { Utils.DebugLog( "FindIntakesOfEngine at {0}, engine: {1}", i, _editor.ship.Parts[i].name ); break; // we found another engine, done } else if ( partType == PartType.Intake ) { intakes.Add( _editor.ship.Parts[i] ); // add found intake to the list } // handle loop overflow, if there is no engine at the end of the partlist, there might be some more intakes that belong to the engine at the end of the list. if ( i == 0 ) { i = _editor.ship.Parts.Count; // start at the end of the list again Utils.DebugLog( "FindIntakesOfEngine reset loop" ); } if ( i == startIndex ) { Utils.DebugLog( "FindIntakesOfEngine done" ); break; // we are through the list, abort } } return intakes; } private PartType GetPartType( Part part ) { // find engines by ModuleEngines and ModuleEnginesFX module with intakeair propellant // this is for modded engines that are both intakes and engines in one part if ( ( ( part.Modules.OfType<ModuleEnginesFX>().Any( x => x.propellants.Any( y => y.name == "IntakeAir" ) ) ) || ( part.Modules.OfType<ModuleEngines>().Any( x => x.propellants.Any( y => y.name == "IntakeAir" ) ) ) ) && ( part.Modules.OfType<ModuleResourceIntake>().Any( x => x.resourceName == "IntakeAir" ) ) ) { return PartType.IntakeAndEngine; } // find engines by ModuleEngines and ModuleEnginesFX module with intakeair propellant else if ( ( part.Modules.OfType<ModuleEnginesFX>().Any( x => x.propellants.Any( y => y.name == "IntakeAir" ) ) ) || ( part.Modules.OfType<ModuleEngines>().Any( x => x.propellants.Any( y => y.name == "IntakeAir" ) ) ) ) { return PartType.AirBreatherEngine; } // find intakes by resource intakeair else if ( part.Modules.OfType<ModuleResourceIntake>().Any( x => x.resourceName == "IntakeAir" ) ) { return PartType.Intake; } else { return PartType.SomethingElse; } } #endregion Helpers #region GUI // old shabby onscreen message... //GUIStyle osdLabelStyle; //private void InitStyles() //{ // osdLabelStyle = new GUIStyle(); // osdLabelStyle.stretchWidth = true; // osdLabelStyle.alignment = TextAnchor.MiddleCenter; // osdLabelStyle.fontSize = 24; // osdLabelStyle.fontStyle = FontStyle.Bold; // osdLabelStyle.normal.textColor = Color.black; //} //float messageCutoff = 0; //string messageText = ""; //private void OSDMessage( string message, float delay ) //{ // messageCutoff = Time.time + delay; // messageText = message; // Utils.DebugLog( messageText ); //} //private void DisplayOSD() //{ // if ( Time.time < messageCutoff ) // { // GUILayout.BeginArea( new Rect( 0, ( Screen.height / 4 ), Screen.width, Screen.height / 2 ), osdLabelStyle ); // GUILayout.Label( messageText, osdLabelStyle ); // GUILayout.EndArea(); // } //} public void OnGUI() { if(_guiVisible) { _guiRect = GUILayout.Window( 0, _guiRect, PaintWindow, "Intake Build Aid" ); } } private void ToggleGUI() { if ( _guiVisible ) { // hide GUI _guiVisible = false; Utils.DebugLog( "GUI hidden" ); } else { // show GUI _guiVisible = true; Utils.DebugLog( "GUI shown" ); } } private void PaintWindow(int windowID) { GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); if ( GUILayout.Button( "Autoarrange engines and intakes" ) ) { BalanceIntakes(); } if ( GUILayout.Button( "Close" ) ) { _guiVisible = false; } GUILayout.EndHorizontal(); foreach ( Part engine in _editor.ship.parts.Where( x => GetPartType( x ) == PartType.AirBreatherEngine ) ) { List<Part> intakes = FindIntakesOfEngine( engine ); GUILayout.Label( string.Format( "{0}: ∑={1}", engine.partInfo.title, intakes.Sum( x => x.Modules.OfType<ModuleResourceIntake>().First().area ) ) ); foreach ( Part intake in intakes ) { GUILayout.BeginHorizontal(); GUILayout.Label( string.Format( " {0}: {1}", intake.partInfo.title, intake.Modules.OfType<ModuleResourceIntake>().First().area ) ); GUILayout.EndHorizontal(); } } foreach ( Part engine in _editor.ship.parts.Where( x => GetPartType( x ) == PartType.IntakeAndEngine ) ) { List<Part> intakes = FindIntakesOfEngine( engine ); GUILayout.Label( string.Format( "{0}: ∑={1}", engine.partInfo.title, intakes.Sum( x => x.Modules.OfType<ModuleResourceIntake>().First().area ) + engine.Modules.OfType<ModuleResourceIntake>().First().area ) ); foreach ( Part intake in intakes ) { GUILayout.BeginHorizontal(); GUILayout.Label( string.Format( " {0}: {1}", intake.partInfo.title, intake.Modules.OfType<ModuleResourceIntake>().First().area ) ); GUILayout.EndHorizontal(); } } GUILayout.EndVertical(); GUI.DragWindow(); } #endregion GUI } } If someone can advise me how to make pull requests out of a locally cloned github repo, I'd be very grateful!
  5. Hi XanderTek, indeed for me it didnt work in 1.0 (1.0.2). I took the freedom to look at your source, and I *believe* I have fixed all instances where 1.0 changed something. (most important was vessel.staticPressure no longer exists, thus my landertrons could not figure out when to fire). Updated source landertron.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; public class Landertron : PartModule { //[KSPField(guiActive = true, guiActiveEditor=true ,isPersistant=true),UI_FloatRange(maxValue=1.5f,minValue=0.5f,stepIncrement=0.05f)] //public float heightmultiplier = 1; //[KSPField(guiActive = true, guiActiveEditor = true, isPersistant = true), UI_FloatRange(maxValue = 3, minValue = -3f, stepIncrement = 0.1f)] //public float offset = 0; //[KSPField(guiActive = false)] //public float endheight = 0; [KSPField(guiActive = false, guiActiveEditor = true, isPersistant = true), UI_FloatRange(maxValue = 10, minValue = 0, stepIncrement = 0.5f)] public float endspeed = 0; [KSPField(guiActive = false)] public bool boom = false; [KSPField(guiActive = false)] public bool showgui = true; [KSPField(guiActive = false)] public bool refuelable = true; //[KSPField(guiActive = false)] //public bool engineShutdown = true; [KSPField(guiActive = false)] public float electricrate = 0.05f; [KSPField(guiActive = false, guiActiveEditor=false ,isPersistant=true)] public int mode = 0; public float thrust = 0; [KSPField(isPersistant = false, guiActiveEditor = false, guiActive = false)] public string Status = "Idle"; [KSPField(isPersistant = false, guiActiveEditor = true, guiActive = true)] public string ModeName = " "; //[KSPField(isPersistant = false, guiActiveEditor = false, guiActive = true)] public double deltaV = 0; public float m = 0; public float elec_dem = 0; public float elec_rec = 0; public float totalfuelmass = 0; public double totalthrust = 0; public double partanglethrust = 0; public double vesselanglethrust = 0; public double localg; public double gee = 0; public double vaccel = 0; public double backgroundaccel = 0; public double vh_prev = 1000; public double v = 0; [KSPField(isPersistant = false, guiActive = true, guiName = "Braking Distance", guiUnits = "m")] public float displayd = 0; public double dfinal = 0; public double dmin = 0; public bool fire = false; public bool arm = false; public bool end = false; public bool firing = false; public bool warning = false; public bool prevland = true; public static bool globaljustrefueled = false; public bool justrefueled = false; protected ModuleEngines engine; protected PartResource sf; protected Landertron ltron; public Vector3d pos; public Vector3d up; public Vector3d acc; public Vector3d vel; [KSPField(guiActive=false)] public int lcount = 0; public RaycastHit craft; public Part mpart; public float isp; public float burntime; [KSPField(isPersistant = false)] public string AnimationName; private AnimationState[] animStates; private bool animdeployed=false; public override void OnAwake() { lcount = 0; } public override void OnStart(PartModule.StartState state) { engine = this.part.Modules["ModuleEngines"] as ModuleEngines; sf = this.part.Resources["SolidFuel"]; if (HighLogic.LoadedScene == GameScenes.EDITOR && mode == 0) { mode = 2; } else if (HighLogic.LoadedScene == GameScenes.EDITOR && mode == 0) { mode = 1; } switch(mode) { case 1: ModeName = "Soft Landing"; break; case 2: ModeName = "Short Landing"; break; case 3: ModeName = "StayPut"; break; } guifixer(); animStates = SetUpAnimation(AnimationName, this.part); //GameEvents.onJointBreak.Add(onJointBreak); } //private void onJointBreak(EventReport eventreport) //{ print("Something detatched! ");} /*[KSPEvent(guiName = "Refuel",guiActive=false ,externalToEVAOnly = true, guiActiveUnfocused = true, unfocusedRange = 3.0f)] public void Refuel() { double sf_available = 0; int containercount=0; foreach (Part p in vessel.parts) { if (!p.Modules.Contains("Landertron") && p.Resources.Contains("SolidFuel")) { PartResource sfp = p.Resources["SolidFuel"]; sf_available += sfp.amount; containercount++; } } //print("avail: " + sf_available); double sf_needed = sf.maxAmount - sf.amount; double sf_added = Math.Min(sf_available, sf_needed); sf.amount += sf_added; foreach (Part p in vessel.parts) { if (!p.Modules.Contains("Landertron") && p.Resources.Contains("SolidFuel")) { PartResource sfp = p.Resources["SolidFuel"]; sfp.amount -= sf_added/containercount; } } justrefueled = true; animdeployed = false; }*/ public void Refuel() { /*int ccount = 0; foreach (Part p in this.part.children) { print("name: "+p.name); p.Die(); //p.explosionPotential = 0; //p.explode(); //ccount++; }*/ for (int i = 0; i < this.part.children.Count; ) { Part p = this.part.children[i]; if (p.Resources.Contains("SolidFuel") && sf.amount < sf.maxAmount) { PartResource sfp = p.Resources["SolidFuel"]; sf.amount = Math.Min(sf.amount + sfp.amount, sf.maxAmount); //print("name: " + p.name); p.Die(); justrefueled = true; animdeployed = false; } else ++i; } /*if (ccount > 0) { for (int i = 0; i < ccount; i++) { print("name: " + this.part.children (i).name); } }*/ } [KSPEvent(guiName = "Soft Landing", guiActiveEditor = true, guiActiveUnfocused = false, guiActive = false)] public void ClassicMode() { mode = 1; ModeName = "Soft Landing"; forAllSym(); } [KSPEvent(guiName = "Short Landing", guiActiveEditor = true, guiActiveUnfocused = false, guiActive = false)] public void VSL() { mode = 2; ModeName = "Short Landing"; forAllSym(); } [KSPEvent(guiName = "StayPut", guiActiveEditor = true, guiActiveUnfocused = false, guiActive = false)] public void SP() { mode = 3; ModeName = "StayPut"; forAllSym(); } [KSPEvent(guiName = "Decouple", guiActive = false, externalToEVAOnly = true, guiActiveUnfocused = true, unfocusedRange = 3.0f)] public void decoup() { this.part.decouple(2000); } /*[KSPEvent(guiName = "Escape!", guiActiveEditor = true, guiActiveUnfocused = false, guiActive = true)] public void escape() { mode = 4; ModeName = "Escape!"; forAllSym(); }*/ [KSPAction("Arm")] public void armaction(KSPActionParam param) { this.part.force_activate(); } [KSPAction("Decouple")] public void decoupleaction(KSPActionParam param) { this.part.decouple(2000); } /*[KSPAction("Abort", KSPActionGroup.Abort)] public void abort() { if (mode==4) { foreach (Part p in vessel.parts) { if (p.Modules.Contains("ModuleDecouple")) { ModuleDecouple dec=p.Modules["ModuleDecouple"] as ModuleDecouple; dec.Decouple(); } } engine.Activate(); } }*/ public void Update() { if (HighLogic.LoadedSceneIsEditor) { guifixer(); /*totalmass = 0; totalfuelmass = 0; foreach (Part p in EditorLogic.SortedShipList) { if (p.Modules.Contains("Landertron") && p.inverseStage == this.part.inverseStage) { ltron = p.Modules["Landertron"] as Landertron; if (ltron.mode == mode) { totalfuelmass = totalfuelmass+p.GetResourceMass(); } } totalmass = totalmass+p.GetResourceMass()+p.mass; } //print("fuel: " + totalfuelmass); //print("ln: " + Mathf.Log(totalmass / (totalmass - totalfuelmass))); deltaV = engine.atmosphereCurve.Evaluate(1) * 9.81f * Mathf.Log(totalmass / (totalmass - totalfuelmass));*/ } } public override void OnActive() { lcount = 0; foreach (Part p in vessel.parts) { if (p.Modules.Contains("Landertron") && p.inverseStage==this.part.inverseStage && p.GetResourceMass()>0) { ltron=p.Modules["Landertron"] as Landertron; if (ltron.mode == mode) { lcount = lcount + 1; } } } //partanglethrust = Vector3d.Dot(this.part.transform.up.normalized, this.vessel.transform.up.normalized); animdeployed = true; } public override void OnUpdate() { guifixer(); if (justrefueled && this.vessel == FlightGlobals.ActiveVessel) { //if (globaljustrefueled) //{ // Staging.AddStageAt(0); // globaljustrefueled = false; //} //int c = 0; //int stg = Staging.CurrentStage; //if (stg == c) //{ Staging.AddStageAt(0); } //this.part.stackIcon.SetIconColor(XKCDColors.White); Status = "Idle"; this.part.deactivate(); //print("deact"); this.part.inverseStage = 0; //Staging.AddStageAt(Staging.CurrentStage+1); //Staging.AddStageAt(Staging.CurrentStage + 1); //print("stage: " + Staging.CurrentStage); //Staging.RecalculateVesselStaging(this.vessel); justrefueled = false; } if (refuelable) { Refuel(); } foreach (AnimationState anim in animStates) { if (animdeployed && anim.normalizedTime < 1) { anim.speed = 1; } if (animdeployed && anim.normalizedTime >= 1) { anim.speed = 0; anim.normalizedTime = 1; } if (!animdeployed && anim.normalizedTime > 0) { anim.speed = -1; } if (!animdeployed && anim.normalizedTime <= 0) { anim.speed = 0; anim.normalizedTime = 0; } } } public override void OnFixedUpdate() { //if (engine.maxThrust != 0 && engine.maxThrust != thrust) //{ thrust = engine.maxThrust; } m = this.vessel.GetTotalMass(); v = this.vessel.verticalSpeed; //gee = FlightGlobals.getGeeForceAtPosition(this.vessel.mainBody.position).magnitude; pos = this.vessel.findWorldCenterOfMass(); up = (pos - this.vessel.mainBody.position).normalized; vesselanglethrust = Vector3d.Dot(this.vessel.transform.up.normalized, up); Vector3 thrustp = Vector3d.zero; foreach (var t in engine.thrustTransforms) { thrustp -= t.forward / engine.thrustTransforms.Count; } //--TheDog: 03.05.2015: FIXED: KSP 1.0.2 has no more GameScenes.SPH-- Vector3 fwd = HighLogic.LoadedScene == GameScenes.EDITOR ? Vector3d.up : (Vector3d)engine.part.vessel.GetTransform().up; partanglethrust = Vector3.Dot(fwd, thrustp); acc = this.vessel.acceleration; vaccel = Vector3d.Dot(acc, up); totalthrust = engine.maxThrust * partanglethrust * vesselanglethrust * lcount * (engine.thrustPercentage / 100); //print(totalthrust); totalfuelmass = lcount * (float)sf.amount * 0.0075f; //this.part.GetResourceMass(); //--TheDog: 03.05.2015: FIXED: KSP 1.0.2 has no more staticPressure-- //isp = engine.atmosphereCurve.Evaluate((float)this.vessel.staticPressure); isp = engine.atmosphereCurve.Evaluate((float)this.vessel.mainBody.GetPressure(this.height())); deltaV = isp * 9.81f * Mathf.Log(this.vessel.GetTotalMass() / (this.vessel.GetTotalMass() - totalfuelmass)) * partanglethrust; //burntime = this.part.GetResourceMass() / (engine.maxThrust / isp); burntime = (float)sf.amount *0.0075f / (engine.maxThrust*(engine.thrustPercentage/100) / (isp*9.81f)); elec_dem = electricrate * TimeWarp.fixedDeltaTime; elec_rec = elec_dem; if (sf.amount > 0.1) { elec_rec = this.part.RequestResource("ElectricCharge", elec_dem); } modeconfig(); if (elec_rec < elec_dem) { this.part.stackIcon.SetIconColor(XKCDColors.BrightYellow); Status = "No Power"; } else if (sf.amount == 0 && engine.getIgnitionState) { engine.allowShutdown = true; engine.Shutdown(); engine.allowShutdown = false; this.part.stackIcon.SetIconColor(XKCDColors.White); Status = "Idle"; this.part.deactivate(); } else if (end) { if (boom) { this.part.explode(); } else { //print("venting " + sf.amount + " fuel"); sf.amount = 0; } firing = false; } else if (fire) { Status = "Firing!"; engine.Activate(); firing = true; this.part.stackIcon.SetIconColor(XKCDColors.RadioactiveGreen); } else if (arm) { if (engine.getIgnitionState) { engine.allowShutdown = true; engine.Shutdown(); engine.allowShutdown = false; } if (sf.amount > 0) { if (warning) { this.part.stackIcon.SetIconColor(XKCDColors.Red); Status = "Warning! Too Fast!"; } else { this.part.stackIcon.SetIconColor(XKCDColors.LightCyan); Status = "Armed"; } } else { this.part.stackIcon.SetIconColor(XKCDColors.White); Status = "Idle"; this.part.deactivate(); } } prevland = this.vessel.Landed; } protected void modeconfig() { switch (mode) { case 1: //Classic warning = -v - endspeed > deltaV * vesselanglethrust; if (vesselanglethrust < 0.2) { dmin = 0; } //else if (warning) //{ //double realend = v + deltaV * vesselanglethrust; //dmin = -1* (realend * realend - v * v) / (2 * (totalthrust / m + vaccel)); //dmin = -(v * burntime + 0.5 * (totalthrust / m + vaccel) * burntime * burntime); //dmin = -v * burntime; //} else if (v + (totalthrust / m + vaccel) * burntime > -endspeed) { dmin = -1 * (endspeed * endspeed - v * v) / (2 * (totalthrust * 0.90 / m + vaccel)); } else { dmin = -(v * burntime + 0.5 * (totalthrust / m + vaccel) * burntime * burntime); } //double dfullburn = -(v + Math.Max(v + (totalthrust / m + vaccel) * burntime,0)) * burntime / 2; //double dfullburn = -(v * burntime + Math.Max(0.5 * (totalthrust / m + vaccel) * burntime * burntime,0)); if (!firing) { backgroundaccel = vaccel; } dfinal = dmin; //* heightmultiplier + offset; //dfinal = Math.Min(dmin, dfullburn); displayd = (float)dfinal; arm = !firing; float h = height(); fire = h < dfinal && v < -1 && !this.vessel.Landed && sf.amount > 0;// && (h/v)<burntime; //end = (h < endheight || v > -1 * endspeed || sf.amount == 0) && firing; if (!firing) { //print("w: " + warning + " dmin: " + dmin + " vf: " + (v + (totalthrust / m + vaccel) * burntime)); } end = (h < 0.1 || v > -1 * endspeed || sf.amount == 0) && firing; double areq = endspeed * endspeed -v * v / (2 * -1 * h) - backgroundaccel; double adiff = areq - vaccel; //float throt=areq * m / totalthrust; if (firing) { engine.throttleLocked = false; engine.useEngineResponseTime = true; engine.engineAccelerationSpeed = 0.0f; engine.engineDecelerationSpeed = 0.0f; //engine.currentThrottle = Mathf.Min((float)(areq * m / totalthrust), 0); //engine.currentThrottle = Mathf.Clamp(engine.currentThrottle + (float)(adiff * m / (vesselanglethrust * partanglethrust * engine.maxThrust)), 0, 1); //engine.currentThrottle = Mathf.Clamp(engine.currentThrottle + (float)(adiff * m / totalthrust), 0, 1); engine.currentThrottle = Mathf.Clamp((float)(areq * m *(engine.thrustPercentage/100) / totalthrust), 0, 1); //print(engine.requestedThrust); //print("areq: " + areq + " adiff: " + adiff); //print("v: " + v + " h: " + h + " rthrot: " + (areq * m / totalthrust)); //print("Fuel: "+sf.amount+" v: " +v); //engine.throttleLocked = true; } break; case 2: //Space Plane double vh = this.vessel.srf_velocity.magnitude; arm = !firing; fire = this.vessel.Landed && !prevland && sf.amount > 0; end = (vh < endspeed || vh_prev<vh ||sf.amount <= 0) && firing; warning = vh > -deltaV; //if (firing) //{ print("vh: " + vh); } vh_prev = vh; break; case 3: //StayPut double staydir = vesselanglethrust;// Vector3d.Dot(this.part.transform.up.normalized, up); arm = !firing; fire = this.vessel.Landed && sf.amount > 0; //&& v > 0.1 end = (staydir<0.1 || sf.amount < 0.1) && firing; warning = false; break; default: break; } } protected float height() { float dsea = (float)FlightGlobals.getAltitudeAtPos(pos); float d = dsea; if (Physics.Raycast(pos, -up, out craft, dsea + 10000f, 1 << 15)) { d = Mathf.Min(dsea, craft.distance); } //else { d = dsea; } float surfheight = dsea - d; float lowestd = d; foreach (Part p in vessel.parts) { if (p.collider != null) //Makes sure the part actually has a collider to touch ground { Vector3 bottom = p.collider.ClosestPointOnBounds(vessel.mainBody.position); //Gets the bottom point float partAlt = FlightGlobals.getAltitudeAtPos(bottom) - surfheight; //Gets the looped part alt lowestd = Mathf.Max(0, Mathf.Min(lowestd, partAlt)); //Stores the smallest value in all the parts } } d = lowestd; return d; } protected void forAllSym() { foreach (Part p in this.part.symmetryCounterparts) { ltron = p.Modules["Landertron"] as Landertron; ltron.mode = mode; ltron.ModeName = ModeName; } } protected void guifixer() { //engine.Events["Activate Engine"].guiActive = false; //engine.Actions["toggle"].active = false; if (!showgui) { ltron = this.part.Modules["Landertron"] as Landertron; Fields["endspeed"].guiActive = false; Fields["endspeed"].guiActiveEditor = false; Events["ClassicMode"].guiActiveEditor = false; Events["Decouple"].guiActiveUnfocused = false; Events["VSL"].guiActiveEditor = false; Events["SP"].guiActiveEditor = false; Fields["ModeName"].guiActive = false; Fields["ModeName"].guiActiveEditor = false; Fields["Status"].guiActive = false; Fields["displayd"].guiActive = false; } else if (mode == 1 || mode==2) { //Fields["heightmultiplier"].guiActive = true; //Fields["heightmultiplier"].guiActiveEditor = true; //Fields["offset"].guiActive = true; //Fields["offset"].guiActiveEditor = true; Fields["endspeed"].guiActive = true; Fields["endspeed"].guiActiveEditor = true; } else { //Fields["heightmultiplier"].guiActive = false; //Fields["heightmultiplier"].guiActiveEditor = false; //Fields["offset"].guiActive = false; //Fields["offset"].guiActiveEditor = false; Fields["endspeed"].guiActive = false; Fields["endspeed"].guiActiveEditor = false; } } public static AnimationState[] SetUpAnimation(string animationName, Part part) //Thanks Majiir! { var states = new List<AnimationState>(); foreach (var animation in part.FindModelAnimators(animationName)) { var animationState = animation[animationName]; animationState.speed = 0; animationState.enabled = true; animationState.wrapMode = WrapMode.ClampForever; animation.Blend(animationName); states.Add(animationState); } return states.ToArray(); } } Now my landertrons are firing as expected. I can also send you the updated file (source and dll), if you want. Cheers, TheDog
  6. Each time this "out of bounds" exceptions comes up, see in the output window which was the last texture it attempted to convert. Then just add this to the exception list, and re-run. Takes some time and patience, as you can see from my exception listing above...
  7. I had trouble converting a couple of textures from mods, mostly normal maps, I guess. Hence I am currently using these additional exceptions: StageRecovery UmbraSpaceIndustries\Kolonization\Assets\AgModule_NORM_NRM.png UmbraSpaceIndustries\Kolonization\Assets\CamSat_NRM.png UmbraSpaceIndustries\Kolonization\Assets\GenericModule_NORM_NRM.png UmbraSpaceIndustries\Kolonization\Assets\Inflatables_01_NORM_NRM.png UmbraSpaceIndustries\Kolonization\Assets\Inflatables_NORM_NRM.png UmbraSpaceIndustries\Kolonization\Assets\LogHub_NORM_NRM.png UmbraSpaceIndustries\Kolonization\Assets\MiscParts_norm_NRM.png UmbraSpaceIndustries\Kolonization\Assets\ModuleBase_NORM_NRM.png UmbraSpaceIndustries\Kolonization\Assets\OKSLogDecal_NORM_NRM.png UmbraSpaceIndustries\Kolonization\Assets\PancakeTub_NORM_NRM.png UmbraSpaceIndustries\Kolonization\Assets\Shared_NRM.png UmbraSpaceIndustries\Kolonization\Assets\StationParts_NORM_NRM.png UmbraSpaceIndustries\Kolonization\Assets\Tank_N_NRM.png UmbraSpaceIndustries\Kolonization\Assets\TubeParts_NORM_NRM.png UmbraSpaceIndustries\Kolonization\Assets\TUBS_NORM_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_Jet_PropFan_01 UmbraSpaceIndustries\Karbonite\Parts\KA_Tank_250_01\karbonite-25_n_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_Tank_125_04\karbonite-125-n_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_RadiaLeg\KaLeg_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_ParticleCollector_250_01\RamScoopBladeN_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_ParticleCollector_250_01\RamScoopMainN_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_Jet_Stack_01\Ka-Engines_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_Generator_250_01\KarGenny_norm_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_Drill_Radial_01\drill-radial-large-n_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_Drill_125_01\drill-25-n_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_Distiller_01\Normal_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_DetectionArray_01\Karbonite_Antenna_norm_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_Converter_250_01\converter-25-n_NRM.png UmbraSpaceIndustries\Karbonite\Parts\KA_Converter_125_02\converter-125-n_NRM.png UmbraSpaceIndustries\Karbonite\Assets\Karb625_NRM.png UmbraSpaceIndustries\Karbonite\Assets\RATNozzle_NRM.png UmbraSpaceIndustries\FTT\Assets\Blank_GLOW.png UmbraSpaceIndustries\FTT\Assets\CargoDecal_N_NRM.png UmbraSpaceIndustries\FTT\Assets\HoneyBadger_N_NRM.png- MechJeb2\Parts\MechJeb2_Pod\model001.png
  8. Love these parts! QuickFix to get this to work with KSP 1.0/1.0.1: change in most part cfgs the "Node stack bottom" to be -1 at the fifth position, like this: node_stack_bottom = 0 , 0.01 , 0 , 0 , -1 , 0 , 0 Then the parts properly stack in the VAB.
  9. If someone needs t get this working (for loading existing craft using these): I made the current version work with KSP 1.0/1.0.1 by editing the parts cfg files like this: SerCom1m.cfg: node_stack_bottom = 0.0, -0.187, 0.0, 0.0, -1.0, 0.0, 1 SerCom2m.cfg: node_stack_bottom = 0.0, -0.187, 0.0, 0.0, -1.0, 0.0, 2 (idea found on several other mod's threads where similar problems with part attachment were noticed)
  10. I guess stock would have never got this feature if you hadn't done DDSLoader first. So - mission (improve KSP load time and memory usage) accomplished! DDSLoader - enjoy your (well deserved) retirement!
  11. OK, thanks guys, I'll try both suggestions (shipping fuel down in advance, dropping down with PE)... Btw, how can I set the thread marker to "[answered]" ?? edit: found it
  12. I see... so the consensus seems to be towards shipping fuel down to LKO. My only grip with that is, that it takes about 2 kerbin days for the tanker to arrive there and rendezvous...
  13. How can I make good/better use of my Minmus fuel station? Setup in low Minmus orbit (80km), completely self-sustaining due to refueling by a Karbonite lander, which ships fuel back up to the station. Was great fun to set it up and practice operating with it. I had anticipated it to be useful as "the" gateway for interplenetary missions. Now, my first Duna mission in en route. And what had happened? -> We started actually from low Kerbin orbit, without going to Minmus first. Why? 1. Using Mechjeb to plan the trip, both Hohmann and porkchop selection does not work in Minmus SOI (transfer calculation needs both bodies having the same "parent" body). Bummer. 2. Flying to Minmus, topping off fuel, then dropping to highly elliptical Kerbin orbit for interplanetary burn takes a long time (2days from Minmus back to PE at Kerbin) -> does not seem practical 3. Flying to Minmus, topping off fuel, then burn to get Kerbin escape trajectory, then calculate transfer via porkchop or Hohmann -> possible, but sounds risky (would you board a craft when the mission plan says "just burn to Sun orbit, then we'll see what we can do..." ???) So,how can I make my beloved Minmus fuel stop useful? Thanks for all suggestions!
  14. From a project management point-of-view: In scope for 1.0: ------------------- MUST-DO Priority: 1) Evalute known/reportd bugs and fix all critical and high priority ones. e.g.: memory leaks, functional bugs seriosly hampering gameplay, bugs with high visibility for the customer (aka player) 2) Complete features that are already work-in-progress and are alrready in an advanced stage of implemtation, and yield high visibility for the customer (enhancing gameplay) e.g.: resource integration DESIRED, BUT OPTIONAL Priority: 3) Complete features which would be save-breaking if introduced post-1.0. This includes major overhauls of aerodynamics, or drastic gameplay-altering changes to game components. Rationale: players on KSP will start their long-term saves with 1.0. Introducing save-braking changes in 1.x would be highly inadvisable. Out of scope for 1.0: ------------------- NICE-TO-HAVE Priority, can easily be shelved for 1.0: 4) All enhancements and new features that do not fall into category 2 and 3, and can be provided today already by various mods. E.g. visual enhancements, some parts, alternative tech trees, ... 5) General visual polish While indeed nice to have, it is priority 5 only. 6) Migration to new development tools/environment e.g. Unity 5, win x64 support Sorry to all fans of Unity 5, but this *is* so optional, and very harmful to delivery dates & deadlines. Consider this for KSP 1.2, earliest.
  15. on Linux it apparently is, as lots of people here confirm... maybe I have to setup dual-boot...
×
×
  • Create New...