Browse Source

- refactoring and right-click GUI improvements

- added script to generate mono symbols for debugging
master
Youen Toupin 9 years ago
parent
commit
9bdd0ff1d2
  1. 1
      .gitignore
  2. 9
      Plugin/Aerostats.csproj
  3. 110
      Plugin/ModuleAerostat.cs
  4. 15
      Plugin/Util.cs
  5. 16
      build/prepare-debug.bat
  6. 4
      todo.txt

1
.gitignore vendored

@ -3,3 +3,4 @@
/Plugin/obj /Plugin/obj
/Plugin/bin /Plugin/bin
/Aerostats.zip /Aerostats.zip
/.vs/Aerostats/v14/*.suo

9
Plugin/Aerostats.csproj

@ -17,7 +17,7 @@
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>..\..\1.0_dev\GameData\Aerostats\Plugin\</OutputPath> <OutputPath>..\..\..\..\Jeux\KSP_1_0_5\GameData\Aerostats\Plugin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
@ -32,7 +32,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Assembly-CSharp"> <Reference Include="Assembly-CSharp">
<HintPath>..\..\1.0_dev\KSP_Data\Managed\Assembly-CSharp.dll</HintPath> <HintPath>..\..\..\..\Jeux\KSP_1_0_5\KSP_Data\Managed\Assembly-CSharp.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
@ -42,7 +42,7 @@
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="UnityEngine"> <Reference Include="UnityEngine">
<HintPath>..\..\1.0_dev\KSP_Data\Managed\UnityEngine.dll</HintPath> <HintPath>..\..\..\..\Jeux\KSP_1_0_5\KSP_Data\Managed\UnityEngine.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
@ -53,7 +53,8 @@
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>
<PostBuildEvent>if $(ConfigurationName)==Release ("$(ProjectDir)..\build\build-package.bat")</PostBuildEvent> <PostBuildEvent>if $(ConfigurationName)==Debug ("$(ProjectDir)..\build\prepare-debug.bat" "$(OutDir)")
if $(ConfigurationName)==Release ("$(ProjectDir)..\build\build-package.bat")</PostBuildEvent>
</PropertyGroup> </PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- 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. Other similar extension points exist, see Microsoft.Common.targets.

110
Plugin/ModuleAerostat.cs

@ -13,7 +13,7 @@ namespace Aerostats
private static readonly float ZeroCelsius = 273.15f; private static readonly float ZeroCelsius = 273.15f;
private static readonly float StandardPressure = 100000.0f; private static readonly float StandardPressure = 100000.0f;
private static readonly float StpVolumeToMoles = 100000.0f / R / 273.15f; private static readonly float StpVolumeToMoles = 100000.0f / R / 273.15f;
/// <summary> /// <summary>
/// Maximum rate at which gas can be injected in the balloon to fill it, in m^3/s at stp /// Maximum rate at which gas can be injected in the balloon to fill it, in m^3/s at stp
/// </summary> /// </summary>
@ -79,38 +79,44 @@ namespace Aerostats
[KSPField(isPersistant = false, guiActive = false)] [KSPField(isPersistant = false, guiActive = false)]
public float SpringHardness = 5000.0f; public float SpringHardness = 5000.0f;
private bool Staged; [KSPField(isPersistant = false, guiActive = true)]
public string Status;
private bool Deployed;
private bool Destroyed; private bool Destroyed;
/// <summary> /// <summary>
/// Gas quantity currently inside the balloon /// Gas quantity currently inside the balloon
/// </summary> /// </summary>
[KSPField(isPersistant = true, guiActive = true)] [KSPField(guiName = "Gas quantity", isPersistant = true, guiActive = true)]
public float LiftingGasQuantity; public float LiftingGasQuantity;
[KSPField(guiName = "Volume", isPersistant = false, guiActive = true)]
public string VolumeStatus;
/// <summary> /// <summary>
/// Inflation ratio of the balloon (0=empty, 1=maximum) /// Inflation ratio of the balloon (0=empty, 1=maximum)
/// </summary> /// </summary>
private float Inflation = 0; private float Inflation = 0;
private float Radius = 0.01f;
private GameObject Balloon; private GameObject Balloon;
private LineRenderer Spring; private LineRenderer Spring;
private Vector3 EstimatedNextFramePosition; private Vector3 EstimatedNextFramePosition;
public override void OnStart(PartModule.StartState state) [KSPEvent(guiActive = true, active = true, externalToEVAOnly = false, guiActiveUnfocused = true, guiName = "Deploy balloon", unfocusedRange = 5)]
{ public void Deploy()
if (!HighLogic.LoadedSceneIsEditor && !HighLogic.LoadedSceneIsFlight) { return; } {
if (Destroyed || Deployed)
return;
ScreenMessages.PostScreenMessage("Aerostat loaded"); Deployed = true;
part.stagingIcon = "PARACHUTES";
}
private void OnStaged()
{
UnityEngine.Debug.Log("Aerostats: staged"); UnityEngine.Debug.Log("Aerostats: staged");
ScreenMessages.PostScreenMessage("staged"); Util.PostScreenMessage("staged");
Balloon = GameObject.CreatePrimitive(PrimitiveType.Sphere); Balloon = GameObject.CreatePrimitive(PrimitiveType.Sphere);
Balloon.transform.position = part.Rigidbody.position + part.Rigidbody.transform.up; Balloon.transform.position = part.Rigidbody.position + part.Rigidbody.transform.up;
@ -131,35 +137,55 @@ namespace Aerostats
part.OnJustAboutToBeDestroyed += OnPartDestroyed; part.OnJustAboutToBeDestroyed += OnPartDestroyed;
EstimatedNextFramePosition = part.Rigidbody.position; EstimatedNextFramePosition = part.Rigidbody.position;
} }
private void OnPartDestroyed() [KSPEvent(guiActive = true, active = true, externalToEVAOnly = false, guiActiveUnfocused = true, guiName = "Cut rope", unfocusedRange = 5)]
{ public void Cut()
{
if (Destroyed || !Deployed)
return;
Destroy(Balloon); // another option could be to let it float freely, but in this case the buoyancy code should be implemented in a separate MonoBehavior Destroy(Balloon); // another option could be to let it float freely, but in this case the buoyancy code should be implemented in a separate MonoBehavior
Balloon = null; Balloon = null;
Spring = null; Spring = null;
part.OnJustAboutToBeDestroyed -= OnPartDestroyed; part.OnJustAboutToBeDestroyed -= OnPartDestroyed;
Destroyed = true; Destroyed = true;
}
public override void OnStart(PartModule.StartState state)
{
if (!HighLogic.LoadedSceneIsEditor && !HighLogic.LoadedSceneIsFlight) { return; }
Util.PostScreenMessage("Aerostat loaded");
part.stagingIcon = "PARACHUTES";
}
private void OnPartDestroyed()
{
Cut();
} }
private void FixedUpdate() private void FixedUpdate()
{ {
if (Destroyed) if (Destroyed)
{
Status = "separated";
VolumeStatus = "-";
return; return;
}
if (!Staged && GameSettings.LAUNCH_STAGES.GetKeyDown() && vessel.isActiveVessel && (part.inverseStage == Staging.CurrentStage - 1 || Staging.CurrentStage == 0)) if (GameSettings.LAUNCH_STAGES.GetKeyDown() && vessel.isActiveVessel && (part.inverseStage == Staging.CurrentStage - 1 || Staging.CurrentStage == 0))
{ {
Staged = true; Deploy();
OnStaged();
} }
if (Staged) if (Deployed)
{ {
// detect Krakensbane teleportation, and fix up the balloon position (otherwise it results in instant ship disintegration due to extreme forces on the spring) // detect Krakensbane teleportation, and fix up the balloon position (otherwise it results in instant ship disintegration due to extreme forces on the spring)
if((part.Rigidbody.position - EstimatedNextFramePosition).magnitude > 1000.0f) if ((part.Rigidbody.position - EstimatedNextFramePosition).magnitude > 1000.0f)
{ {
ScreenMessages.PostScreenMessage("Krakensbane teleportation detected! (dist=" + (part.Rigidbody.position - EstimatedNextFramePosition).magnitude+")"); Util.PostScreenMessage("Krakensbane teleportation detected! (dist=" + (part.Rigidbody.position - EstimatedNextFramePosition).magnitude+")");
var offset = part.rigidbody.position - EstimatedNextFramePosition; var offset = part.rigidbody.position - EstimatedNextFramePosition;
Balloon.rigidbody.position += offset; Balloon.rigidbody.position += offset;
Balloon.transform.position = Balloon.rigidbody.position; Balloon.transform.position = Balloon.rigidbody.position;
@ -179,11 +205,21 @@ namespace Aerostats
// infalting balloon // infalting balloon
float stepFinalQuantity = Math.Min(LiftingGasQuantity + MaxGasFillRate * Time.fixedDeltaTime, Math.Min(LiftingGasTargetQuantity, currentMaxQuantity)); float stepFinalQuantity = Math.Min(LiftingGasQuantity + MaxGasFillRate * Time.fixedDeltaTime, Math.Min(LiftingGasTargetQuantity, currentMaxQuantity));
float step = Math.Max(stepFinalQuantity - LiftingGasQuantity, 0.0f); float step = Math.Max(stepFinalQuantity - LiftingGasQuantity, 0.0f);
LiftingGasQuantity += part.RequestResource("Helium", step); float stepResource = part.RequestResource("Helium", step);
LiftingGasQuantity += stepResource;
if(step > 0.0f)
{
Status = stepResource > 0.0f ? "inflating" : "out-of-gas";
}
else
{
Status = "nominal";
}
} }
else else
{ {
// deflating balloon // deflating balloon
Status = LiftingGasTargetQuantity == LiftingGasQuantity ? "nominal" : "deflating";
LiftingGasQuantity = Math.Max(LiftingGasQuantity - MaxGasVentRate * Time.fixedDeltaTime, LiftingGasTargetQuantity); LiftingGasQuantity = Math.Max(LiftingGasQuantity - MaxGasVentRate * Time.fixedDeltaTime, LiftingGasTargetQuantity);
} }
@ -191,6 +227,7 @@ namespace Aerostats
// balloon security valve // balloon security valve
if (LiftingGasQuantity > currentMaxQuantity) if (LiftingGasQuantity > currentMaxQuantity)
{ {
Status = "full (venting)";
Util.PostSingleScreenMessage("security valve", "Some gas has been vented by the balloon security valve"); Util.PostSingleScreenMessage("security valve", "Some gas has been vented by the balloon security valve");
LiftingGasQuantity = currentMaxQuantity; LiftingGasQuantity = currentMaxQuantity;
} }
@ -198,6 +235,7 @@ namespace Aerostats
float currentGasMoles = StpVolumeToMoles * LiftingGasQuantity; float currentGasMoles = StpVolumeToMoles * LiftingGasQuantity;
float currentGasVolume = currentGasMoles * R * balloonInternalTemperature / externalPressure; float currentGasVolume = currentGasMoles * R * balloonInternalTemperature / externalPressure;
Inflation = currentGasVolume / MaxBalloonVolume; Inflation = currentGasVolume / MaxBalloonVolume;
VolumeStatus = Mathf.Round(currentGasVolume) + " / " + Mathf.Round(MaxBalloonVolume);
Util.PostSingleScreenMessage("inflation", "Inflation = " + (Inflation * 100.0f).ToString("0.00") + "%"); Util.PostSingleScreenMessage("inflation", "Inflation = " + (Inflation * 100.0f).ToString("0.00") + "%");
@ -210,8 +248,8 @@ namespace Aerostats
//Util.PostSingleScreenMessage("gravity", "Gravity accel = (" + gravityAccel.x + ", " + gravityAccel.y + ", " + gravityAccel.z + ")"); //Util.PostSingleScreenMessage("gravity", "Gravity accel = (" + gravityAccel.x + ", " + gravityAccel.y + ", " + gravityAccel.z + ")");
// V = 4/3*pi*r^3 // V = 4/3*pi*r^3
float radius = Mathf.Pow(currentGasVolume * 0.75f / Mathf.PI, 0.333f); Radius = Mathf.Pow(currentGasVolume * 0.75f / Mathf.PI, 0.333f);
float scale = radius * 2.0f + 0.1f; float scale = Radius * 2.0f + 0.1f;
Balloon.transform.localScale = new Vector3(scale,scale,scale); Balloon.transform.localScale = new Vector3(scale,scale,scale);
Balloon.rigidbody.mass = (BalloonEmptyMass + balloonGasMass) * 0.001f; Balloon.rigidbody.mass = (BalloonEmptyMass + balloonGasMass) * 0.001f;
@ -221,16 +259,16 @@ namespace Aerostats
var airVelocity = Balloon.rigidbody.velocity + Krakensbane.GetFrameVelocity() /*- vessel.mainBody.getRFrmVel(vessel.GetWorldPos3D())*/; var airVelocity = Balloon.rigidbody.velocity + Krakensbane.GetFrameVelocity() /*- vessel.mainBody.getRFrmVel(vessel.GetWorldPos3D())*/;
float sqVel = (float)airVelocity.magnitude; float sqVel = (float)airVelocity.magnitude;
sqVel *= sqVel; sqVel *= sqVel;
float dragForce = 0.5f * airDensity * sqVel * BalloonDragCoeff * (Mathf.PI * radius * radius); float dragForce = 0.5f * airDensity * sqVel * BalloonDragCoeff * (Mathf.PI * Radius * Radius);
Util.PostSingleScreenMessage("balloon drag", "Drag = " + dragForce + "N"); Util.PostSingleScreenMessage("balloon drag", "Drag = " + dragForce + "N");
Balloon.rigidbody.AddForce(-airVelocity.normalized * dragForce / 1000.0f, ForceMode.Force); Balloon.rigidbody.AddForce(-airVelocity.normalized * dragForce / 1000.0f, ForceMode.Force);
// spring between balloon and base // spring between balloon and base
float restLength = SpringRestLength + radius; float restLength = SpringRestLength + Radius;
var springVec = Balloon.rigidbody.position - part.rigidbody.position; var springVec = Balloon.rigidbody.position - part.rigidbody.position;
float springLength = springVec.magnitude; float springLength = springVec.magnitude;
float springForceMag = 0; float springForceMag = 0;
var balloonAttachPoint = Balloon.rigidbody.position - Balloon.transform.up.normalized * radius; var balloonAttachPoint = Balloon.rigidbody.position - Balloon.transform.up.normalized * Radius;
if(springLength > restLength) if(springLength > restLength)
{ {
float tensingLength = springLength - restLength; float tensingLength = springLength - restLength;
@ -240,6 +278,22 @@ namespace Aerostats
Balloon.rigidbody.AddForceAtPosition(-springForce, balloonAttachPoint, ForceMode.Force); Balloon.rigidbody.AddForceAtPosition(-springForce, balloonAttachPoint, ForceMode.Force);
} }
Util.PostSingleScreenMessage("spring force", "Spring force = " + springForceMag + "N"); Util.PostSingleScreenMessage("spring force", "Spring force = " + springForceMag + "N");
}
else
{
Status = "packed";
VolumeStatus = "-";
}
}
private void LateUpdate()
{
if (Destroyed)
return;
if (Deployed)
{
var balloonAttachPoint = Balloon.rigidbody.position - Balloon.transform.up.normalized * Radius;
Spring.SetPosition(0, part.transform.position); Spring.SetPosition(0, part.transform.position);
Spring.SetPosition(1, balloonAttachPoint); Spring.SetPosition(1, balloonAttachPoint);

15
Plugin/Util.cs

@ -1,4 +1,8 @@
using System; #if DEBUG
#define ENABLE_ONSCREEN_DEBUG
#endif
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -11,9 +15,18 @@ namespace Aerostats
public static void PostSingleScreenMessage(string id, string message) public static void PostSingleScreenMessage(string id, string message)
{ {
#if ENABLE_ONSCREEN_DEBUG
if (messages.ContainsKey(id)) if (messages.ContainsKey(id))
ScreenMessages.RemoveMessage(messages[id]); ScreenMessages.RemoveMessage(messages[id]);
messages[id] = ScreenMessages.PostScreenMessage(message); messages[id] = ScreenMessages.PostScreenMessage(message);
#endif
}
public static void PostScreenMessage(string message)
{
#if ENABLE_ONSCREEN_DEBUG
ScreenMessages.PostScreenMessage(message);
#endif
} }
} }
} }

16
build/prepare-debug.bat

@ -0,0 +1,16 @@
@echo off
rem get parameters that are passed by visual studio post build event
SET outDllPath=%1
rem make sure the initial working directory is the one containing the current script
SET scriptPath=%~dp0
SET initialWD=%CD%
rem generate the MDB file needed by Monodevelop and UnityVS for debugging
rem see http://forum.kerbalspaceprogram.com/index.php?/topic/102909-ksp-plugin-debugging-for-visual-studio-and-monodevelop-on-all-os/&page=1 for information on how to setup your debugging environment
echo "Aerostats.dll -> %outDllPath%Aerostats.dll.mdb"
cd %outDllPath%
cmd /C "c:\Program Files (x86)\Mono\bin\pdb2mdb" Aerostats.dll
cd %initialWD%

4
todo.txt

@ -0,0 +1,4 @@
save/load balloon state
test in orbit
button to deploy
button to cut the rope
Loading…
Cancel
Save