diff --git a/GameData/ProcAirships/Parts/BallastTank.cfg b/GameData/ProcAirships/Parts/BallastTank.cfg index dd43bae..815b908 100644 --- a/GameData/ProcAirships/Parts/BallastTank.cfg +++ b/GameData/ProcAirships/Parts/BallastTank.cfg @@ -20,7 +20,7 @@ PART node_attach=0,0,0.5,0,0,-1,1 // --- editor parameters --- - cost = 4000 + cost = 300 TechRequired = start entryCost = 4000 category = Aero @@ -49,6 +49,16 @@ PART name = ProceduralPart textureSet=Stockalike shapeName=Fillet Cylinder + TECHLIMIT { + + name = start + diameterMin = 0.1 + diameterMax = Infinity + lengthMin = 0.1 + lengthMax = Infinity + volumeMin = 0.001 + volumeMax = Infinity + } } MODULE { @@ -129,9 +139,12 @@ PART MODULE { name = BuoyancyStats - } - - + MODULE + { + name=AirshipCost + costPerCubicMeter=0.1 // cost per m³ + } + } \ No newline at end of file diff --git a/GameData/ProcAirships/Parts/Envelope.cfg b/GameData/ProcAirships/Parts/Envelope.cfg index fc631ac..dc37e18 100644 --- a/GameData/ProcAirships/Parts/Envelope.cfg +++ b/GameData/ProcAirships/Parts/Envelope.cfg @@ -20,12 +20,12 @@ PART node_attach=0,0,0.5,0,0,-1,1 // --- editor parameters --- - cost = 4000 + cost = 300 TechRequired = start entryCost = 4000 category = Aero subcategory = 0 - title = Airship envelope + title = Airship Envelope manufacturer = Count Keppelins Airship manufactory description = TODO @@ -49,6 +49,16 @@ PART name = ProceduralPart textureSet=PlainWhite shapeName=Fillet Cylinder + TECHLIMIT { + + name = start + diameterMin = 0.1 + diameterMax = Infinity + lengthMin = 0.1 + lengthMax = Infinity + volumeMin = 0.001 + volumeMax = Infinity + } } MODULE { @@ -97,7 +107,7 @@ PART name = AirshipEnvelope dryMassPerQubicMeter = 0.0005 //in tonnes idealRelPressure = 0.005 // in bar - PressureTolerance = 0.05 // +- in bar + pressureTolerance = 0.05 // +- in bar } MODULE @@ -110,4 +120,10 @@ PART name=BuoyancyStats } + MODULE + { + name=AirshipCost + costPerCubicMeter=0.2 // cost per m³ + } + } \ No newline at end of file diff --git a/GameData/ProcAirships/Parts/EnvelopeCap.cfg b/GameData/ProcAirships/Parts/EnvelopeCap.cfg index 95707e8..1bc4a12 100644 --- a/GameData/ProcAirships/Parts/EnvelopeCap.cfg +++ b/GameData/ProcAirships/Parts/EnvelopeCap.cfg @@ -1,7 +1,7 @@ PART { // --- general parameters --- - name = AirshipEnvelopeCone + name = AirshipEnvelopeCap module = Part author = RadarManFromTheMoon @@ -18,12 +18,12 @@ PART node_stack_bottom=0,-0.5,0,0,-1,0,1 // --- editor parameters --- - cost = 4000 + cost = 300 TechRequired = start entryCost = 4000 category = Aero subcategory = 0 - title = Airship envelope cone + title = Airship Envelope Cap manufacturer = Count Keppelins Airship manufactory description = TODO @@ -46,6 +46,17 @@ PART { name = ProceduralPart textureSet=PlainWhite + shapeName=Smooth Cone + TECHLIMIT { + + name = start + diameterMin = 0.5 + diameterMax = Infinity + lengthMin = 0.5 + lengthMax = Infinity + volumeMin = 0.001 + volumeMax = Infinity + } } MODULE @@ -66,7 +77,7 @@ PART name = AirshipEnvelope dryMassPerQubicMeter = 0.0005 //in tonnes idealRelPressure = 0.005 // in bar - PressureTolerance = 0.05 + pressureTolerance = 0.05 // +- in bar } MODULE @@ -80,5 +91,10 @@ PART } + MODULE + { + name=AirshipCost + costPerCubicMeter=0.2 // cost per m³ + } } \ No newline at end of file diff --git a/GameData/ProcAirships/Resources/AirshipResources.cfg b/GameData/ProcAirships/Resources/AirshipResources.cfg index 50e469f..faab55f 100644 --- a/GameData/ProcAirships/Resources/AirshipResources.cfg +++ b/GameData/ProcAirships/Resources/AirshipResources.cfg @@ -48,6 +48,7 @@ LIFTING_GAS_OPTIONS molarMass = 2.01588 // grams per mol. combustible = true maxTemperature = 300 + cost = 2 } LIFTING_GAS @@ -57,6 +58,7 @@ LIFTING_GAS_OPTIONS molarMass = 4.002602 // grams per mol. combustible = false maxTemperature = 300 + cost = 2.3 } } \ No newline at end of file diff --git a/GameData/ProcAirships/airships.cfg b/GameData/ProcAirships/airships.cfg deleted file mode 100644 index ba915d0..0000000 --- a/GameData/ProcAirships/airships.cfg +++ /dev/null @@ -1,6 +0,0 @@ -PROC_AIRSHIPS_CONFIG -{ - name = default // name of the configuration - buoyancyMultiplicator = 3.0 // value the buoyancy of an envelope gets multiplied with. 1.0 is realistic - -} \ No newline at end of file diff --git a/README.md b/README.md index 44a54fb..d497d40 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ Procedural Airships =================== -ver. 0.3.0.0 - experimental +ver. 0.4.1.0 - beta This plugin adds procedural airship envelopes to Kerbal Space Program **!!!WORK IN PROGRESS!!!** -**This will most certainly be full of bugs and breaks savegames/crafts. Only use it for test purposes** +**This is a beta version. It may contain bugs** Dependencies: * swamp_ig's great ProceduralParts mod. Get it [here](http://forum.kerbalspaceprogram.com/threads/70676-0-24-2WIP-Procedural-Parts-Parts-the-way-you-want-em-0-9-18-Aug-6 "ProceduralParts mod"). diff --git a/changelog.txt b/changelog.txt index e63549b..28a4a1c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,12 @@ +Version 0.4.1.0 +-Bugfix: Fixed a major bug that prevents Procedural Airships from function properly in career mode + +Version 0.4.0.0 +-Feature: FAR compatibility +-Feature: procedural cost handling +-Feature: Parts are no longer controllable without a pod or probecore +-Feature: Center of Buoyancy marker in editor (activates with CoL marker) + Version 0.3.0.0 -Feature: envelopes containing combustrogen will explode when exposed to high temperatures -Feature: envelopes will explode when their gas pressure exceeds the tolerance diff --git a/source/ProcAirships/AirshipCost.cs b/source/ProcAirships/AirshipCost.cs new file mode 100644 index 0000000..c5e3a79 --- /dev/null +++ b/source/ProcAirships/AirshipCost.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using KSPAPIExtensions; +using KSPAPIExtensions.PartMessage; + +namespace ProcAirships +{ + public class AirshipCost : PartModule, IPartCostModifier + { + + [KSPField] + public float costPerCubicMeter = 0.0f; + + [KSPField(isPersistant=true)] + public float overallCost = 0.0f; + + private float envelopeVolume=0.0f; + + + + public override void OnAwake() + { + Log.post(this.ClassName + " OnAwake-callback: "); + + base.OnAwake(); + PartMessageService.Register(this); + Log.post(this.ClassName + "end of OnAwake-callback: "); + } + + + + // message receiving + + [PartMessageListener(typeof(PartVolumeChanged), scenes: ~GameSceneFilter.Flight)] + public void ChangeVolume(string volumeName, float volume) + { + Log.post("AirshipCost received ChangeVolume message for " + volumeName + " Volume: " + volume); + if (volumeName != PartVolumes.Tankage.ToString()) + return; + + if (volume <= 0f) + { + Log.post("volume is: " + volume.ToString() + " thats odd... setting volume to 1 instead"); + envelopeVolume = 1.0f; + } + else + { + Log.post("tank Volume Changed to " + volume, LogLevel.LOG_INFORMATION); + + envelopeVolume = volume; + } + + } + + + // interface + + public float GetModuleCost() + { + if (util.editorActive()) + { + //Log.post(this.ClassName + " getModuleCost"); + float cost = costPerCubicMeter * envelopeVolume; + + //Log.post(this.ClassName + " volume: " + envelopeVolume); + //Log.post(this.ClassName + " cost per m³: " + costPerCubicMeter); + //Log.post(this.ClassName + " volume costs: " + cost); + + foreach (PartResource resource in part.Resources) + { + cost += (float)(resource.info.unitCost * resource.amount); + } + //Log.post(this.ClassName + " cost after resource costs: " + cost); + + foreach (AirshipEnvelope e in part.Modules.OfType<AirshipEnvelope>()) + { + AirshipEnvelope.LiftingGas lg = e.getCurrentLiftingGas(); + if (lg != null) + cost += e.getCurrentLiftingGas().cost * e.LiftingGasAmount; + } + //Log.post(this.ClassName + " cost after lifting gas costs: " + cost); + + //Log.post(this.ClassName + " end of getModuleCost"); + overallCost = cost; + } + + return overallCost; + } + } +} diff --git a/source/ProcAirships/AirshipDrainResource.cs b/source/ProcAirships/AirshipDrainResource.cs index dc1b106..5ece10b 100644 --- a/source/ProcAirships/AirshipDrainResource.cs +++ b/source/ProcAirships/AirshipDrainResource.cs @@ -42,7 +42,7 @@ public class AirshipDrainResource : PartModule public void toggleDump(KSPActionParam ap) { Log.post("ACTION: toggle dumping '" + displayName + "'.", LogLevel.LOG_INFORMATION); - dumping.Toggle(); + dumping = dumping.Toggle(); } [KSPAction(guiName:"start dumping")] @@ -114,6 +114,12 @@ public float DumpRate } } + public bool isControllable + { + get { return part.isControllable && !Preferences.alwaysControllable; } + + } + #endregion //------------------------------------------------------------------------------------------------------------------------ #region Message receiving @@ -165,7 +171,7 @@ public override void OnStart(StartState state) public override void OnFixedUpdate() { - if (dumping) + if (dumping && isControllable) { float amountDumped; Log.post("dumping: " + resourceName + " at rate " + dumpRate); diff --git a/source/ProcAirships/AirshipEnvelope.cs b/source/ProcAirships/AirshipEnvelope.cs index 29d1e0c..14e6240 100644 --- a/source/ProcAirships/AirshipEnvelope.cs +++ b/source/ProcAirships/AirshipEnvelope.cs @@ -1,4 +1,25 @@ -using System; +/* + * Procedural Airships + * Copyright (C) 2014 Tobias Knappe <mindconductor@googlemail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -19,13 +40,14 @@ public class AirshipEnvelope : PartModule //[KSPField(guiActive = true, guiActiveEditor = true, guiName = "envelope net vol.", guiUnits = "m³", guiFormat = "F3")] private double envelopeVolumeNet = 0; // no save // ui as string + [KSPField(guiActive = true, guiActiveEditor = true, guiName = "envelope net. vol.")] private string envelopeVolumeNetUI; [KSPField( isPersistant=true, guiActive=true, guiActiveEditor=true, guiName="lifting gas"), UI_ChooseOption(scene = UI_Scene.Editor, controlEnabled = true)] - public string liftingGas; // type of lifting gas // KSPField peristent + public string liftingGas=""; // type of lifting gas // KSPField peristent [KSPField] @@ -98,8 +120,6 @@ public class AirshipEnvelope : PartModule [KSPField] private float pressureTolerance = 0.05f; - //[KSPField(isPersistant=true)] - //private double gasFlow = 0.5; [KSPField(isPersistant=true, guiName = "autofill", guiActive = false, guiActiveEditor = true), UI_Toggle(controlEnabled = true, enabledText = "", disabledText = "", scene = UI_Scene.Editor)] @@ -107,7 +127,7 @@ public class AirshipEnvelope : PartModule [KSPField(isPersistant=true, guiName = "pressureControl", guiActive = true, guiActiveEditor = true), UI_Toggle(controlEnabled = true, enabledText = "", disabledText = "", scene = UI_Scene.All)] - private bool pressureControl = true; // ui + private bool pressureControl = false; // ui [KSPField(guiActive = true, guiActiveEditor = false, guiName = "venting rate", guiUnits = "kg/s", guiFormat = "F4"), UI_FloatEdit(scene = UI_Scene.Flight, minValue = 0.01f, maxValue = float.PositiveInfinity, incrementLarge = 1.0f, incrementSmall = 0.1f, incrementSlide = 0.001f)] @@ -168,13 +188,19 @@ protected set } } + public bool isControllable + { + get { return part.isControllable && !Preferences.alwaysControllable; } + + } + #endregion List<LiftingGas> liftingGasOptions; - Athmosphere athmosphere; + //Athmosphere athmosphere; float damageTimer = 0.0f; @@ -234,7 +260,7 @@ public void ballonetPlusPlusPlusPlus(KSPActionParam ap) [KSPAction(guiName: "toggle venting")] public void toggleVenting(KSPActionParam ap) { - ventGas.Toggle(); + ventGas = ventGas.Toggle(); } [KSPAction(guiName: "vent gas")] @@ -297,6 +323,24 @@ public void ventingRatePlusPlusPlusPlus(KSPActionParam ap) ventingRate += 1.0f; } + [KSPAction(guiName: "PControl On")] + public void PControlOn(KSPActionParam ap) + { + pressureControl = true; + } + + [KSPAction(guiName: "PControl Off")] + public void PControlOff(KSPActionParam ap) + { + pressureControl = false; + } + + [KSPAction(guiName: " toggle PControl")] + public void PControlToggle(KSPActionParam ap) + { + pressureControl = pressureControl.Toggle(); + } + #endregion //---------------------------------------------------------------------------------------------- @@ -307,13 +351,8 @@ public override void OnAwake() Log.post(this.ClassName + " OnAwake-callback: "); base.OnAwake(); - PartMessageService.Register(this); - } - - public override void OnStart(StartState state) - { - Log.post(this.ClassName + " OnStart-callback: " + state.ToString()); - + PartMessageService.Register(this); + loadLiftingGasOptions(); // check liftingGas validity. If invalid: set to default @@ -322,17 +361,21 @@ public override void OnStart(StartState state) Log.post("no valid lifting gas selected. Set to default", LogLevel.LOG_WARNING); if (liftingGasOptions.Count > 0) { - liftingGas = liftingGasOptions.First <LiftingGas>().displayName; + liftingGas = liftingGasOptions.First<LiftingGas>().displayName; Log.post("liftinggas set to: " + liftingGas, LogLevel.LOG_INFORMATION); } else Log.post("no valid lifting gas option found.", LogLevel.LOG_ERROR); - } - + + } + + public override void OnStart(StartState state) + { + Log.post(this.ClassName + " OnStart-callback: " + state.ToString()); + setupUI(); - athmosphere = Factory.getAthmosphere(); if (!util.editorActive()) { @@ -352,6 +395,8 @@ void Update() if (HighLogic.LoadedScene == GameScenes.EDITOR || HighLogic.LoadedScene == GameScenes.SPH) updateEnvelope(); + + //Log.post("world position: " + part.rigidbody.worldCenterOfMass.ToString()); } public override void OnFixedUpdate() @@ -364,7 +409,7 @@ public void LateUpdate() { updateFlag = false; - if (pressureControl && !util.editorActive()) + if (pressureControl && !util.editorActive() && isControllable) { if (relativePressure > idealRelPressure) { @@ -434,12 +479,17 @@ double getGasAmount(double pressure) // returns the gas amount thats needed to a public LiftingGas getCurrentLiftingGas() { + if (liftingGas == "") return null; return liftingGasOptions.First<LiftingGas>(x => x.displayName == liftingGas); } public double requestBallonetAir(double amount) { + + if (!util.editorActive() && !isControllable) + return 0; + float inflationRate = util.editorActive() ? ballonetInflationRateEditor : ballonetInflationRate; inflationRate *= envelopeVolume; @@ -493,12 +543,17 @@ private void updateVolume() double volumeDelta = (ballonetTargetInflation - ballonetInflation) * ballonetVolumeMax / 100.0d; - if (volumeDelta > 0.01) - ballonetStatus = "inflating"; - else if (volumeDelta < -0.01) - ballonetStatus = "deflating"; + if (isControllable) + { + if (volumeDelta > 0.01) + ballonetStatus = "inflating"; + else if (volumeDelta < -0.01) + ballonetStatus = "deflating"; + else + ballonetStatus = "idle"; + } else - ballonetStatus = "idle"; + ballonetStatus = "--no signal--"; ballonetVolume += requestBallonetAir(volumeDelta); ballonetVolumeUI = ballonetVolume.ToStringExt("F3") + "m³"; @@ -522,8 +577,11 @@ private void updatePressureDamage() float randomNumber = UnityEngine.Random.Range(0.0f, pressureTolerance); if (randomNumber < overpressure) { - part.explode(); - FlightLogger.eventLog.Add("envelope destroyed due to too high or low pressure"); + if (Preferences.pressureDestruction) + { + part.explode(); + FlightLogger.eventLog.Add("envelope destroyed due to too high or low pressure"); + } } } @@ -548,6 +606,7 @@ private void updateEnvelope() double connectedGas = 0.0; double connectedTemperature = 0.0; + foreach(AirshipEnvelope envelope in connectedEnvelopes) { envelope.updateVolume(); @@ -576,7 +635,8 @@ private void updateEnvelope() temperature = (float)getTemperature(); //absolutePressure = (float)getAbsolutePressure(); - relativePressure = (float)(absolutePressure - athmosphere.getAirPressure()); + //relativePressure = (float)(absolutePressure - athmosphere.getAirPressure()); + relativePressure = (float)(absolutePressure - Athmosphere.fetch().getAirPressure(part.rigidbody.worldCenterOfMass)); pStatus = (relativePressure-idealRelPressure).Clamp(-pressureTolerance, pressureTolerance); @@ -585,7 +645,7 @@ private void updateEnvelope() if (autofill && util.editorActive()) autoFill(); - if(ventGas) + if(ventGas && isControllable) { LiftingGasAmount -= ventingRate * TimeWarp.fixedDeltaTime; } @@ -593,11 +653,13 @@ private void updateEnvelope() if (!util.editorActive()) updatePressureDamage(); + } void autoFill() { - liftingGasAmount = (float)getGasAmount(athmosphere.getAirPressure() + idealRelPressure); + //liftingGasAmount = (float)getGasAmount(athmosphere.getAirPressure() + idealRelPressure); + liftingGasAmount = (float)getGasAmount(Athmosphere.fetch().getAirPressure(part.rigidbody.worldCenterOfMass) + idealRelPressure); } @@ -608,22 +670,38 @@ void autoFill() [PartMessageListener(typeof(PartVolumeChanged), scenes: ~GameSceneFilter.Flight)] public void ChangeVolume(string volumeName, float volume) { + if(float.IsInfinity(volume) || float.IsNaN(volume)) + { + Log.post("received Volume change message, but volume is not a valid number", LogLevel.LOG_ERROR); + return; + } + Log.post("received ChangeVolume message for " + volumeName + " Volume: " + volume); if (volumeName != PartVolumes.Tankage.ToString()) return; if (volume <= 0f) - throw new ArgumentOutOfRangeException("volume"); - Log.post("tank Volume Changed to " + volume, LogLevel.LOG_INFORMATION); + { + Log.post("volume is: " + volume.ToString() + " thats odd... setting volume to 1 instead"); + envelopeVolume = 1.0f; + } + else + { + Log.post("tank Volume Changed to " + volume, LogLevel.LOG_INFORMATION); + + envelopeVolume = volume; + } + - envelopeVolume = volume; } + /* [PartMessageListener(typeof(PartResourceInitialAmountChanged), scenes: GameSceneFilter.Flight)] public void ChangeInitResource(PartResource resource, double amount) { Log.post("Envelope changed init resource " + resource.resourceName + " to " + amount); } + */ @@ -714,6 +792,44 @@ private void setupUI() } } + + field = Fields["envelopeVolume"]; + if (field != null) + { + field.guiActive = Preferences.showVolumeInfoInFlight; + field.guiActiveEditor = Preferences.showVolumeInfoInEditor; + } + + field = Fields["envelopeVolumeNetUI"]; + if (field != null) + { + field.guiActive = Preferences.showVolumeInfoInFlight; + field.guiActiveEditor = Preferences.showVolumeInfoInEditor; + } + + field = Fields["ballonetVolumeMax"]; + if (field != null) + { + field.guiActive = Preferences.showVolumeInfoInFlight; + field.guiActiveEditor = Preferences.showVolumeInfoInEditor; + } + + field = Fields["temperature"]; + if (field != null) + { + field.guiActive = Preferences.showTemperatureInFlight; + field.guiActiveEditor = Preferences.showTemperatureInEditor; + } + + field = Fields["absolutePressure"]; + if (field != null) + { + field.guiActive = Preferences.showAbsPressureInFlight; + field.guiActiveEditor = Preferences.showAbsPressureInEditor; + } + + + } @@ -742,6 +858,9 @@ public class LiftingGas : IConfigNode [SerializeField] public float maxTemperature; + [SerializeField] + public float cost; + public void Load(ConfigNode node) { //ConfigNode.LoadObjectFromConfig(this, node); @@ -766,6 +885,9 @@ public void Load(ConfigNode node) maxTemperature = 0.0f; } + if (!node.TryGetValue("cost", out cost)) + Log.post("Could not read cost from ConfigNode", LogLevel.LOG_ERROR); + } public void Save(ConfigNode node) { @@ -774,9 +896,10 @@ public void Save(ConfigNode node) node.SetValue("displayName", displayName); node.SetValue("resourceName", resourceName); node.SetValue("molarMass", molarMass.ToString()); + node.SetValue("cost", cost.ToString()); } } - + } // class } diff --git a/source/ProcAirships/Athmosphere.cs b/source/ProcAirships/Athmosphere.cs index 436c324..e90e996 100644 --- a/source/ProcAirships/Athmosphere.cs +++ b/source/ProcAirships/Athmosphere.cs @@ -9,9 +9,180 @@ namespace ProcAirships { - abstract public class Athmosphere + public class Athmosphere { - public abstract double getAirDensity(); - public abstract double getAirPressure(); + + public double getAirDensity(double altitude) + { + updateBody(); + try + { + return currentModel.getAirDensity(altitude, currentBody); + } + catch (Exception e) + { + Log.postException(e); + return 0; + } + } + + public double getAirDensity(Vector3 worldPosition) + { + updateBody(); + double density = 0; + try + { + + if (util.editorActive()) + { + + if (util.vabActive()) + { + density = currentModel.getAirDensity(worldPosition.y + vabAltitude, currentBody); + //Log.post(worldPosition.y + vabAltitude); + } + else + { + density = currentModel.getAirDensity(worldPosition.y + sphAltitude, currentBody); + //Log.post(worldPosition.y + sphAltitude); + } + } + else + density = currentModel.getAirDensity(worldPosition, currentBody); + + } + catch(Exception e) + { + Log.postException(e); + } + //Log.post(density); + return density; + + } + + public double getAirPressure(double altitude) + { + updateBody(); + try + { + return currentModel.getAirPressure(altitude, currentBody); + } + catch (Exception e) + { + Log.postException(e); + return 0; + } + } + + public double getAirPressure(Vector3 worldPosition) + { + updateBody(); + + try + { + + if (util.editorActive()) + { + if (util.vabActive()) + return currentModel.getAirPressure(worldPosition.y + vabAltitude, currentBody); + else + return currentModel.getAirPressure(worldPosition.y + sphAltitude, currentBody); + } + else + return currentModel.getAirPressure(worldPosition, currentBody); + + } + catch (Exception e) + { + Log.postException(e); + return 0; + } + + } + + private Athmosphere() + { + if (currentModel == null) + { + + bool isFARLoaded = AssemblyLoader.loadedAssemblies.Any(a => a.assembly.GetName().Name == "FerramAerospaceResearch"); + + //isFARLoaded = false; + + if (isFARLoaded) + { + + Log.post("FAR detected", LogLevel.LOG_INFORMATION); + + AssemblyLoader.LoadedAssembly FAR = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.assembly.GetName().Name == "FerramAerospaceResearch"); + Log.post("FAR Version: " + FAR.assembly.GetName().Version.ToString(), LogLevel.LOG_INFORMATION); + + currentModel = new AthmosphereModelFAR(); + if (!currentModel.init()) + fallBackToStock(); + } + else + { + Log.post("No FAR detected...", LogLevel.LOG_INFORMATION); + + fallBackToStock(); + } + } + + } + + private void fallBackToStock() + { + Log.post("Falling back to stock athmosphere model.", LogLevel.LOG_INFORMATION); + currentModel = new AthmosphereModelStock(); + if (!currentModel.init()) + Log.post("Could not init stock athmosphere model", LogLevel.LOG_ERROR); + } + + private void updateBody() + { + + if(util.editorActive()) + { + if (forceBody != null) + currentBody = forceBody; + else + currentBody = FlightGlobals.Bodies[1]; + } + else + { + currentBody = FlightGlobals.currentMainBody; + } + + if(currentBody != lastBody) + { + lastBody = currentBody; + Log.post("current Body changed to: " + currentBody.bodyName); + } + + + } + + public static Athmosphere fetch() + { + if(instance == null) + { + instance = new Athmosphere(); + instance.updateBody(); + } + + return instance; + } + + private static Athmosphere instance = null; + + public const double vabAltitude = 72.0; + public const double sphAltitude = 69.0; + + private IAthmosphereModel currentModel = null; + private CelestialBody currentBody = null; + private CelestialBody lastBody = null; + private CelestialBody forceBody = null; + } } diff --git a/source/ProcAirships/AthmosphereFAR.cs b/source/ProcAirships/AthmosphereFAR.cs deleted file mode 100644 index d197906..0000000 --- a/source/ProcAirships/AthmosphereFAR.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -//using System.Threading.Tasks; - -namespace ProcAirships -{ - public class AthmosphereFAR : Athmosphere - { - - public override double getAirDensity() - { - try - { - return ferram4.FARAPI.GetActiveControlSys_AirDensity(); - } - catch (Exception e) - { - Log.postException(e); - return 0; - } - }// getAirDensity - - public override double getAirPressure() - { - return 0.0d; // not yet implemented - } - - } // class - -} // namespace diff --git a/source/ProcAirships/AthmosphereFAREditor.cs b/source/ProcAirships/AthmosphereFAREditor.cs new file mode 100644 index 0000000..6c6a7e4 --- /dev/null +++ b/source/ProcAirships/AthmosphereFAREditor.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace ProcAirships +{ + public class AthmosphereFAREditor : Athmosphere + { + public override double getAirDensity() + { + + double density = 0; + try + { + if (HighLogic.LoadedScene == GameScenes.EDITOR) + density = ferram4.FARAeroUtil.GetCurrentDensity(FlightGlobals.Bodies[1], 72.5); + else + density = ferram4.FARAeroUtil.GetCurrentDensity(FlightGlobals.Bodies[1], 69.0); + } + catch (Exception e) + { + Log.postException(e); + return 0; + } + + return density; + }// getAirDensity + + public override double getAirPressure() + { + double pressure = 0.0; + float altitude; + + if (HighLogic.LoadedScene == GameScenes.EDITOR) + altitude = 72.5f; + else + altitude = 69.0f; + + + try + { + ferram4.FARAeroUtil.UpdateCurrentActiveBody(FlightGlobals.Bodies[1]); + + double temp = Math.Max(0.1, ferram4.FARAeroUtil.currentBodyTemp + FlightGlobals.getExternalTemperature(altitude, FlightGlobals.Bodies[1])); + + pressure = FlightGlobals.getStaticPressure(altitude, FlightGlobals.Bodies[1]); + if (pressure > 0) + pressure = (pressure - ferram4.FARAeroUtil.currentBodyAtmPressureOffset); + } + catch (Exception e) + { + Log.postException(e); + return 0; + } + + return pressure; + } + + + public override double getAirDensity(CelestialBody body, Vector3 worldLocation) + { + /* + double density = 0.0; + try + { + density = ferram4.FARAeroUtil.GetCurrentDensity(body, worldLocation); + } + catch (Exception e) + { + Log.postException(e); + return 0; + } + + return density; + */ + return getAirDensity(); + + } + + public override double getAirPressure(CelestialBody body, Vector3 worldLocation) + { + /* + double pressure = 0.0; + try + { + ferram4.FARAeroUtil.UpdateCurrentActiveBody(body); + + double temp = Math.Max(0.1, ferram4.FARAeroUtil.currentBodyTemp + FlightGlobals.getExternalTemperature(worldLocation)); + + pressure = FlightGlobals.getStaticPressure(worldLocation, body); + if (pressure > 0) + pressure = (pressure - ferram4.FARAeroUtil.currentBodyAtmPressureOffset); //Need to convert atm to Pa + } + catch (Exception e) + { + Log.postException(e); + return 0; + } + + return pressure; + */ + return getAirPressure(); + + } + + } +} diff --git a/source/ProcAirships/AthmosphereModelFAR.cs b/source/ProcAirships/AthmosphereModelFAR.cs new file mode 100644 index 0000000..aeff8ec --- /dev/null +++ b/source/ProcAirships/AthmosphereModelFAR.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Reflection; +using UnityEngine; + +namespace ProcAirships +{ + class AthmosphereModelFAR : IAthmosphereModel + { + private delegate double getAirDensityAltFunc(CelestialBody body, double altitude); + private delegate double getAirDensityPosFunc(CelestialBody body, Vector3 worldPosition); + //private delegate void updateCurrentActivelBodyFunc(CelestialBody body); + + private getAirDensityAltFunc getAirDensityAlt; + private getAirDensityPosFunc getAirDensityPos; + //private updateCurrentActivelBodyFunc updateCurrentActiveBody; + + + + private Type aeroUtilType; + + public bool init() + { + if (!AssemblyLoader.loadedAssemblies.Any(a => a.assembly.GetName().Name == "FerramAerospaceResearch")) + return false; + + AssemblyLoader.LoadedAssembly far = AssemblyLoader.loadedAssemblies.First(a => a.assembly.GetName().Name == "FerramAerospaceResearch"); + + /* + foreach(Type t in far.assembly.GetExportedTypes()) + { + Log.post("--exported Type from FAR--"); + Log.post("name: " + t.Name); + Log.post("full name: " + t.FullName); + Log.post("is Class: " + t.IsClass); + Log.post("---------------------------"); + } + */ + + aeroUtilType = far.assembly.GetExportedTypes().First(x => x.Name == "FARAeroUtil"); + + if (aeroUtilType == null) + { + Log.post("could not find class FARAeroUtil"); + return false; + } + + // init delegates + try + { + + getAirDensityAlt = (getAirDensityAltFunc)Delegate.CreateDelegate(typeof(getAirDensityAltFunc), null, + aeroUtilType.GetMethod("GetCurrentDensity", new Type[] { typeof(CelestialBody), typeof(double) })); + + getAirDensityPos = (getAirDensityPosFunc)Delegate.CreateDelegate(typeof(getAirDensityPosFunc), null, + aeroUtilType.GetMethod("GetCurrentDensity", new Type[] { typeof(CelestialBody), typeof(Vector3) })); + + //updateCurrentActiveBody = (updateCurrentActivelBodyFunc)Delegate.CreateDelegate(typeof(updateCurrentActivelBodyFunc), null, + // aeroUtilType.GetMethod("UpdateCurrentActiveBody", new Type[] { typeof(CelestialBody)})); + + + + + } + catch (Exception e) + { + Log.postException("error initializing FAR athmosphere model", e); + return false; + } + + return true; + } + + + public double getAirDensity(double altitude, CelestialBody body) + { + //return ferram4.FARAeroUtil.GetCurrentDensity(body, altitude); + + return getAirDensityAlt(body, altitude); + } + + public double getAirDensity(UnityEngine.Vector3 worldPosition, CelestialBody body) + { + + //return getAirDensityPos(body, worldPosition); + // FAR uses a bugged function so this is the workaround until its fixed + return getAirDensity(FlightGlobals.getAltitudeAtPos(worldPosition, body), body); + } + + // FAR does not seem to have a function for this so I copied this out of it's AeroUtil class + public double getAirPressure(double altitude, CelestialBody body) + { + /* + //ferram4.FARAeroUtil.UpdateCurrentActiveBody(body); + updateCurrentActiveBody(body); + + if (altitude > body.maxAtmosphereAltitude) + return 0; + + //double temp = Math.Max(0.1, ferram4.FARAeroUtil.currentBodyTemp + FlightGlobals.getExternalTemperature((float)altitude, body)); + double currentBodyAtmPressureOffset = (double)aeroUtilType.GetField("currentBodyAtmPressureOffset").GetValue(null); + + + double pressure = FlightGlobals.getStaticPressure(altitude, body); + if (pressure > 0) + //pressure = (pressure - ferram4.FARAeroUtil.currentBodyAtmPressureOffset); + pressure = (pressure - currentBodyAtmPressureOffset); + + return pressure; + * + */ + + return FlightGlobals.getStaticPressure(altitude, body); + } + + // FAR does not seem to have a function for this so I copied this out of it's AeroUtil class + public double getAirPressure(UnityEngine.Vector3 worldPosition, CelestialBody body) + { + /* + //ferram4.FARAeroUtil.UpdateCurrentActiveBody(body); + updateCurrentActiveBody(body); + + //double temp = Math.Max(0.1, ferram4.FARAeroUtil.currentBodyTemp + FlightGlobals.getExternalTemperature(worldPosition)); + + double currentBodyAtmPressureOffset = (double)aeroUtilType.GetField("currentBodyAtmPressureOffset").GetValue(null); + + + double pressure = FlightGlobals.getStaticPressure(worldPosition, body); + if (pressure > 0) + //pressure = (pressure - ferram4.FARAeroUtil.currentBodyAtmPressureOffset); + pressure = (pressure - currentBodyAtmPressureOffset); + + return pressure; + */ + return FlightGlobals.getStaticPressure(worldPosition, body); + } + + + } +} diff --git a/source/ProcAirships/AthmosphereModelStock.cs b/source/ProcAirships/AthmosphereModelStock.cs new file mode 100644 index 0000000..b761540 --- /dev/null +++ b/source/ProcAirships/AthmosphereModelStock.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ProcAirships +{ + class AthmosphereModelStock : IAthmosphereModel + { + + public bool init() + { + return true; + } + + public double getAirDensity(double altitude, CelestialBody body) + { + return FlightGlobals.getAtmDensity(getAirPressure(altitude, body)); + } + + public double getAirDensity(UnityEngine.Vector3 worldPosition, CelestialBody body) + { + return FlightGlobals.getAtmDensity(getAirPressure(worldPosition, body)); + } + + public double getAirPressure(double altitude, CelestialBody body) + { + return FlightGlobals.getStaticPressure(altitude, body); + } + + public double getAirPressure(UnityEngine.Vector3 worldPosition, CelestialBody body) + { + return FlightGlobals.getStaticPressure(worldPosition, body); + } + } +} diff --git a/source/ProcAirships/AthmosphereStock.cs b/source/ProcAirships/AthmosphereStock.cs deleted file mode 100644 index 55fb9d3..0000000 --- a/source/ProcAirships/AthmosphereStock.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using KSP; - -namespace ProcAirships -{ - public class AthmosphereStock : Athmosphere - { - public override double getAirDensity() - { - //Log.post("Getting air density from stock athmosphere"); - double pressure = FlightGlobals.getStaticPressure(); - return FlightGlobals.getAtmDensity(pressure); - } - - public override double getAirPressure() - { - return FlightGlobals.getStaticPressure(); - } - - } - - -} diff --git a/source/ProcAirships/AthmosphereStockEditor.cs b/source/ProcAirships/AthmosphereStockEditor.cs deleted file mode 100644 index 4338bcb..0000000 --- a/source/ProcAirships/AthmosphereStockEditor.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using UnityEngine; -using KSP; - - -namespace ProcAirships -{ - class AthmosphereStockEditor : Athmosphere - { - - public override double getAirDensity() - { - double pressure = 0; - if(HighLogic.LoadedScene == GameScenes.EDITOR) - pressure = FlightGlobals.getStaticPressure(72.5, FlightGlobals.Bodies[1]); - else - pressure = FlightGlobals.getStaticPressure(69.0, FlightGlobals.Bodies[1]); - - return FlightGlobals.getAtmDensity(pressure); - } - - public override double getAirPressure() - { - - if (HighLogic.LoadedScene == GameScenes.EDITOR) - return FlightGlobals.getStaticPressure(72.5, FlightGlobals.Bodies[1]); - else - return FlightGlobals.getStaticPressure(69.0, FlightGlobals.Bodies[1]); - } - - - } -} diff --git a/source/ProcAirships/Buoyancy.cs b/source/ProcAirships/Buoyancy.cs index 1693cd4..57d15a5 100644 --- a/source/ProcAirships/Buoyancy.cs +++ b/source/ProcAirships/Buoyancy.cs @@ -11,7 +11,7 @@ namespace ProcAirships { public class Buoyancy : PartModule { - private Athmosphere athmosphere = null; + //private Athmosphere athmosphere = null; private Vector3 buoyantForce; @@ -21,7 +21,7 @@ public class Buoyancy : PartModule [KSPField(guiActive = true, guiActiveEditor=true, guiName = "Buoyancy", guiUnits = "kN", guiFormat = "F2")] public float guiBuoyancy = 0; - [KSPField(guiActive = true, guiName = "Grav Pull", guiUnits = "kN", guiFormat = "F2")] + [KSPField(guiActive = true, guiActiveEditor=true, guiName = "Grav Pull", guiUnits = "kN", guiFormat = "F2")] public float guiGravPull = 0; private float buoyancyMultiplicator = 1.0f; @@ -45,7 +45,7 @@ public override void OnStart(StartState state) Log.post(this.ClassName + " OnStart-callback: " + state.ToString()); - athmosphere = Factory.getAthmosphere(); + if (state != StartState.Editor) { @@ -53,37 +53,40 @@ public override void OnStart(StartState state) part.force_activate(); } - Log.post("get configuration. memo for me: PUT CONFIG STUFF IN A DEDICATED CLASS LATER."); - ConfigNode[] nodes = GameDatabase.Instance.GetConfigNodes("PROC_AIRSHIPS_CONFIG"); - - if (nodes.GetLength(0) == 0) - { - Debug.LogWarning("'PROC_AIRSHIPS_CONFIG' not detected. Using standard values."); - return; - } - - Config config = new Config(); - config.Load(nodes[0]); - + buoyancyMultiplicator = Preferences.buoyancyMultiplicator; - buoyancyMultiplicator = config.buoyancyMultiplicator; Log.post("Buoyancy Multiplicator: " + buoyancyMultiplicator, LogLevel.LOG_INFORMATION); - } + setupUI(); + } - [PartMessageListener(typeof(PartVolumeChanged), scenes: ~GameSceneFilter.Flight)] - public void ChangeVolume(string volumeName, float volume) - { - //Log.post("received ChangeVolume message for " + volumeName + " Volume: " + volume); + //public void OnCenterOfLiftQuery(CenterOfLiftQuery col) + //{ + // if (colActive) + // { + // Log.post("COL Query"); + // col.dir = Vector3.up; + // col.lift = tankVolume; + // col.pos = transform.position; + + + // } + //} + + + //[PartMessageListener(typeof(PartVolumeChanged), scenes: ~GameSceneFilter.Flight)] + //public void ChangeVolume(string volumeName, float volume) + //{ + // //Log.post("received ChangeVolume message for " + volumeName + " Volume: " + volume); - //if (volumeName != PartVolumes.Tankage.ToString()) - // return; + // //if (volumeName != PartVolumes.Tankage.ToString()) + // // return; - //if (volume <= 0f) - // throw new ArgumentOutOfRangeException("volume"); - //Log.post("Buoyancy changed volume to" + volume, LogLevel.LOG_INFORMATION); - //tankVolume = volume; - } + // //if (volume <= 0f) + // // throw new ArgumentOutOfRangeException("volume"); + // //Log.post("Buoyancy changed volume to" + volume, LogLevel.LOG_INFORMATION); + // //tankVolume = volume; + //} void Update() { @@ -151,17 +154,39 @@ private void applyBuoyancyForce() public Vector3 getBuoyancyForce() { - if (HighLogic.LoadedScene == GameScenes.EDITOR || HighLogic.LoadedScene == GameScenes.SPH) + if (util.editorActive()) { - float airDensity = (float)athmosphere.getAirDensity(); + //float airDensity = (float)athmosphere.getAirDensity(); + float airDensity = (float)Athmosphere.fetch().getAirDensity(part.rigidbody.worldCenterOfMass); return (-Vector3.down * 9.8f * airDensity * tankVolume) * buoyancyMultiplicator / 1000.0f; } else { - float airDensity = (float)athmosphere.getAirDensity(); + //float airDensity = (float)athmosphere.getAirDensity(); + float airDensity = (float)Athmosphere.fetch().getAirDensity(part.rigidbody.worldCenterOfMass); return (-FlightGlobals.getGeeForceAtPosition(part.rigidbody.worldCenterOfMass) * airDensity * tankVolume) * buoyancyMultiplicator / 1000.0f; } } - } -} + private void setupUI() + { + BaseField field = Fields["guiBuoyancy"]; + + if (field != null) + { + field.guiActiveEditor = Preferences.showBuoyancyInEditor; + field.guiActive = Preferences.showBuoyancyInFlight; + } + + field = Fields["guiGravPull"]; + if (field != null) + { + field.guiActiveEditor = Preferences.showGravPullInEditor; + field.guiActive = Preferences.showGravPullInFlight; + } + + + } + + } // class +} // namespace diff --git a/source/ProcAirships/BuoyancyStats.cs b/source/ProcAirships/BuoyancyStats.cs index 0b6db88..9653f27 100644 --- a/source/ProcAirships/BuoyancyStats.cs +++ b/source/ProcAirships/BuoyancyStats.cs @@ -24,6 +24,8 @@ public override void OnStart(StartState state) { Log.post(this.ClassName + " OnStart-callback: " + state.ToString()); + setupUI(); + if (state != StartState.Editor) { part.force_activate(); @@ -75,5 +77,26 @@ public override void OnFixedUpdate() vesselNetBuoyancy = (float)(vesselBuoyancy - FlightGlobals.getGeeForceAtPosition(part.rigidbody.worldCenterOfMass).magnitude * vesselMass); } + + private void setupUI() + { + BaseField field = Fields["vesselBuoyancy"]; + + if (field != null) + { + field.guiActiveEditor = Preferences.showVesselBuoyancyInEditor; + field.guiActive = Preferences.showVesselBuoyancyInFlight; + } + + field = Fields["vesselMass"]; + if (field != null) + { + field.guiActiveEditor = Preferences.showVesselMassInEditor; + field.guiActive = Preferences.showVesselMassInFlight; + } + + + } + } } diff --git a/source/ProcAirships/COBMarker.cs b/source/ProcAirships/COBMarker.cs new file mode 100644 index 0000000..43ccfac --- /dev/null +++ b/source/ProcAirships/COBMarker.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace ProcAirships +{ + + struct force + { + public force(Vector3 pos, Vector3 dir) + { + Pos = pos; + Dir = dir; + } + + public Vector3 Pos; + public Vector3 Dir; + } + + public class COBMarker : EditorMarker_CoL + { + + void Update() + { + List<force> forces = new List<force>(); + float BuoyancySum = 0.0f; + + if (EditorLogic.fetch.ship == null) return; + + foreach (Part p in EditorLogic.fetch.ship.parts) + { + //Log.post("part found"); + if (p.isConnected) + { + //Log.post("part is connected"); + foreach (Buoyancy b in p.Modules.OfType<Buoyancy>()) + { + //force f = new force(b.part.rigidbody.worldCenterOfMass, b.getBuoyancyForce()); + + forces.Add(new force(b.part.rigidbody.worldCenterOfMass ,b.getBuoyancyForce())); + BuoyancySum += b.getBuoyancyForce().magnitude; + } + } + } + + //Vector3 CoB = new Vector3(); + + force result = new force( Vector3.zero, Vector3.up); + + foreach(force f in forces) + { + result.Pos += f.Dir.magnitude * f.Pos; + result.Dir += f.Dir; + //CoB += f.Dir.magnitude * f.Pos; + } + //CoB = (1.0f / BuoyancySum) * CoB; + result.Pos = (1.0f / BuoyancySum) * result.Pos; + + this.posMarkerObject.transform.position = result.Pos; //CoB; //UpdatePosition(); + + dirMarkerObject.transform.rotation = Quaternion.LookRotation(result.Dir.normalized); + + + } + + protected override Vector3 UpdatePosition() + { + Log.post("COB marker update direction"); + return Vector3.zero; + } + + protected override Vector3 UpdateDirection() + { + Log.post("COB marker update direction"); + Vector3 direction = Vector3.zero; + + foreach (Part p in EditorLogic.fetch.ship.parts) + { + Log.post("part found"); + if (p.isConnected) + { + Log.post("part is connected"); + foreach (Buoyancy b in p.Modules.OfType<Buoyancy>()) + { + direction += b.getBuoyancyForce(); + + } + } + } + Log.post(direction); + return direction.normalized; + } + + + + } +} diff --git a/source/ProcAirships/Config.cs b/source/ProcAirships/Config.cs deleted file mode 100644 index 5cedf5c..0000000 --- a/source/ProcAirships/Config.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using UnityEngine; -using KSP; - -namespace ProcAirships -{ - [Serializable] - class Config : IConfigNode - { - [SerializeField] - public string name; - - [SerializeField] - public float buoyancyMultiplicator = 5.0f; - - - public void Load(ConfigNode node) - { - name = node.GetValue("name"); - float.TryParse(node.GetValue("buoyancyMultiplicator"), out buoyancyMultiplicator); - } - public void Save(ConfigNode node) - { - node.SetValue("name", name); - node.SetValue("buoyancyMultiplicator", buoyancyMultiplicator.ToString()); - } - - } -} diff --git a/source/ProcAirships/EditorController.cs b/source/ProcAirships/EditorController.cs new file mode 100644 index 0000000..ec907b7 --- /dev/null +++ b/source/ProcAirships/EditorController.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace ProcAirships +{ + [KSPAddon(KSPAddon.Startup.EditorAny, false)] + class EditorController : MonoBehaviour + { + + private GameObject CoL; + private GameObject CoB; + private GameObject CoBdir; + + COBMarker cobMarker; + EditorVesselOverlays vesselOverlays; + + bool markerVisibilityChanged = false; + + void Start() + { + + vesselOverlays = (EditorVesselOverlays)GameObject.FindObjectOfType( + typeof(EditorVesselOverlays)); + + if (vesselOverlays == null) + Log.post("Error. No vesselOverlays found", LogLevel.LOG_ERROR); + + CoL = vesselOverlays.CoLmarker.gameObject; + + if(CoL == null) + Log.post("CoL == null", LogLevel.LOG_ERROR); + + if (CoL.transform.parent != null) + Log.post("CoL parent: " + CoL.transform.parent); + + CoB = (GameObject)UnityEngine.Object.Instantiate(vesselOverlays.CoLmarker.gameObject); + //CoBdir = (GameObject)UnityEngine.Object.Instantiate(vesselOverlays.CoLmarker.dirMarkerObject); + + try + { + CoBdir = CoB.transform.GetChild(0).gameObject; + } + catch (Exception e) + { + Log.postException("Could not find CoBdir game object", e); + } + + try + { + Destroy(CoB.GetComponent<EditorMarker_CoL>()); + } + catch (Exception e) + { + Log.postException("Could destroy stock col marker", e); + } + + + CoB.name = "CoB marker"; + + cobMarker = CoB.AddComponent<COBMarker>(); + + //CoB.SetActive(true); + //CoBdir.SetActive(true); + + if(cobMarker == null) + Log.post("cobMarker == null", LogLevel.LOG_ERROR); + + cobMarker.enabled = true; + + cobMarker.posMarkerObject = CoB; + + cobMarker.dirMarkerObject = CoBdir; + + //cobMarker.referencePitch = vesselOverlays.referencePitch; + //cobMarker.referenceSpeed = vesselOverlays.referenceAirSpeed; + + + //CoB.renderer.enabled = true; + //CoB.renderer.material.color = Color.gray; + + foreach(Material m in CoB.renderer.materials) + { + m.color = Color.gray; + } + + + try + { + vesselOverlays.toggleCoLbtn.AddValueChangedDelegate(this.CoLButtonClick); + } + catch (Exception e) + { + Log.postException("Could not add Change delegate", e); + } + + //EZValueChangedDelegate + + + } + + public void CoLButtonClick(IUIObject obj) + { + + markerVisibilityChanged = true; + + + } + + void LateUpdate() + { + if(markerVisibilityChanged) + { + CoB.SetActive(CoL.activeSelf); + CoBdir.SetActive(CoL.activeSelf); + markerVisibilityChanged = false; + + } + + } + + } +} diff --git a/source/ProcAirships/Factory.cs b/source/ProcAirships/Factory.cs deleted file mode 100644 index af59bd0..0000000 --- a/source/ProcAirships/Factory.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using UnityEngine; -using System.Reflection; - - -namespace ProcAirships -{ - public static class Factory - { - - public static Athmosphere getAthmosphere() - { - bool isFARLoaded = AssemblyLoader.loadedAssemblies.Any(a => a.assembly.GetName().Name == "FerramAerospaceResearch"); - - isFARLoaded = false; // force stock behaviour because FAR does not seem to work right yet. - - - if (isFARLoaded) - { - Log.post("FAR detected", LogLevel.LOG_INFORMATION); - - AssemblyLoader.LoadedAssembly FAR = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.assembly.GetName().Name == "FerramAerospaceResearch"); - Log.post("FAR Version: " + FAR.assembly.GetName().Version.ToString(), LogLevel.LOG_INFORMATION); - - if (HighLogic.LoadedScene == GameScenes.EDITOR || HighLogic.LoadedScene == GameScenes.SPH) - { - Log.post("create Athmosphere for Editor.", LogLevel.LOG_INFORMATION); - return new AthmosphereStockEditor(); - } - else - { - Log.post("create Athmosphere for Flight.", LogLevel.LOG_INFORMATION); - return new AthmosphereFAR(); - } - } - else - { - Log.post("No FAR detected. Fallback to Stock behaviour.", LogLevel.LOG_INFORMATION); - if (HighLogic.LoadedScene == GameScenes.EDITOR || HighLogic.LoadedScene == GameScenes.SPH) - { - - Log.post("create Athmosphere for Editor.", LogLevel.LOG_INFORMATION); - return new AthmosphereStockEditor(); - } - else - { - Log.post("create Athmosphere for Flight.", LogLevel.LOG_INFORMATION); - return new AthmosphereStock(); - } - } - } - - - - } -} diff --git a/source/ProcAirships/IAthmosphereModel.cs b/source/ProcAirships/IAthmosphereModel.cs new file mode 100644 index 0000000..b0ce4d8 --- /dev/null +++ b/source/ProcAirships/IAthmosphereModel.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace ProcAirships +{ + interface IAthmosphereModel + { + + bool init(); + + double getAirDensity(double altitude, CelestialBody body); + double getAirDensity(Vector3 worldPosition, CelestialBody body); + + double getAirPressure(double altitude, CelestialBody body); + double getAirPressure(Vector3 worldPosition, CelestialBody body); + + } +} diff --git a/source/ProcAirships/Log.cs b/source/ProcAirships/Log.cs index 040b6f6..93abd92 100644 --- a/source/ProcAirships/Log.cs +++ b/source/ProcAirships/Log.cs @@ -19,13 +19,13 @@ public enum LogLevel : uint public class Log { - public static LogLevel logLevel = LogLevel.LOG_ALL; // the highest debug level to show in logs + //public static LogLevel logLevel = LogLevel.LOG_ALL; // the highest debug level to show in logs public static void post(object message, LogLevel level = LogLevel.LOG_DEBUG, UnityEngine.Object context = null) { - if (level <= logLevel) + if ((uint)level <= Preferences.debugLevel) { string assemblyName = Assembly.GetExecutingAssembly().GetName().Name; string assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); @@ -62,7 +62,12 @@ public static void post(object message, LogLevel level = LogLevel.LOG_DEBUG, Uni public static void postException(Exception e) { Debug.LogException(e); - //Debug.Log() + } + + public static void postException(object message, Exception e) + { + Debug.LogError(message); + Debug.LogException(e); } diff --git a/source/ProcAirships/Preferences.cs b/source/ProcAirships/Preferences.cs new file mode 100644 index 0000000..a6e5418 --- /dev/null +++ b/source/ProcAirships/Preferences.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Reflection; +using UnityEngine; +using KSP.IO; + +namespace ProcAirships +{ + + public class Preferences + { + + public static float buoyancyMultiplicator = 3.0f; + + public static bool showVolumeInfoInEditor = false; + public static bool showVolumeInfoInFlight = false; + public static bool showTemperatureInEditor = false; + public static bool showTemperatureInFlight = true; + public static bool showAbsPressureInEditor = false; + public static bool showAbsPressureInFlight = false; + public static bool showBuoyancyInEditor = false; + public static bool showBuoyancyInFlight = false; + public static bool showVesselBuoyancyInEditor = false; + public static bool showVesselBuoyancyInFlight = false; + public static bool showVesselMassInEditor = false; + public static bool showVesselMassInFlight = false; + public static bool showGravPullInEditor = false; + public static bool showGravPullInFlight = false; + public static uint debugLevel = (uint)LogLevel.LOG_ALL; + public static bool pressureDestruction = true; + public static bool alwaysControllable = false; + + } + + public static class PluginConfigurationExtensions + { + + public static bool TryGetBool( this PluginConfiguration config, string key, ref bool value) + { + return bool.TryParse(config.GetValue(key, value.ToString()), out value); + } + + public static void SetBool(this PluginConfiguration config, string key, bool value) + { + config.SetValue(key, value.ToString()); + } + + public static bool TryGetFloat(this PluginConfiguration config, string key, ref float value) + { + return float.TryParse(config.GetValue(key, value.ToString()), out value); + } + + public static bool TryGetUInt(this PluginConfiguration config, string key, ref uint value) + { + return uint.TryParse(config.GetValue(key, value.ToString()), out value); + } + + /* + public static void SetFloat(this PluginConfiguration config, string key, float value) + { + config.SetValue(key, value.ToString()); + } + */ + + public static void SetVal<T>(this PluginConfiguration config, string key, T value) where T: IConvertible + { + config.SetValue(key, value.ToString()); + } + + } + + + [KSPAddon(KSPAddon.Startup.SpaceCentre, false)] + class PrefLoader : MonoBehaviour + { + public void Awake() + { + + PluginConfiguration config = PluginConfiguration.CreateForType<PrefLoader>(); + + config.load(); + + + //float.TryParse(config.GetValue("buoyancyMultiplicator", Preferences.buoyancyMultiplicator.ToString()), out Preferences.buoyancyMultiplicator); + + config.TryGetFloat("buoyancyMultiplicator", ref Preferences.buoyancyMultiplicator); + + config.TryGetBool("showVolumeInfoInEditor", ref Preferences.showVolumeInfoInEditor); + config.TryGetBool("showVolumeInfoInFlight", ref Preferences.showVolumeInfoInFlight); + + config.TryGetBool("showTemperatureInEditor", ref Preferences.showTemperatureInEditor); + config.TryGetBool("showTemperatureInFlight", ref Preferences.showTemperatureInFlight); + + config.TryGetBool("showAbsPressureInEditor" , ref Preferences.showAbsPressureInEditor); + config.TryGetBool("showAbsPressureInFlight", ref Preferences.showAbsPressureInFlight); + + config.TryGetBool("showBuoyancyInEditor", ref Preferences. showBuoyancyInEditor); + config.TryGetBool("showBuoyancyInFlight", ref Preferences.showBuoyancyInFlight); + + config.TryGetBool("showVesselBuoyancyInEditor", ref Preferences.showVesselBuoyancyInEditor); + config.TryGetBool("showVesselBuoyancyInFlight", ref Preferences.showVesselBuoyancyInFlight); + + config.TryGetBool("showVesselMassInEditor", ref Preferences.showVesselMassInEditor); + config.TryGetBool("showVesselMassInFlight", ref Preferences.showVesselMassInFlight); + + config.TryGetBool("showGravPullInEditor", ref Preferences.showGravPullInEditor); + config.TryGetBool("showGravPullInFlight", ref Preferences.showGravPullInFlight); + + config.TryGetUInt("debugLevel", ref Preferences.debugLevel); + + config.TryGetBool("pressureDestruction", ref Preferences.pressureDestruction); + config.TryGetBool("alwaysControllable", ref Preferences.alwaysControllable); + + } + + void OnDestroy() + { + PluginConfiguration config = PluginConfiguration.CreateForType<PrefLoader>(); + + config.SetVal("buoyancyMultiplicator", Preferences.buoyancyMultiplicator); + + config.SetVal("showVolumeInfoInEditor", Preferences.showVolumeInfoInEditor); + config.SetVal("showVolumeInfoInFlight", Preferences.showVolumeInfoInFlight); + config.SetVal("showTemperatureInEditor", Preferences.showTemperatureInEditor); + config.SetVal("showTemperatureInFlight", Preferences.showTemperatureInFlight); + config.SetVal("showAbsPressureInEditor", Preferences.showAbsPressureInEditor); + config.SetVal("showAbsPressureInFlight", Preferences.showAbsPressureInFlight); + config.SetVal("showBuoyancyInEditor", Preferences.showBuoyancyInEditor); + config.SetVal("showBuoyancyInFlight", Preferences.showBuoyancyInFlight); + config.SetVal("showVesselBuoyancyInEditor", Preferences.showVesselBuoyancyInEditor); + config.SetVal("showVesselBuoyancyInFlight", Preferences.showVesselBuoyancyInFlight); + config.SetVal("showVesselMassInEditor", Preferences.showVesselMassInEditor); + config.SetVal("showVesselMassInFlight", Preferences.showVesselMassInFlight); + config.SetVal("showGravPullInEditor", Preferences.showGravPullInEditor); + config.SetVal("showGravPullInFlight", Preferences.showGravPullInFlight); + config.SetVal("debugLevel", Preferences.debugLevel); + config.SetVal("pressureDestruction", Preferences.pressureDestruction); + config.SetVal("alwaysControllable", Preferences.alwaysControllable); + + config.save(); + + } + + } +} diff --git a/source/ProcAirships/ProcAirships.csproj b/source/ProcAirships/ProcAirships.csproj index f9dcb01..cc00908 100644 --- a/source/ProcAirships/ProcAirships.csproj +++ b/source/ProcAirships/ProcAirships.csproj @@ -38,15 +38,9 @@ <SpecificVersion>False</SpecificVersion> <HintPath>..\..\..\..\..\Kerbal Space Program\0.24.2_dev\KSP_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath> </Reference> - <Reference Include="FerramAerospaceResearch"> - <HintPath>..\..\..\..\..\Kerbal Space Program\0.24.2_dev\GameData\FerramAerospaceResearch\Plugins\FerramAerospaceResearch.dll</HintPath> - </Reference> <Reference Include="KSPAPIExtensions, Version=1.7.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\..\..\KSPAPIExtensionsDLL\KSPAPIExtensions.dll</HintPath> - </Reference> - <Reference Include="ProceduralParts"> - <HintPath>..\..\..\..\..\Kerbal Space Program\0.24.2_dev\GameData\ProceduralParts\Plugins\ProceduralParts.dll</HintPath> + <HintPath>..\..\..\..\KSP\KSPAPIExtensionsDLL\from PP\KSPAPIExtensions.dll</HintPath> </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> @@ -59,25 +53,28 @@ </Reference> </ItemGroup> <ItemGroup> + <Compile Include="AirshipCost.cs" /> <Compile Include="AirshipDrain.cs" /> <Compile Include="AirshipDrainResource.cs" /> <Compile Include="AirshipEnvelope.cs" /> <Compile Include="Athmosphere.cs" /> - <Compile Include="AthmosphereFAR.cs" /> - <Compile Include="AthmosphereStock.cs" /> - <Compile Include="AthmosphereStockEditor.cs" /> + <Compile Include="AthmosphereModelFAR.cs" /> + <Compile Include="AthmosphereModelStock.cs" /> <Compile Include="Buoyancy.cs" /> <Compile Include="BuoyancyStats.cs" /> - <Compile Include="Config.cs" /> - <Compile Include="Factory.cs" /> + <Compile Include="COBMarker.cs" /> + <Compile Include="EditorController.cs" /> + <Compile Include="IAthmosphereModel.cs" /> <Compile Include="Log.cs" /> <Compile Include="3rd Party\PartExtensions.cs" /> + <Compile Include="Preferences.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="util.cs" /> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <PropertyGroup> - <PostBuildEvent>copy $(TargetDir)$(TargetFileName) $(ProjectDir)..\..\GameData\ProcAirships\Plugins</PostBuildEvent> + <PostBuildEvent>copy $(TargetDir)$(TargetFileName) $(ProjectDir)..\..\GameData\ProcAirships\Plugins +copy $(TargetDir)KSPAPIExtensions.dll $(ProjectDir)..\..\GameData\ProcAirships\Plugins</PostBuildEvent> </PropertyGroup> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. diff --git a/source/ProcAirships/Properties/AssemblyInfo.cs b/source/ProcAirships/Properties/AssemblyInfo.cs index d092968..0daec4f 100644 --- a/source/ProcAirships/Properties/AssemblyInfo.cs +++ b/source/ProcAirships/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern // übernehmen, indem Sie "*" eingeben: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.3.0.0")] -[assembly: AssemblyFileVersion("0.3.0.0")] +[assembly: AssemblyVersion("0.4.1.0")] +[assembly: AssemblyFileVersion("0.4.1.0")] diff --git a/source/ProcAirships/util.cs b/source/ProcAirships/util.cs index b82c34c..7cc9256 100644 --- a/source/ProcAirships/util.cs +++ b/source/ProcAirships/util.cs @@ -18,7 +18,7 @@ public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T> public static bool Toggle(this bool val) { - return val == true ? false : true; + return (val == true ? false : true); } public static bool editorActive() @@ -29,6 +29,22 @@ public static bool editorActive() return false; } + public static bool vabActive() + { + if (HighLogic.LoadedScene == GameScenes.EDITOR) + return true; + else + return false; + } + + public static bool sphActive() + { + if (HighLogic.LoadedScene == GameScenes.SPH) + return true; + else + return false; + } + public static double celsiusToKelvin(double T) { return T + 273.15d;