Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Superglue #10

Merged
merged 13 commits into from
Sep 16, 2021
140 changes: 140 additions & 0 deletions Source/Welding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Based on the https://github.com/UmbraSpaceIndustries/Konstruction/tree/master/Source/Konstruction/Konstruction/Welding
// GPLV3

using System;
using UnityEngine;

namespace Kaboom
{

public class Welding
{
Vessel vessel;
Part part;
public Welding(Vessel vessel, Part part)
{
this.vessel = vessel;
this.part = part;
}

public bool MergeParts(bool compress)
{
if (vessel.rootPart == part)
{
ScreenMessages.PostScreenMessage("You cannot weld the root part!");
return false;
}

var wData = LoadWeldingData();
if (wData == null)
return false;

bool sucess = PerformWeld(wData, compress);
return sucess;
}

public WeldingData LoadWeldingData()
{
/**********************
*
* (root)-...-LPA==KGP==LPB
*
* LPA==LPB
*
**********************/

var wData = new WeldingData();
wData.KaboomGluedPart = part;

int attachedPartsCount = 0;
foreach (var n in part.attachNodes)
if (n.attachedPart != null)
attachedPartsCount++;

//Debug.Log("attachedPartsCount: " + attachedPartsCount + " part.children.Count: " + part.children.Count);

if (attachedPartsCount == 2 && part.children.Count == 1)
{
wData.LinkedPartA = part.parent;
wData.LinkedPartB = part.children[0];
}

if (wData.LinkedPartA == null || wData.LinkedPartB == null)
{
ScreenMessages.PostScreenMessage("This part need to have 2 parts on attachment nodes");
return null;
}

if (wData.KaboomGluedPart == vessel.rootPart)
{
ScreenMessages.PostScreenMessage("This part is the root part! Cancelling");
return null;
}

return wData;
}


private Vector3 GetOffset(WeldingData wData)
yalov marked this conversation as resolved.
Show resolved Hide resolved
{
//Vector3 offset1 =
//nodeA.owner.transform.rotation * nodeA.position + nodeA.owner.transform.position -
//nodeB.owner.transform.rotation * nodeB.position + nodeB.owner.transform.position;
//Vector3 offset2 = wData.LinkedPartA.transform.localPosition - wData.LinkedPartB.transform.localPosition;
//offset2.Normalize();
//offset2 *= WeldingNodeUtilities.GetPartThickness(wData.KaboomGluedPart);

var nodeA = WeldingUtilities.GetLinkingNode(wData.KaboomGluedPart, wData.LinkedPartA);
var nodeB = WeldingUtilities.GetLinkingNode(wData.KaboomGluedPart, wData.LinkedPartB);

Vector3 offset = part.transform.rotation * (nodeA.position - nodeB.position);

return offset;
}



private bool PerformWeld(WeldingData wData, bool compress)
{
var nodeA = WeldingUtilities.GetLinkingNode(wData.LinkedPartA, wData.KaboomGluedPart);
var nodeB = WeldingUtilities.GetLinkingNode(wData.LinkedPartB, wData.KaboomGluedPart);

var offset = GetOffset(wData);

WeldingUtilities.DetachPart(wData.KaboomGluedPart);

WeldingUtilities.SwapLinks(
wData.LinkedPartA,
wData.KaboomGluedPart,
wData.LinkedPartB);

WeldingUtilities.SwapLinks(
wData.LinkedPartB,
wData.KaboomGluedPart,
wData.LinkedPartA);

wData.KaboomGluedPart.SetCollisionIgnores();

WeldingUtilities.SpawnStructures(wData.LinkedPartA, nodeA);
WeldingUtilities.SpawnStructures(wData.LinkedPartB, nodeB);

if (compress)
{
WeldingUtilities.MovePart(wData.LinkedPartB, offset);
}

PartJoint newJoint = PartJoint.Create(
wData.LinkedPartB,
wData.LinkedPartA,
nodeB,
nodeA,
AttachModes.STACK);

wData.LinkedPartB.attachJoint = newJoint;

WeldingUtilities.Explode(wData.KaboomGluedPart);

return true;
}
}
}
12 changes: 12 additions & 0 deletions Source/WeldingData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Based on the https://github.com/UmbraSpaceIndustries/Konstruction/tree/master/Source/Konstruction/Konstruction/Welding
// GPLV3

namespace Kaboom
{
public class WeldingData
{
public Part LinkedPartA { get; set; }
public Part LinkedPartB { get; set; }
public Part KaboomGluedPart { get; set; }
}
}
94 changes: 94 additions & 0 deletions Source/WeldingUtilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Based on the https://github.com/UmbraSpaceIndustries/Konstruction/tree/master/Source/Konstruction/Konstruction/Welding
// GPLV3

using System;
using System.Linq;
using UnityEngine;
//using USITools;

namespace Kaboom
{
public static class WeldingUtilities
{
public static void SpawnStructures(Part thisPart, AttachNode thisNode)
{
var structList = thisPart.FindModulesImplementing<ModuleStructuralNode>();
foreach (var s in structList.Where(s => s.attachNodeNames.Contains(thisNode.id)))
{
s.SpawnStructure();
}
}

public static void DetachPart(Part thisPart)
{
thisPart.parent = null;
thisPart.attachJoint.DestroyJoint();
thisPart.children.Clear();

foreach (var an in thisPart.attachNodes)
{
an.attachedPart = null;
}
thisPart.topNode.attachedPart = null;
}

public static void MovePart(Part thisPart, Vector3 offset)
{
if (thisPart.Rigidbody != null && thisPart.physicalSignificance == Part.PhysicalSignificance.FULL)
thisPart.transform.position += offset;

thisPart.UpdateOrgPosAndRot(thisPart.vessel.rootPart);

foreach (var p in thisPart.children)
MovePart(p, offset);
}


public static void SwapLinks(Part thisPart, Part oldPart, Part newPart)
{
if (thisPart.parent != null && thisPart.parent == oldPart)
thisPart.parent = newPart;

if(thisPart.topNode != null && thisPart.topNode.attachedPart == oldPart)
thisPart.topNode.attachedPart = newPart;

if (thisPart.attachJoint != null)
{
if (thisPart.attachJoint.Child == oldPart || thisPart.attachJoint.Parent == oldPart)
{
thisPart.attachJoint.DestroyJoint();
}
}

foreach (var an in thisPart.attachNodes.Where(an => an.attachedPart == oldPart))
{
an.attachedPart = newPart;
}

if (!thisPart.children.Contains(oldPart))
return;

thisPart.children.Remove(oldPart);
thisPart.children.Add(newPart);
}

public static float GetPartThickness(Part thisPart)
{
var diff = thisPart.attachNodes[0].position - thisPart.attachNodes[1].position;
return (diff).magnitude;
}

public static AttachNode GetLinkingNode(Part p1, Part p2)
{
return p1.attachNodes.FirstOrDefault(an => an.attachedPart == p2);
}

public static void Explode(Part thisPart)
{
if (HighLogic.CurrentGame.Parameters.CustomParams<KaboomSettings>().softExplode)
thisPart.explosionPotential = Math.Min(thisPart.explosionPotential, 0.1f);

thisPart.explode();
}
}
}
77 changes: 63 additions & 14 deletions source/Kaboom.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using KSP.Localization;

namespace Kaboom
{
/// <summary>
Expand All @@ -11,8 +8,8 @@ namespace Kaboom
public class ModuleKaboom : PartModule
{
[KSPField(isPersistant = true, guiActiveEditor = true, guiActive = true, guiName = "Kaboom delay",
groupDisplayName = "<color=red><b>Switch Safety Cover</b></color>", groupName = "Kaboom", groupStartCollapsed = true,
guiUnits = "Seconds"),
groupName = "Kaboom", groupStartCollapsed = true,
guiUnits = " Seconds"),
UI_FloatRange(minValue = 0f, maxValue = 30f, stepIncrement = 1f)]

public float delay = 0;
Expand All @@ -23,21 +20,54 @@ public class ModuleKaboom : PartModule
[KSPField(isPersistant = true)]
public double kaboomTime;

[KSPEvent(guiActive = true, guiActiveUnfocused = true, unfocusedRange = 5f, guiName = "Kaboom!", groupName = "Kaboom", active = true)]
[KSPField(isPersistant = true)]
public bool isGlued = false;

[KSPEvent(groupName = "Kaboom",
guiActive = true, guiActiveEditor = true, active = true, guiActiveUncommand = true)]
public void GluedEvent()
{
isGlued = !isGlued;
GUITextUpdate();
}

private void GUITextUpdate()
{
if (isGlued)
Events["GluedEvent"].guiName = "Superglue: " + Localizer.Format("#autoLOC_6001072")/*Enabled*/;
else
Events["GluedEvent"].guiName = "Superglue: " + Localizer.Format("#autoLOC_6001071")/*Disabled*/;
}

[KSPEvent(guiName = "Kaboom!", groupName = "Kaboom",
guiActive = true, guiActiveUnfocused = true, unfocusedRange = 5f, active = true, guiActiveUncommand = true)]
public void KaboomEvent()
{
KaboomIt();
}

[KSPEvent(guiActive = true, guiActiveUnfocused = true, unfocusedRange = 5f, guiName = "Cancel Kaboom!", groupName = "Kaboom", active = false)]
[KSPEvent(guiName = "Cancel Kaboom!", groupName = "Kaboom",
guiActive = true, guiActiveUnfocused = true, unfocusedRange = 5f, active = false, guiActiveUncommand = true)]
public void CancelKaboomEvent()
{
CancelKaboomIt();
}

[KSPAction("Kaboom!")]
public void KaboomAction(KSPActionParam param)
=> KaboomIt();
public void KaboomAction(KSPActionParam _) => KaboomIt();

public override void OnStart(StartState state)
{
base.OnStart(state);

if (HighLogic.CurrentGame.Parameters.CustomParams<KaboomSettings>().coloredPAW)
Fields["delay"].group.displayName = "<color=red>Kaboom Safety Cover</color>";
else
Fields["delay"].group.displayName = "Kaboom Safety Cover";

GUITextUpdate();

}

private void KaboomIt()
{
Expand All @@ -47,7 +77,9 @@ private void KaboomIt()

if (delay == 0)
{
part.explode();
bool success = Proceed();
if (!success)
CancelKaboomIt();
}
else
{
Expand All @@ -57,6 +89,21 @@ private void KaboomIt()
}
}

private bool Proceed()
{
if (isGlued)
{
var k = new Welding(vessel, part);
bool success = k.MergeParts(true);
return success;
}
else
{
WeldingUtilities.Explode(part);
return true;
}
}

private void CancelKaboomIt()
{
Events["CancelKaboomEvent"].active = false;
Expand All @@ -73,10 +120,12 @@ public override void OnUpdate()
if (Planetarium.GetUniversalTime() >= kaboomTime)
{
timerActive = false;
part.explode();
bool success = Proceed();
if (!success)
CancelKaboomIt();
}
}
base.OnUpdate();
//base.OnUpdate();
}
}
}
Loading