Merge branch 'master' of github.com:toadicus/QuantumStrutsContinued
Merge branch 'master' of github.com:toadicus/QuantumStrutsContinued

// QuantumStrutsContinued // QuantumStrutsContinued
// //
// AssemblyInfo.cs // AssemblyInfo.cs
// //
// Continued from QuantumStruts by BoJaN. Used by permission. // Continued from QuantumStruts by BoJaN. Used by permission.
// //
// ModuleManager patches © 2014 K3|Chris. Used by permission. // ModuleManager patches © 2014 K3|Chris. Used by permission.
// //
// Copyright © 2014, toadicus // Copyright © 2014, toadicus
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met: // are permitted provided that the following conditions are met:
// //
// 1. Redistributions of source code must retain the above copyright notice, // 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// //
// 2. Redistributions in binary form must reproduce the above copyright notice, // 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation and/or other // this list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution. // materials provided with the distribution.
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
   
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("QuantumStrutsContinued")] [assembly: AssemblyTitle("QuantumStrutsContinued")]
[assembly: AssemblyDescription("A KSP part mod that provides magical struts for rigidifying vessels constructed outside the VAB.")] [assembly: AssemblyDescription("A KSP part mod that provides magical struts for rigidifying vessels constructed outside the VAB.")]
[assembly: AssemblyProduct("QuantumStrutsContinued")] [assembly: AssemblyProduct("QuantumStrutsContinued")]
[assembly: AssemblyCopyright("Copyright © 2014 toadicus")] [assembly: AssemblyCopyright("Copyright © 2014 toadicus")]
   
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
   
// The following GUID is for the ID of the typelib if this project is exposed to COM // The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("57e209db-4b94-46b4-be0e-bd6e830d4eb5")] [assembly: Guid("57e209db-4b94-46b4-be0e-bd6e830d4eb5")]
   
// Version information for an assembly consists of the following four values: // Version information for an assembly consists of the following four values:
// //
// Major Version // Major Version
// Minor Version // Minor Version
// Build Number // Build Number
// Revision // Revision
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.4.*")] [assembly: AssemblyVersion("1.6.*")]
   
// QuantumStrutsContinued // QuantumStrutsContinued
// //
// QuantumStrut.cs // QuantumStrut.cs
// //
// Continued from QuantumStruts by BoJaN. Used by permission. // Continued from QuantumStruts by BoJaN. Used by permission.
// //
// ModuleManager patches © 2014 K3|Chris. Used by permission. // ModuleManager patches © 2014 K3|Chris. Used by permission.
// //
// Copyright © 2014, toadicus // Copyright © 2014, toadicus
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met: // are permitted provided that the following conditions are met:
// //
// 1. Redistributions of source code must retain the above copyright notice, // 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// //
// 2. Redistributions in binary form must reproduce the above copyright notice, // 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation and/or other // this list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution. // materials provided with the distribution.
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
using KSP; using KSP;
using System; using System;
using ToadicusTools; using ToadicusTools;
using UnityEngine; using UnityEngine;
   
namespace QuantumStrut namespace QuantumStrut
{ {
public class QuantumStrut : PartModule public class QuantumStrut : PartModule
{ {
public static Material LaserMaterial; public static Material LaserMaterial;
Strut strut = null; Strut strut = null;
GameObject lineObj; GameObject lineObj;
LineRenderer lr; LineRenderer lr;
int I = 0; int I = 0;
   
#region Fields #region Fields
   
[KSPField(isPersistant = true)] [KSPField(isPersistant = true)]
public bool IsEnabled = true; public bool IsEnabled = true;
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public float PowerConsumption = 0; public float PowerConsumption = 0;
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public string TransformName = ""; public string TransformName = "";
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public Vector3 Start = new Vector3(0, 0, 0); public Vector3 Start = new Vector3(0, 0, 0);
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public Vector3 Dir = new Vector3(0, 1, 0); public Vector3 Dir = new Vector3(0, 1, 0);
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public string Material = "Particles/Additive"; public string Material = "Particles/Additive";
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public Vector3 StartColor = Vector3.zero; public Vector3 StartColor = Vector3.zero;
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public Vector3 EndColor = Vector3.zero; public Vector3 EndColor = Vector3.zero;
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public float StartSize = 0.03f; public float StartSize = 0.03f;
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public float EndSize = 0.015f; public float EndSize = 0.015f;
   
[KSPField( [KSPField(
isPersistant = false, guiActiveEditor = true, isPersistant = false, guiActiveEditor = true,
guiName = "Max. Strut Length", guiUnits = "m", guiFormat = "F0" guiName = "Max. Strut Length", guiUnits = "m", guiFormat = "F0"
)] )]
[UI_FloatRange(minValue = 2f, maxValue = 50f, stepIncrement = 2f)] [UI_FloatRange(minValue = 2f, maxValue = 50f, stepIncrement = 2f)]
public float MaxStrutLength = 10f; public float MaxStrutLength = 10f;
   
#endregion #endregion
   
#region Actions #region Actions
   
[KSPAction("Toggle")] [KSPAction("Toggle")]
public void ToggleStrut(KSPActionParam param) public void ToggleStrut(KSPActionParam param)
{ {
IsEnabled = !IsEnabled; IsEnabled = !IsEnabled;
CheckHit(); CheckHit();
} }
   
[KSPAction("Activate")] [KSPAction("Activate")]
public void ActivateStrut(KSPActionParam param) public void ActivateStrut(KSPActionParam param)
{ {
this.ActivateStrut(); this.ActivateStrut();
} }
   
[KSPAction("Deactivate")] [KSPAction("Deactivate")]
public void DeactivateStrut(KSPActionParam param) public void DeactivateStrut(KSPActionParam param)
{ {
this.DeactivateStrut(); this.DeactivateStrut();
} }
   
#endregion #endregion
   
#region Events #region Events
   
[KSPEvent(guiActive = true, guiName = "Activate", active = true, guiActiveUnfocused = true, unfocusedRange = 2f)] [KSPEvent(guiActive = true, guiName = "Activate", active = true, guiActiveUnfocused = true, unfocusedRange = 2f)]
public void ActivateStrut() public void ActivateStrut()
{ {
IsEnabled = true; IsEnabled = true;
CheckHit(); CheckHit();
this.Events["ActivateStrut"].guiActiveEditor = false; this.Events["ActivateStrut"].guiActiveEditor = false;
this.Events["DeactivateStrut"].guiActiveEditor = true; this.Events["DeactivateStrut"].guiActiveEditor = true;
} }
   
[KSPEvent(guiActive = true, guiName = "Deactivate", active = false, guiActiveUnfocused = true, unfocusedRange = 2f)] [KSPEvent(guiActive = true, guiName = "Deactivate", active = false, guiActiveUnfocused = true, unfocusedRange = 2f)]
public void DeactivateStrut() public void DeactivateStrut()
{ {
IsEnabled = false; IsEnabled = false;
CheckHit(); CheckHit();
this.Events["ActivateStrut"].guiActiveEditor = true; this.Events["ActivateStrut"].guiActiveEditor = true;
this.Events["DeactivateStrut"].guiActiveEditor = false; this.Events["DeactivateStrut"].guiActiveEditor = false;
} }
   
#endregion #endregion
   
public Material material = null; public Material material = null;
public Color startColor = Color.white; public Color startColor = Color.white;
public Color endColor = Color.white; public Color endColor = Color.white;
   
public Color Vector3toColor(Vector3 vec) public Color Vector3toColor(Vector3 vec)
{ {
return new Color(vec.x / 255, vec.y / 255, vec.z / 255); return new Color(vec.x / 255, vec.y / 255, vec.z / 255);
} }
   
Transform getTransform() Transform getTransform()
{ {
if (TransformName == "") if (TransformName == "")
return part.transform; return part.transform;
else else
return part.FindModelTransform(TransformName); return part.FindModelTransform(TransformName);
} }
   
public void print(object body, params object[] args) public void print(object body, params object[] args)
{ {
string final = body.ToString(); string final = body.ToString();
for (int I = 0; I < args.Length; I++) for (int I = 0; I < args.Length; I++)
{ {
final = final.Replace("{" + I + "}", args[I].ToString()); final = final.Replace("{" + I + "}", args[I].ToString());
} }
MonoBehaviour.print("[AutoStrut] " + final); MonoBehaviour.print("[AutoStrut] " + final);
} }
   
public override void OnLoad(ConfigNode node) public override void OnLoad(ConfigNode node)
{ {
base.OnLoad(node); base.OnLoad(node);
} }
   
public override void OnActive() public override void OnActive()
{ {
InitLaser(); InitLaser();
   
base.OnActive(); base.OnActive();
} }
   
public override void OnInactive() public override void OnInactive()
{ {
DestroyLaser(); DestroyLaser();
   
base.OnInactive(); base.OnInactive();
} }
   
public override string GetInfo() public override string GetInfo()
{ {
return "Requires:\n- ElectricCharge (" + PowerConsumption + "/s.)\n\n Costs 5 to create strut."; return "Requires:\n- ElectricCharge (" + PowerConsumption + "/s.)\n\n Costs 5 to create strut.";
} }
   
public override void OnStart(PartModule.StartState state) public override void OnStart(PartModule.StartState state)
{ {
try try
{ {
print("Material: {0}", Material); print("Material: {0}", Material);
material = new Material(Shader.Find(Material.Trim())); material = new Material(Shader.Find(Material.Trim()));
} }
catch catch
{ {
material = null; material = null;
} }
   
base.stagingEnabled = false; base.stagingEnabled = false;
   
startColor = Vector3toColor(StartColor); startColor = Vector3toColor(StartColor);
endColor = Vector3toColor(EndColor); endColor = Vector3toColor(EndColor);
   
if (!Util.isValid(LaserMaterial)) if (!Util.isValid(LaserMaterial))
LaserMaterial = new Material(Shader.Find("Particles/Additive")); LaserMaterial = new Material(Shader.Find("Particles/Additive"));
switch (state) switch (state)
{ {
case StartState.Editor: case StartState.Editor:
InitLaser(); InitLaser();
break; break;
case StartState.Docked: case StartState.Docked:
CheckHit(); CheckHit();
DestroyLaser(); DestroyLaser();
break; break;
default: default:
DestroyLaser(); DestroyLaser();
break; break;
} }
   
base.OnStart(state); base.OnStart(state);
} }
   
public override bool IsStageable() public override bool IsStageable()
{ {
return false; return false;
} }
   
  public void Update()
  {
  if (strut != null && !strut.isDestroyed)
  {
  if (PowerConsumption == 0 || (Util.GetEnergy(part.vessel) > PowerConsumption * TimeWarp.fixedDeltaTime && part.RequestResource(
  "ElectricCharge",
  PowerConsumption * TimeWarp.fixedDeltaTime
  ) > 0))
  {
  strut.Update();
  }
  else
  {
  strut.Destroy();
  }
  }
  }
   
public void FixedUpdate() public void FixedUpdate()
{ {
Events["ActivateStrut"].guiActiveEditor = Events["ActivateStrut"].active = !IsEnabled; Events["ActivateStrut"].guiActiveEditor = Events["ActivateStrut"].active = !IsEnabled;
Events["DeactivateStrut"].guiActiveEditor = Events["DeactivateStrut"].active = IsEnabled; Events["DeactivateStrut"].guiActiveEditor = Events["DeactivateStrut"].active = IsEnabled;
   
if (IsEnabled) if (IsEnabled)
{ {
I = I + 1 % 255; I = I + 1 % 255;
   
if (strut != null && !strut.isDestroyed) if (strut == null || strut.isDestroyed)
{  
if (PowerConsumption == 0 || (Util.GetEnergy(part.vessel) > PowerConsumption * TimeWarp.fixedDeltaTime && part.RequestResource(  
"ElectricCharge",  
PowerConsumption * TimeWarp.fixedDeltaTime  
) > 0))  
strut.Update();  
else  
strut.Destroy();  
}  
else  
{ {
if ((I % 10) == 0) if ((I % 10) == 0)
{ {
CheckHit(); CheckHit();
} }
} }
} }
else else
{ {
if (strut != null) if (strut != null)
{ {
strut.Destroy(); strut.Destroy();
strut = null; strut = null;
} }
} }
   
base.OnUpdate(); base.OnUpdate();
} }
   
public void OnGUI() public void OnGUI()
{ {
if (HighLogic.LoadedSceneIsEditor && Util.isValid(part)) if (HighLogic.LoadedSceneIsEditor && Util.isValid(part))
{ {
this.DrawBuildOverlay(); this.DrawBuildOverlay();
} }
else else
{ {
DestroyLaser(); DestroyLaser();
} }
} }
   
public void OnDestroy() public void OnDestroy()
{ {
DestroyLaser(); DestroyLaser();
} }
   
void CheckHit() void CheckHit()
{ {
if (HighLogic.LoadedSceneIsEditor) if (HighLogic.LoadedSceneIsEditor)
{ {
Logging.PostDebugMessage(this, "Checking bailing out: in the editor!"); Logging.PostDebugMessage(this, "Checking bailing out: in the editor!");
return; return;
} }
   
if (!isEnabled) if (!isEnabled)
{ {
Logging.PostDebugMessage(this, "Destroying strut."); Logging.PostDebugMessage(this, "Destroying strut.");
   
strut.Destroy(); strut.Destroy();
strut = null; strut = null;
return; return;
} }
   
Logging.PostDebugMessage(this, "Checking for ray hit."); Logging.PostDebugMessage(this, "Checking for ray hit.");
   
Logging.PostDebugMessage(this, "Enabled, continuing."); Logging.PostDebugMessage(this, "Enabled, continuing.");
   
if (strut == null || strut.isDestroyed) if (strut == null || strut.isDestroyed)
{ {
Logging.PostDebugMessage(this, "strut is {0}", strut == null ? "null" : strut.isDestroyed.ToString()); Logging.PostDebugMessage(this, "strut is {0}", strut == null ? "null" : strut.isDestroyed.ToString());
   
Vector3 dir = getTransform().TransformDirection(Dir); Vector3 dir = getTransform().TransformDirection(Dir);
Vector3 start = getTransform().TransformPoint(Start); Vector3 start = getTransform().TransformPoint(Start);
   
Logging.PostDebugMessage(this, "Got transforms. Checking for raycast hit."); Logging.PostDebugMessage(this, "Got transforms. Checking for raycast hit.");
   
UnityEngine.RaycastHit info = new RaycastHit(); UnityEngine.RaycastHit info = new RaycastHit();
bool hit = Physics.Raycast(new UnityEngine.Ray(start + (dir * 0.05f), dir), out info, MaxStrutLength); bool hit = Physics.Raycast(new UnityEngine.Ray(start + (dir * 0.05f), dir), out info, MaxStrutLength);
   
if (hit) if (hit)
{ {
Logging.PostDebugMessage(this, "Found raycast hit. Fetching target part."); Logging.PostDebugMessage(this, "Found raycast hit. Fetching target part.");
   
Part targetPart = Util.partFromRaycast(info); Part targetPart = Util.partFromRaycast(info);
   
Logging.PostDebugMessage(this, Logging.PostDebugMessage(this,
"Found target part {0} on {1}.", "Found target part {0} on {1}.",
targetPart.partName, targetPart.partName,
targetPart.vessel == null ? "null vessel" : targetPart.vessel.vesselName targetPart.vessel == null ? "null vessel" : targetPart.vessel.vesselName
); );
   
if ( if (
targetPart && vessel.parts.Contains(targetPart) && targetPart && vessel.parts.Contains(targetPart) &&
Util.GetEnergy(part.vessel) > 5 * TimeWarp.fixedDeltaTime Util.GetEnergy(part.vessel) > 5 * TimeWarp.fixedDeltaTime
) )
{ {
Logging.PostDebugMessage(this, "Target part is in our vessel and we have the energy to continue."); Logging.PostDebugMessage(this, "Target part is in our vessel and we have the energy to continue.");
   
strut = new Strut( strut = new Strut(
part, part,
targetPart, targetPart,
targetPart.transform.InverseTransformPoint(info.point), targetPart.transform.InverseTransformPoint(info.point),
getTransform() getTransform()
); );
   
Logging.PostDebugMessage(this, "Built a new strut, setting material, colors, and sizes."); Logging.PostDebugMessage(this, "Built a new strut, setting material, colors, and sizes.");
   
strut.Material = material; strut.Material = material;
strut.StartColor = startColor; strut.StartColor = startColor;
strut.EndColor = endColor; strut.EndColor = endColor;
strut.StartSize = StartSize; strut.StartSize = StartSize;
strut.EndSize = EndSize; strut.EndSize = EndSize;
   
Logging.PostDebugMessage(this, "Strut all done!"); Logging.PostDebugMessage(this, "Strut all done!");
} }
} }
} }
} }
   
void InitLaser() void InitLaser()
{ {
if (!Util.isValid(lr)) if (!Util.isValid(lr))
{ {
lineObj = new GameObject(); lineObj = new GameObject();
   
lr = lineObj.AddComponent<LineRenderer>(); lr = lineObj.AddComponent<LineRenderer>();
lr.useWorldSpace = true; lr.useWorldSpace = false;
   
lr.material = material; lr.material = material;
lr.SetColors(startColor, endColor); lr.SetColors(startColor, endColor);
lr.SetWidth(StartSize, EndSize); lr.SetWidth(StartSize, EndSize);
   
lr.SetVertexCount(2); lr.SetVertexCount(2);
lr.SetPosition(0, Vector3.zero); lr.SetPosition(0, Vector3.zero);
lr.SetPosition(1, Vector3.zero); lr.SetPosition(1, Vector3.zero);
lr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; lr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
lr.receiveShadows = true; lr.receiveShadows = true;
} }
} }
   
void DestroyLaser() void DestroyLaser()
{ {
if (Util.isValid(lr)) if (Util.isValid(lr))
LineRenderer.DestroyImmediate(lr); LineRenderer.DestroyImmediate(lr);
   
if (Util.isValid(lineObj)) if (Util.isValid(lineObj))
GameObject.DestroyImmediate(lineObj); GameObject.DestroyImmediate(lineObj);
} }
   
public void DrawBuildOverlay() public void DrawBuildOverlay()
{ {
if (Util.isValid(lr)) if (Util.isValid(lr))
{ {
Vector3 dir = getTransform().TransformDirection(Dir); Vector3 dir = getTransform().TransformDirection(Dir);
Vector3 start = getTransform().TransformPoint(Start); Vector3 start = getTransform().TransformPoint(Start);
   
UnityEngine.RaycastHit info = new RaycastHit(); UnityEngine.RaycastHit info = new RaycastHit();
bool hit = Physics.Raycast(new UnityEngine.Ray(start + (dir * 0.05f), dir), out info, MaxStrutLength); bool hit = Physics.Raycast(new UnityEngine.Ray(start + (dir * 0.05f), dir), out info, MaxStrutLength);
if (hit && IsEnabled) if (hit && IsEnabled)
{ {
if (Util.isValid(material)) if (Util.isValid(material))
lr.material = material; lr.material = material;
   
lr.SetColors(startColor, endColor); lr.SetColors(startColor, endColor);
lr.SetWidth(StartSize, EndSize); lr.SetWidth(StartSize, EndSize);
   
lr.SetPosition(0, start); lr.SetPosition(0, start);
lr.SetPosition(1, info.point); lr.SetPosition(1, info.point);
} }
else else
{ {
lr.material = LaserMaterial; lr.material = LaserMaterial;
lr.SetColors(Color.red, Color.red); lr.SetColors(Color.red, Color.red);
lr.SetWidth(0.01f, 0.01f); lr.SetWidth(0.01f, 0.01f);
   
lr.SetPosition(0, start); lr.SetPosition(0, start);
lr.SetPosition(1, start + (dir * MaxStrutLength)); lr.SetPosition(1, start + (dir * MaxStrutLength));
} }
} }
} }
} }
} }
file:a/Strut.cs -> file:b/Strut.cs
// QuantumStrutsContinued // QuantumStrutsContinued
// //
// Strut.cs // Strut.cs
// //
// Continued from QuantumStruts by BoJaN. Used by permission. // Continued from QuantumStruts by BoJaN. Used by permission.
// //
// ModuleManager patches © 2014 K3|Chris. Used by permission. // ModuleManager patches © 2014 K3|Chris. Used by permission.
// //
// Copyright © 2014, toadicus // Copyright © 2014, toadicus
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met: // are permitted provided that the following conditions are met:
// //
// 1. Redistributions of source code must retain the above copyright notice, // 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// //
// 2. Redistributions in binary form must reproduce the above copyright notice, // 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation and/or other // this list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution. // materials provided with the distribution.
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
using KSP; using KSP;
using System; using System;
using UnityEngine; using UnityEngine;
   
namespace QuantumStrut namespace QuantumStrut
{ {
class Strut class Strut
{ {
public bool isDestroyed = false; public bool isDestroyed = false;
Material _material = null; Material _material = null;
   
public Material Material public Material Material
{ {
set set
{ {
_material = value; _material = value;
if (Material != null) if (Material != null)
lr.material = Material; lr.material = Material;
} }
get get
{ {
return _material; return _material;
} }
} }
   
Color _startColor = Color.white; Color _startColor = Color.white;
   
public Color StartColor public Color StartColor
{ {
set set
{ {
_startColor = value; _startColor = value;
lr.SetColors(StartColor, EndColor); lr.SetColors(StartColor, EndColor);
} }
get get
{ {
return _startColor; return _startColor;
} }
} }
   
Color _endColor = Color.white; Color _endColor = Color.white;
   
public Color EndColor public Color EndColor
{ {
set set
{ {
_endColor = value; _endColor = value;
lr.SetColors(StartColor, EndColor); lr.SetColors(StartColor, EndColor);
} }
get get
{ {
return _endColor; return _endColor;
} }
} }
   
float _startSize = 0; float _startSize = 0;
   
public float StartSize public float StartSize
{ {
set set
{ {
_startSize = value; _startSize = value;
lr.SetWidth(StartSize, EndSize); lr.SetWidth(StartSize, EndSize);
} }
get get
{ {
return _startSize; return _startSize;
} }
} }
   
float _endSize = 0; float _endSize = 0;
   
public float EndSize public float EndSize
{ {
set set
{ {
_endSize = value; _endSize = value;
lr.SetWidth(StartSize, EndSize); lr.SetWidth(StartSize, EndSize);
} }
get get
{ {
return _endSize; return _endSize;
} }
} }
   
ConfigurableJoint joint; ConfigurableJoint joint;
Transform parentTransform = null; Transform parentTransform = null;
Part parent = null; Part parent = null;
Part target = null; Part target = null;
Vector3 targetOffset = Vector3.zero; Vector3 targetOffset = Vector3.zero;
GameObject LineObj = null; GameObject LineObj = null;
LineRenderer lr = null; LineRenderer lr = null;
   
public void print(object body, params object[] args) public void print(object body, params object[] args)
{ {
string final = body.ToString(); string final = body.ToString();
for (int I = 0; I < args.Length; I++) for (int I = 0; I < args.Length; I++)
{ {
final = final.Replace("{" + I + "}", args[I].ToString()); final = final.Replace("{" + I + "}", args[I].ToString());
} }
MonoBehaviour.print("[AutoStrut] " + final); MonoBehaviour.print("[AutoStrut] " + final);
} }
   
void DrawLine(Vector3 origin, Vector3 end) void DrawLine(Vector3 origin, Vector3 end)
{ {
if (Util.isValid(lr)) if (Util.isValid(lr))
{ {
lr.SetPosition(0, origin); lr.SetPosition(0, origin);
lr.SetPosition(1, end); lr.SetPosition(1, end);
} }
} }
   
public Strut(Part parent, Part target, Vector3 targetOffset, Transform parentTransform) public Strut(Part parent, Part target, Vector3 targetOffset, Transform parentTransform)
{ {
this.parent = parent; this.parent = parent;
this.target = target; this.target = target;
this.targetOffset = targetOffset; this.targetOffset = targetOffset;
this.parentTransform = parentTransform; this.parentTransform = parentTransform;
   
if (parent.vessel.parts.Contains(target)) if (parent.vessel.parts.Contains(target))
{ {
joint = parent.parent.gameObject.AddComponent<ConfigurableJoint>(); joint = parent.parent.gameObject.AddComponent<ConfigurableJoint>();
joint.connectedBody = target.Rigidbody; joint.connectedBody = target.Rigidbody;
   
joint.anchor = new Vector3( joint.anchor = new Vector3(
0, 0,
0, 0,
Vector3.Distance( Vector3.Distance(
parentTransform.position, parentTransform.position,
target.transform.TransformPoint(targetOffset) target.transform.TransformPoint(targetOffset)
) / 2 ) / 2
); );
joint.axis = new Vector3(0, 0, 1); joint.axis = new Vector3(0, 0, 1);
joint.xMotion = ConfigurableJointMotion.Locked; joint.xMotion = ConfigurableJointMotion.Locked;
joint.yMotion = ConfigurableJointMotion.Locked; joint.yMotion = ConfigurableJointMotion.Locked;
joint.zMotion = ConfigurableJointMotion.Locked; joint.zMotion = ConfigurableJointMotion.Locked;
joint.angularXMotion = ConfigurableJointMotion.Locked; joint.angularXMotion = ConfigurableJointMotion.Locked;
joint.angularYMotion = ConfigurableJointMotion.Locked; joint.angularYMotion = ConfigurableJointMotion.Locked;
joint.angularZMotion = ConfigurableJointMotion.Locked; joint.angularZMotion = ConfigurableJointMotion.Locked;
   
LineObj = new GameObject(); LineObj = new GameObject();
LineObj.name = "quantumstrut"; LineObj.name = "quantumstrut";
   
lr = LineObj.AddComponent<LineRenderer>(); lr = LineObj.AddComponent<LineRenderer>();
lr.useWorldSpace = true; lr.useWorldSpace = false;
   
Material = QuantumStrut.LaserMaterial; Material = QuantumStrut.LaserMaterial;
StartColor = Color.white; StartColor = Color.white;
EndColor = Color.white; EndColor = Color.white;
StartSize = 0.03f; StartSize = 0.03f;
EndSize = 0.0075f; EndSize = 0.0075f;
   
lr.SetVertexCount(2); lr.SetVertexCount(2);
lr.SetPosition(0, Vector3.zero); lr.SetPosition(0, Vector3.zero);
lr.SetPosition(1, Vector3.zero); lr.SetPosition(1, Vector3.zero);
} }
else else
{ {
Destroy(); Destroy();
} }
} }
   
public void Update() public void Update()
{ {
if (Util.isValid(parent) && Util.isValid(target) && Util.isValid(parent.vessel) && parent.vessel.parts.Contains(target)) if (Util.isValid(parent) && Util.isValid(target) && Util.isValid(parent.vessel) && parent.vessel.parts.Contains(target))
{ {
Vector3 start = parentTransform.position; Vector3 start = parentTransform.position;
Vector3 end = target.transform.TransformPoint(targetOffset); Vector3 end = target.transform.TransformPoint(targetOffset);
DrawLine(start, end); DrawLine(start, end);
} }
else else
{ {
DrawLine(Vector3.zero, Vector3.zero); DrawLine(Vector3.zero, Vector3.zero);
Destroy(); Destroy();
} }
} }
   
public void Destroy() public void Destroy()
{ {
DrawLine(Vector3.zero, Vector3.zero); DrawLine(Vector3.zero, Vector3.zero);
if (Util.isValid(joint)) if (Util.isValid(joint))
GameObject.DestroyImmediate(joint); GameObject.DestroyImmediate(joint);
   
if (Util.isValid(lr)) if (Util.isValid(lr))
GameObject.DestroyImmediate(lr); GameObject.DestroyImmediate(lr);
   
if (Util.isValid(LineObj)) if (Util.isValid(LineObj))
GameObject.DestroyImmediate(LineObj); GameObject.DestroyImmediate(LineObj);
   
joint = null; joint = null;
LineObj = null; LineObj = null;
lr = null; lr = null;
   
parentTransform = null; parentTransform = null;
parent = null; parent = null;
target = null; target = null;
targetOffset = Vector3.zero; targetOffset = Vector3.zero;
isDestroyed = true; isDestroyed = true;
} }
} }
} }