Skip to content

Commit

Permalink
Merge pull request #10 from yalov/Dev-KaboomSuperglue
Browse files Browse the repository at this point in the history
Superglue
  • Loading branch information
zer0Kerbal authored Sep 16, 2021
2 parents f252d65 + b4df189 commit 0ea9508
Show file tree
Hide file tree
Showing 5 changed files with 315 additions and 33 deletions.
137 changes: 137 additions & 0 deletions Source/Welding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// 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;
}

private 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)
{
//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);

AttachNode a = WeldingUtilities.GetLinkingNode(wData.KaboomGluedPart, wData.LinkedPartA);
AttachNode b = WeldingUtilities.GetLinkingNode(wData.KaboomGluedPart, wData.LinkedPartB);

Vector3 offset = part.transform.rotation * (a.position - b.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; }
}
}
93 changes: 93 additions & 0 deletions Source/WeldingUtilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// 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

0 comments on commit 0ea9508

Please sign in to comment.