Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/UltimateRope.cs
2026-02-21 16:45:37 +08:00

3245 lines
101 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class UltimateRope : MonoBehaviour
{
public enum ERopeType
{
Procedural = 0,
LinkedObjects = 1,
ImportBones = 2
}
public enum EAxis
{
MinusX = 0,
MinusY = 1,
MinusZ = 2,
X = 3,
Y = 4,
Z = 5
}
public enum EColliderType
{
None = 0,
Capsule = 1,
Box = 2
}
public enum ERopeExtensionMode
{
CoilRotationIncrement = 0,
LinearExtensionIncrement = 1
}
[Serializable]
public class RopeNode
{
public GameObject goNode;
public float fLength;
public float fTotalLength;
public int nNumLinks;
public int nTotalLinks;
public EColliderType eColliderType;
public int nColliderSkip;
public bool bFold;
public bool bIsCoil;
public bool bInitialOrientationInitialized;
public Vector3 v3InitialLocalPos;
public Quaternion qInitialLocalRot;
public Vector3 v3InitialLocalScale;
public bool m_bExtensionInitialized;
public int m_nExtensionLinkIn;
public int m_nExtensionLinkOut;
public float m_fExtensionRemainingLength;
public float m_fExtensionRemainderIn;
public float m_fExtensionRemainderOut;
public Vector3 m_v3LocalDirectionForward;
public Vector3 m_v3LocalDirectionUp;
public GameObject[] segmentLinks;
public ConfigurableJoint[] linkJoints;
public bool[] linkJointBreaksProcessed;
public bool bSegmentBroken;
public RopeNode()
{
goNode = null;
fLength = 5f;
fTotalLength = fLength;
nNumLinks = 20;
nTotalLinks = nNumLinks;
eColliderType = EColliderType.Capsule;
nColliderSkip = 1;
bFold = true;
bIsCoil = false;
bInitialOrientationInitialized = false;
linkJoints = new ConfigurableJoint[0];
linkJointBreaksProcessed = new bool[0];
bSegmentBroken = false;
}
}
[Serializable]
public class RopeBone
{
public GameObject goBone;
public Transform tfParent;
public Transform tfNonBoneParent;
public bool bCreatedCollider;
public bool bIsStatic;
public float fLength;
public bool bCreatedRigidbody;
public int nOriginalLayer;
public Vector3 v3OriginalLocalScale;
public Vector3 v3OriginalLocalPos;
public Quaternion qOriginalLocalRot;
public RopeBone()
{
goBone = null;
tfParent = null;
tfNonBoneParent = null;
bCreatedCollider = false;
bIsStatic = false;
fLength = 0f;
bCreatedRigidbody = false;
nOriginalLayer = 0;
}
}
public class RopeBreakEventInfo
{
public UltimateRope rope;
public GameObject link1;
public GameObject link2;
public Vector3 worldPos;
public Vector3 localLink1Pos;
public Vector3 localLink2Pos;
}
[RopePersist]
public ERopeType RopeType;
[RopePersist]
public GameObject RopeStart;
[RopePersist]
public List<RopeNode> RopeNodes;
[RopePersist]
public int RopeLayer;
[RopePersist]
public PhysicMaterial RopePhysicsMaterial;
[RopePersist]
public float RopeDiameter = 0.1f;
[RopePersist]
public float RopeDiameterScaleX = 1f;
[RopePersist]
public float RopeDiameterScaleY = 1f;
[RopePersist]
public int RopeSegmentSides = 8;
[RopePersist]
public Material RopeMaterial;
[RopePersist]
public float RopeTextureTileMeters = 1f;
[RopePersist]
public Material RopeSectionMaterial;
[RopePersist]
public float RopeTextureSectionTileMeters = 1f;
[RopePersist]
public bool IsExtensible;
[RopePersist]
public float ExtensibleLength = 10f;
[RopePersist]
public int PartToExtend = -1;
[RopePersist]
public bool HasACoil;
[RopePersist]
public GameObject CoilObject;
[RopePersist]
public EAxis CoilAxisRight = EAxis.X;
[RopePersist]
public EAxis CoilAxisUp = EAxis.Y;
[RopePersist]
public float CoilWidth = 0.5f;
[RopePersist]
public float CoilDiameter = 0.5f;
[RopePersist]
public int CoilNumBones = 50;
[RopePersist]
public GameObject LinkObject;
[RopePersist]
public EAxis LinkAxis = EAxis.Z;
[RopePersist]
public float LinkOffsetObject;
[RopePersist]
public float LinkTwistAngleStart;
[RopePersist]
public float LinkTwistAngleIncrement;
[RopePersist]
public GameObject BoneFirst;
[RopePersist]
public GameObject BoneLast;
[RopePersist]
public string BoneListNamesStatic;
[RopePersist]
public string BoneListNamesNoColliders;
[RopePersist]
public EAxis BoneAxis = EAxis.Z;
[RopePersist]
public EColliderType BoneColliderType = EColliderType.Capsule;
[RopePersist]
public float BoneColliderDiameter = 0.1f;
[RopePersist]
public int BoneColliderSkip;
[RopePersist]
public float BoneColliderLength = 1f;
[RopePersist]
public float BoneColliderOffset;
[RopePersist]
public float LinkMass = 1f;
[RopePersist]
public int LinkSolverIterationCount = 100;
[RopePersist]
public float LinkJointAngularXLimit = 30f;
[RopePersist]
public float LinkJointAngularYLimit = 30f;
[RopePersist]
public float LinkJointAngularZLimit = 30f;
[RopePersist]
public float LinkJointSpringValue = 1f;
[RopePersist]
public float LinkJointDamperValue;
[RopePersist]
public float LinkJointMaxForceValue = 1f;
[RopePersist]
public float LinkJointBreakForce = float.PositiveInfinity;
[RopePersist]
public float LinkJointBreakTorque = float.PositiveInfinity;
[RopePersist]
public bool LockStartEndInZAxis;
[RopePersist]
public bool SendEvents;
[RopePersist]
public GameObject EventsObjectReceiver;
[RopePersist]
public string OnBreakMethodName;
[RopePersist]
public bool PersistAfterPlayMode;
[RopePersist]
public bool EnablePrefabUsage;
[RopePersist]
public bool AutoRegenerate = true;
[RopePersist]
[HideInInspector]
public bool Deleted = true;
[RopePersist]
[HideInInspector]
public float[] LinkLengths;
[RopePersist]
[HideInInspector]
public int TotalLinks;
[RopePersist]
[HideInInspector]
public float TotalRopeLength;
[RopePersist]
[HideInInspector]
public bool m_bRopeStartInitialOrientationInitialized;
[HideInInspector]
[RopePersist]
public Vector3 m_v3InitialRopeStartLocalPos;
[RopePersist]
[HideInInspector]
public Quaternion m_qInitialRopeStartLocalRot;
[HideInInspector]
[RopePersist]
public Vector3 m_v3InitialRopeStartLocalScale;
[HideInInspector]
[RopePersist]
public int m_nFirstNonCoilNode;
[RopePersist]
[HideInInspector]
public float[] m_afCoilBoneRadiuses;
[RopePersist]
[HideInInspector]
public float[] m_afCoilBoneAngles;
[RopePersist]
[HideInInspector]
public float[] m_afCoilBoneX;
[RopePersist]
[HideInInspector]
public float m_fCurrentCoilRopeRadius;
[RopePersist]
[HideInInspector]
public float m_fCurrentCoilTurnsLeft;
[RopePersist]
[HideInInspector]
public float m_fCurrentCoilLength;
[RopePersist]
[HideInInspector]
public float m_fCurrentExtension;
[HideInInspector]
[RopePersist]
public float m_fCurrentExtensionInput;
[RopePersist]
[HideInInspector]
public RopeBone[] ImportedBones;
[RopePersist]
[HideInInspector]
public bool m_bBonesAreImported;
[HideInInspector]
[RopePersist]
public string m_strStatus;
[HideInInspector]
[RopePersist]
public bool m_bLastStatusIsError = true;
[HideInInspector]
[RopePersist]
public string m_strAssetFile = string.Empty;
public SkinnedMeshRenderer mySkin;
[HideInInspector]
public string Status
{
get
{
return m_strStatus;
}
set
{
m_strStatus = value;
}
}
private void Awake()
{
if (Application.isPlaying)
{
CreateRopeJoints(true);
SetupRopeLinks();
if (FirstNodeIsCoil())
{
RecomputeCoil();
}
}
}
private void Start()
{
m_fCurrentExtensionInput = m_fCurrentExtension;
mySkin = base.gameObject.GetComponent<SkinnedMeshRenderer>();
}
public void UpdateRopeVisuals()
{
if (!(mySkin == null))
{
}
}
public Transform GetLookAtNode()
{
if (RopeNodes[0].m_nExtensionLinkIn >= mySkin.bones.Length - 4)
{
return null;
}
return mySkin.bones[RopeNodes[0].m_nExtensionLinkIn + 4].transform;
}
private void OnGUI()
{
}
private void Update()
{
}
private void FixedUpdate()
{
if (RopeNodes == null || RopeNodes.Count == 0)
{
return;
}
int num = -1;
if (RopeType == ERopeType.Procedural && (LinkJointBreakForce != float.PositiveInfinity || LinkJointBreakTorque != float.PositiveInfinity))
{
SkinnedMeshRenderer component = base.gameObject.GetComponent<SkinnedMeshRenderer>();
if (component == null)
{
return;
}
Mesh sharedMesh = component.sharedMesh;
int[] indices = null;
int[] indices2 = null;
int num2 = 0;
for (int i = 0; i < RopeNodes.Count; i++)
{
RopeNode ropeNode = RopeNodes[i];
if (ropeNode.bIsCoil)
{
num2 += ropeNode.segmentLinks.Length;
continue;
}
for (int j = 0; j < ropeNode.linkJoints.Length; j++)
{
if (ropeNode.linkJoints[j] == null && !ropeNode.linkJointBreaksProcessed[j])
{
bool flag = i == 0 && j == 0 && !FirstNodeIsCoil();
bool flag2 = i == RopeNodes.Count - 1 && j == ropeNode.linkJoints.Length - 1;
if (!flag && !flag2)
{
indices = sharedMesh.GetTriangles(0);
indices2 = sharedMesh.GetTriangles(1);
break;
}
}
}
if (indices != null && indices2 != null)
{
break;
}
}
for (int k = 0; k < RopeNodes.Count; k++)
{
RopeNode ropeNode2 = RopeNodes[k];
if (ropeNode2.bIsCoil)
{
num2 += ropeNode2.segmentLinks.Length;
continue;
}
for (int l = 0; l < ropeNode2.linkJoints.Length; l++)
{
if (ropeNode2.linkJoints[l] == null && !ropeNode2.linkJointBreaksProcessed[l])
{
ropeNode2.linkJointBreaksProcessed[l] = true;
bool flag3 = k == 0 && l == 0 && !FirstNodeIsCoil();
bool flag4 = k == RopeNodes.Count - 1 && l == ropeNode2.linkJoints.Length - 1;
if (!flag3 && !flag4)
{
FillLinkMeshIndicesRope(num2 - 1, TotalLinks, ref indices, true, true);
FillLinkMeshIndicesSections(num2 - 1, TotalLinks, ref indices2, true, true);
num = k;
}
if (SendEvents && EventsObjectReceiver != null && OnBreakMethodName.Length > 0)
{
RopeBreakEventInfo ropeBreakEventInfo = new RopeBreakEventInfo();
ropeBreakEventInfo.rope = this;
ropeBreakEventInfo.worldPos = ((l != ropeNode2.linkJoints.Length - 1) ? ropeNode2.segmentLinks[l].transform.position : ropeNode2.goNode.transform.position);
ropeBreakEventInfo.link2 = ((l != ropeNode2.linkJoints.Length - 1) ? ropeNode2.segmentLinks[l] : ropeNode2.goNode);
ropeBreakEventInfo.localLink2Pos = Vector3.zero;
if (flag3)
{
ropeBreakEventInfo.link1 = RopeStart.gameObject;
ropeBreakEventInfo.localLink1Pos = Vector3.zero;
}
else
{
if (l > 0)
{
ropeBreakEventInfo.link1 = ropeNode2.segmentLinks[l - 1];
}
else
{
ropeBreakEventInfo.link1 = RopeNodes[k - 1].goNode;
}
ropeBreakEventInfo.localLink1Pos = GetLinkAxisOffset(LinkLengths[num2 - 1]);
}
EventsObjectReceiver.SendMessage(OnBreakMethodName, ropeBreakEventInfo);
}
}
if (l < ropeNode2.segmentLinks.Length)
{
num2++;
}
}
}
if (num != -1)
{
sharedMesh.SetTriangles(indices, 0);
sharedMesh.SetTriangles(indices2, 1);
Vector4[] array = null;
if (sharedMesh.tangents != null && sharedMesh.tangents.Length == sharedMesh.vertexCount)
{
array = sharedMesh.tangents;
}
sharedMesh.RecalculateNormals();
if (array != null)
{
sharedMesh.tangents = array;
}
}
}
else if (RopeType == ERopeType.LinkedObjects && (LinkJointBreakForce != float.PositiveInfinity || LinkJointBreakTorque != float.PositiveInfinity) && SendEvents)
{
int num3 = 0;
for (int m = 0; m < RopeNodes.Count; m++)
{
RopeNode ropeNode3 = RopeNodes[m];
if (ropeNode3.bIsCoil)
{
num3 += ropeNode3.segmentLinks.Length;
continue;
}
for (int n = 0; n < ropeNode3.linkJoints.Length; n++)
{
if (ropeNode3.linkJoints[n] == null && !ropeNode3.linkJointBreaksProcessed[n])
{
ropeNode3.linkJointBreaksProcessed[n] = true;
bool flag5 = m == 0 && n == 0 && !FirstNodeIsCoil();
num = m;
if (SendEvents && EventsObjectReceiver != null && OnBreakMethodName.Length > 0)
{
RopeBreakEventInfo ropeBreakEventInfo2 = new RopeBreakEventInfo();
ropeBreakEventInfo2.rope = this;
ropeBreakEventInfo2.worldPos = ((n != ropeNode3.linkJoints.Length - 1) ? ropeNode3.segmentLinks[n].transform.position : ropeNode3.goNode.transform.position);
ropeBreakEventInfo2.link2 = ((n != ropeNode3.linkJoints.Length - 1) ? ropeNode3.segmentLinks[n] : ropeNode3.goNode);
ropeBreakEventInfo2.localLink2Pos = Vector3.zero;
if (flag5)
{
ropeBreakEventInfo2.link1 = RopeStart.gameObject;
ropeBreakEventInfo2.localLink1Pos = Vector3.zero;
}
else
{
if (n > 0)
{
ropeBreakEventInfo2.link1 = ropeNode3.segmentLinks[n - 1];
}
else
{
ropeBreakEventInfo2.link1 = RopeNodes[m - 1].goNode;
}
ropeBreakEventInfo2.localLink1Pos = GetLinkAxisOffset(LinkLengths[num3 - 1]);
}
EventsObjectReceiver.SendMessage(OnBreakMethodName, ropeBreakEventInfo2);
}
}
if (n < ropeNode3.segmentLinks.Length)
{
num3++;
}
}
}
}
if (num == -1)
{
return;
}
RopeNode ropeNode4 = RopeNodes[num];
ropeNode4.bSegmentBroken = true;
for (int num4 = 0; num4 < ropeNode4.linkJoints.Length; num4++)
{
if (ropeNode4.linkJoints[num4] != null)
{
ropeNode4.linkJoints[num4].breakForce = float.PositiveInfinity;
ropeNode4.linkJoints[num4].breakTorque = float.PositiveInfinity;
}
}
}
public void DeleteRope(bool bResetNodePositions = false, bool bDestroySkin = true)
{
DeleteRopeLinks();
foreach (RopeNode ropeNode in RopeNodes)
{
ropeNode.bSegmentBroken = false;
if (ropeNode.bInitialOrientationInitialized && bResetNodePositions)
{
ropeNode.goNode.transform.localPosition = ropeNode.v3InitialLocalPos;
ropeNode.goNode.transform.localRotation = ropeNode.qInitialLocalRot;
ropeNode.goNode.transform.localScale = ropeNode.v3InitialLocalScale;
}
ropeNode.bInitialOrientationInitialized = false;
for (int i = 0; i < ropeNode.linkJoints.Length; i++)
{
if (ropeNode.linkJoints[i] != null)
{
UnityEngine.Object.DestroyImmediate(ropeNode.linkJoints[i]);
}
}
}
if (RopeStart != null && m_bRopeStartInitialOrientationInitialized && bResetNodePositions)
{
RopeStart.transform.localPosition = m_v3InitialRopeStartLocalPos;
RopeStart.transform.localRotation = m_qInitialRopeStartLocalRot;
RopeStart.transform.localScale = m_v3InitialRopeStartLocalScale;
}
m_bRopeStartInitialOrientationInitialized = false;
if (ImportedBones != null)
{
RopeBone[] importedBones = ImportedBones;
foreach (RopeBone ropeBone in importedBones)
{
if (ropeBone.goBone != null)
{
ropeBone.goBone.layer = ropeBone.nOriginalLayer;
if (ropeBone.bCreatedCollider && ropeBone.goBone.GetComponent<Collider>() != null)
{
UnityEngine.Object.DestroyImmediate(ropeBone.goBone.GetComponent<Collider>());
}
if (ropeBone.bCreatedRigidbody && ropeBone.goBone.GetComponent<Rigidbody>() != null)
{
UnityEngine.Object.DestroyImmediate(ropeBone.goBone.GetComponent<Rigidbody>());
}
}
}
RopeBone[] importedBones2 = ImportedBones;
foreach (RopeBone ropeBone2 in importedBones2)
{
if (ropeBone2.goBone != null)
{
if (ropeBone2.tfNonBoneParent != null)
{
ropeBone2.goBone.transform.parent = ropeBone2.tfNonBoneParent;
ropeBone2.goBone.transform.localPosition = ropeBone2.v3OriginalLocalPos;
ropeBone2.goBone.transform.localRotation = ropeBone2.qOriginalLocalRot;
}
ropeBone2.goBone.transform.parent = ropeBone2.tfParent;
ropeBone2.goBone.transform.localScale = ropeBone2.v3OriginalLocalScale;
}
}
}
if (!Application.isEditor || !Application.isPlaying)
{
ImportedBones = null;
}
SkinnedMeshRenderer component = GetComponent<SkinnedMeshRenderer>();
if ((bool)component)
{
UnityEngine.Object.DestroyImmediate(component.sharedMesh);
if (bDestroySkin)
{
UnityEngine.Object.DestroyImmediate(component);
}
}
CheckDelCoilNode();
Deleted = true;
}
public void DeleteRopeLinks()
{
if (m_bBonesAreImported)
{
return;
}
if (CoilObject != null)
{
for (int i = 0; i < CoilObject.transform.childCount; i++)
{
Transform child = CoilObject.transform.GetChild(i);
if (child.gameObject.GetComponent<UltimateRopeLink>() != null)
{
UnityEngine.Object.DestroyImmediate(child.gameObject);
i--;
}
}
}
if (RopeStart != null)
{
for (int j = 0; j < RopeStart.transform.childCount; j++)
{
Transform child2 = RopeStart.transform.GetChild(j);
if (child2.gameObject.GetComponent<UltimateRopeLink>() != null)
{
UnityEngine.Object.DestroyImmediate(child2.gameObject);
j--;
}
}
}
for (int k = 0; k < base.transform.childCount; k++)
{
Transform child3 = base.transform.GetChild(k);
if (child3.gameObject.GetComponent<UltimateRopeLink>() != null)
{
UnityEngine.Object.DestroyImmediate(child3.gameObject);
k--;
}
}
foreach (RopeNode ropeNode in RopeNodes)
{
if ((bool)ropeNode.goNode)
{
for (int l = 0; l < ropeNode.goNode.transform.childCount; l++)
{
Transform child4 = ropeNode.goNode.transform.GetChild(l);
if (child4.gameObject.GetComponent<UltimateRopeLink>() != null)
{
UnityEngine.Object.DestroyImmediate(child4.gameObject);
l--;
}
}
}
ropeNode.segmentLinks = null;
}
}
public bool Regenerate(bool bResetNodePositions = false)
{
m_bLastStatusIsError = true;
DeleteRope(bResetNodePositions, false);
if (RopeType == ERopeType.Procedural || RopeType == ERopeType.LinkedObjects)
{
if (RopeStart == null)
{
Status = "A rope start GameObject needs to be specified";
return false;
}
if (RopeNodes == null)
{
Status = "At least a rope node needs to be added";
return false;
}
if (RopeNodes.Count == 0)
{
Status = "At least a rope node needs to be added";
return false;
}
if (RopeType == ERopeType.Procedural && IsExtensible && HasACoil && CoilObject == null)
{
Status = "A coil object needs to be specified";
return false;
}
if (RopeType == ERopeType.LinkedObjects && LinkObject == null)
{
Status = "A link object needs to be specified";
return false;
}
for (int i = 0; i < RopeNodes.Count; i++)
{
if (RopeNodes[i].goNode == null)
{
Status = string.Format("Rope segment {0} has unassigned Segment End property", i);
return false;
}
}
}
float realtimeSinceStartup = Time.realtimeSinceStartup;
List<RopeBone> outListImportedBones = null;
if (RopeType == ERopeType.ImportBones)
{
Status = string.Empty;
if (BoneFirst == null)
{
Status = "The first bone needs to be specified";
return false;
}
if (BoneLast == null)
{
Status = "The last bone needs to be specified";
return false;
}
List<int> outListBoneIndices;
string strErrorMessage;
if (!ParseBoneIndices(BoneListNamesStatic, out outListBoneIndices, out strErrorMessage))
{
Status = "Error parsing static bone list:\n" + strErrorMessage;
return false;
}
List<int> outListBoneIndices2;
if (!ParseBoneIndices(BoneListNamesNoColliders, out outListBoneIndices2, out strErrorMessage))
{
Status = "Error parsing collider bone list:\n" + strErrorMessage;
return false;
}
if (!BuildImportedBoneList(BoneFirst, BoneLast, outListBoneIndices, outListBoneIndices2, out outListImportedBones, out strErrorMessage))
{
Status = "Error building bone list:\n" + strErrorMessage;
return false;
}
}
base.gameObject.layer = RopeLayer;
CheckAddCoilNode();
if (!m_bRopeStartInitialOrientationInitialized && RopeStart != null)
{
m_v3InitialRopeStartLocalPos = RopeStart.transform.localPosition;
m_qInitialRopeStartLocalRot = RopeStart.transform.localRotation;
m_v3InitialRopeStartLocalScale = RopeStart.transform.localScale;
m_bRopeStartInitialOrientationInitialized = true;
}
if (RopeType == ERopeType.Procedural || RopeType == ERopeType.LinkedObjects)
{
TotalLinks = 0;
TotalRopeLength = 0f;
for (int j = 0; j < RopeNodes.Count; j++)
{
RopeNode ropeNode = RopeNodes[j];
if (!ropeNode.bInitialOrientationInitialized)
{
ropeNode.v3InitialLocalPos = ropeNode.goNode.transform.localPosition;
ropeNode.qInitialLocalRot = ropeNode.goNode.transform.localRotation;
ropeNode.v3InitialLocalScale = ropeNode.goNode.transform.localScale;
ropeNode.bInitialOrientationInitialized = true;
}
if (ropeNode.nNumLinks < 1)
{
ropeNode.nNumLinks = 1;
}
if (ropeNode.fLength < 0f)
{
ropeNode.fLength = 0.001f;
}
ropeNode.nTotalLinks = ropeNode.nNumLinks;
ropeNode.fTotalLength = ropeNode.fLength;
GameObject gameObject = null;
GameObject gameObject2 = null;
if (FirstNodeIsCoil() && j == 0)
{
gameObject = CoilObject;
gameObject2 = RopeStart;
}
else
{
gameObject = ((j != m_nFirstNonCoilNode) ? RopeNodes[j - 1].goNode : RopeStart);
gameObject2 = RopeNodes[j].goNode;
}
ropeNode.m_v3LocalDirectionForward = gameObject.transform.InverseTransformDirection((gameObject2.transform.position - gameObject.transform.position).normalized);
if (j == RopeNodes.Count - 1 && IsExtensible && ExtensibleLength > 0f)
{
ropeNode.nTotalLinks += (int)(ExtensibleLength / (ropeNode.fLength / (float)ropeNode.nNumLinks)) + 1;
ropeNode.fTotalLength += ExtensibleLength;
ropeNode.m_bExtensionInitialized = false;
ropeNode.m_nExtensionLinkIn = ropeNode.nTotalLinks - ropeNode.nNumLinks;
ropeNode.m_nExtensionLinkOut = ropeNode.m_nExtensionLinkIn - 1;
ropeNode.m_fExtensionRemainingLength = ExtensibleLength;
ropeNode.m_fExtensionRemainderIn = 0f;
ropeNode.m_fExtensionRemainderOut = 0f;
m_fCurrentExtension = 0f;
}
ropeNode.linkJoints = new ConfigurableJoint[ropeNode.nTotalLinks + 1];
ropeNode.linkJointBreaksProcessed = new bool[ropeNode.nTotalLinks + 1];
ropeNode.segmentLinks = new GameObject[ropeNode.nTotalLinks];
if (FirstNodeIsCoil() && j == 0)
{
for (int k = 0; k < ropeNode.segmentLinks.Length; k++)
{
string text = "Coil Link " + k;
ropeNode.segmentLinks[k] = new GameObject(text);
ropeNode.segmentLinks[k].AddComponent<UltimateRopeLink>();
ropeNode.segmentLinks[k].transform.parent = CoilObject.transform;
ropeNode.segmentLinks[k].layer = RopeLayer;
}
if (CoilDiameter < 0f)
{
CoilDiameter = 0f;
}
if (CoilWidth < 0f)
{
CoilWidth = 0f;
}
SetupCoilBones(ExtensibleLength);
}
else
{
float num = ropeNode.fLength / (float)ropeNode.nNumLinks;
float num2 = ((gameObject2.transform.position - gameObject.transform.position).magnitude - num) / (gameObject2.transform.position - gameObject.transform.position).magnitude;
float num3 = ((RopeType != ERopeType.LinkedObjects) ? 1f : GetLinkedObjectScale(ropeNode.fLength, ropeNode.nNumLinks));
for (int l = 0; l < ropeNode.segmentLinks.Length; l++)
{
float num4 = (float)l / ((ropeNode.segmentLinks.Length != 1) ? ((float)ropeNode.segmentLinks.Length - 1f) : 1f);
string text2 = "Node " + j + " Link " + l;
if (ropeNode.nTotalLinks > ropeNode.nNumLinks && l < ropeNode.nTotalLinks - ropeNode.nNumLinks)
{
text2 += " (extension)";
}
if (RopeType == ERopeType.Procedural)
{
ropeNode.segmentLinks[l] = new GameObject(text2);
}
else if (RopeType == ERopeType.LinkedObjects)
{
ropeNode.segmentLinks[l] = UnityEngine.Object.Instantiate(LinkObject);
ropeNode.segmentLinks[l].name = text2;
}
ropeNode.segmentLinks[l].AddComponent<UltimateRopeLink>();
if (Vector3.Distance(gameObject.transform.position, gameObject2.transform.position) < 0.001f)
{
ropeNode.segmentLinks[l].transform.position = gameObject.transform.position;
ropeNode.segmentLinks[l].transform.rotation = gameObject.transform.rotation;
}
else
{
ropeNode.segmentLinks[l].transform.position = Vector3.Lerp(gameObject.transform.position, gameObject2.transform.position, num4 * num2);
ropeNode.segmentLinks[l].transform.rotation = Quaternion.LookRotation((gameObject2.transform.position - gameObject.transform.position).normalized);
}
if (RopeType == ERopeType.LinkedObjects)
{
ropeNode.segmentLinks[l].transform.rotation *= GetLinkedObjectLocalRotation(LinkTwistAngleStart + LinkTwistAngleIncrement * (float)l);
ropeNode.segmentLinks[l].transform.localScale = new Vector3(num3, num3, num3);
}
if (ropeNode.segmentLinks[l].GetComponent<Rigidbody>() == null)
{
ropeNode.segmentLinks[l].AddComponent<Rigidbody>();
}
ropeNode.segmentLinks[l].transform.parent = base.transform;
ropeNode.segmentLinks[l].layer = RopeLayer;
}
}
TotalLinks += ropeNode.segmentLinks.Length;
TotalRopeLength += ropeNode.fTotalLength;
}
m_bBonesAreImported = false;
}
else if (RopeType == ERopeType.ImportBones)
{
TotalLinks = 0;
TotalRopeLength = 0f;
ImportedBones = outListImportedBones.ToArray();
bool flag = false;
if (RopeNodes != null && RopeNodes.Count != 0)
{
flag = true;
}
if (!flag)
{
RopeNodes = new List<RopeNode>();
RopeNodes.Add(new RopeNode());
}
RopeNode ropeNode2 = RopeNodes[0];
ropeNode2.nNumLinks = ImportedBones.Length;
ropeNode2.nTotalLinks = ropeNode2.nNumLinks;
ropeNode2.linkJoints = new ConfigurableJoint[ImportedBones.Length];
ropeNode2.linkJointBreaksProcessed = new bool[ImportedBones.Length];
ropeNode2.segmentLinks = new GameObject[ropeNode2.nTotalLinks];
int num5 = 0;
for (int m = 0; m < ImportedBones.Length; m++)
{
ropeNode2.segmentLinks[num5] = ImportedBones[m].goBone;
if (ImportedBones[m].goBone.GetComponent<Rigidbody>() == null)
{
ImportedBones[m].goBone.AddComponent<Rigidbody>();
ImportedBones[m].bCreatedRigidbody = true;
}
else
{
ImportedBones[m].bCreatedRigidbody = false;
}
ImportedBones[m].goBone.layer = RopeLayer;
float num6 = 0f;
num6 = ((num5 >= ImportedBones.Length - 1) ? 0f : Vector3.Distance(ImportedBones[m].goBone.transform.position, ImportedBones[m + 1].goBone.transform.position));
TotalLinks += ropeNode2.segmentLinks.Length;
TotalRopeLength += num6;
ImportedBones[m].fLength = num6;
num5++;
}
ropeNode2.fLength = TotalRopeLength;
ropeNode2.fTotalLength = ropeNode2.fLength;
ropeNode2.eColliderType = BoneColliderType;
ropeNode2.nColliderSkip = BoneColliderSkip;
m_bBonesAreImported = true;
}
if (RopeType == ERopeType.Procedural)
{
Transform[] array = new Transform[TotalLinks];
Matrix4x4[] array2 = new Matrix4x4[TotalLinks];
LinkLengths = new float[TotalLinks];
int num7 = 0;
for (int n = 0; n < RopeNodes.Count; n++)
{
RopeNode ropeNode3 = RopeNodes[n];
for (int num8 = 0; num8 < ropeNode3.segmentLinks.Length; num8++)
{
array[num7] = ropeNode3.segmentLinks[num8].transform;
array2[num7] = ropeNode3.segmentLinks[num8].transform.worldToLocalMatrix;
if (ropeNode3.segmentLinks[num8].transform.parent != null)
{
array2[num7] *= base.transform.localToWorldMatrix;
}
LinkLengths[num7] = ropeNode3.fLength / (float)ropeNode3.nNumLinks;
num7++;
}
}
if (RopeDiameter < 0.01f)
{
RopeDiameter = 0.01f;
}
if (RopeDiameterScaleX < 0.01f)
{
RopeDiameterScaleX = 0.01f;
}
if (RopeDiameterScaleY < 0.01f)
{
RopeDiameterScaleY = 0.01f;
}
bool flag2 = LinkJointBreakForce != float.PositiveInfinity || LinkJointBreakTorque != float.PositiveInfinity;
Mesh mesh = new Mesh();
int num9 = ((!flag2) ? ((TotalLinks + 1) * (RopeSegmentSides + 1) + (RopeSegmentSides + 1) * 2) : (TotalLinks * (RopeSegmentSides + 1) * 4));
int num10 = TotalLinks * RopeSegmentSides * 2;
int num11 = ((!flag2) ? (2 * (RopeSegmentSides - 2)) : (TotalLinks * 2 * (RopeSegmentSides - 2)));
Vector3[] array3 = new Vector3[num9];
Vector2[] array4 = new Vector2[num9];
Vector4[] array5 = new Vector4[num9];
BoneWeight[] array6 = new BoneWeight[num9];
int[] indices = new int[num10 * 3];
int[] indices2 = new int[num11 * 3];
if (flag2)
{
int num12 = 0;
for (int num13 = 0; num13 < TotalLinks; num13++)
{
int num14 = num13;
int num15 = num14;
float num16 = 1f;
float num17 = 1f - num16;
FillLinkMeshIndicesRope(num13, TotalLinks, ref indices, flag2);
FillLinkMeshIndicesSections(num13, TotalLinks, ref indices2, flag2);
for (int num18 = 0; num18 < 4; num18++)
{
for (int num19 = 0; num19 < RopeSegmentSides + 1; num19++)
{
int num20 = ((num18 >= 2) ? 1 : 0);
float num21 = (float)(num13 + num20) / (float)TotalLinks;
float num22 = Mathf.Cos((float)num19 / (float)RopeSegmentSides * (float)Math.PI * 2f);
float num23 = Mathf.Sin((float)num19 / (float)RopeSegmentSides * (float)Math.PI * 2f);
array3[num12] = new Vector3(num22 * RopeDiameter * RopeDiameterScaleX * 0.5f, num23 * RopeDiameter * RopeDiameterScaleY * 0.5f, LinkLengths[num13] * (float)num20);
array3[num12] = array[num14].TransformPoint(array3[num12]) * num16 + array[num15].TransformPoint(array3[num12]) * num17;
array3[num12] = base.transform.InverseTransformPoint(array3[num12]);
if (num18 == 0 || num18 == 3)
{
array4[num12] = new Vector2(Mathf.Clamp01((num22 + 1f) * 0.5f), Mathf.Clamp01((num23 + 1f) * 0.5f));
array5[num12] = new Vector4(1f, 0f, 0f, 1f);
}
else
{
array4[num12] = new Vector2(num21 * TotalRopeLength * RopeTextureTileMeters, (float)num19 / (float)RopeSegmentSides);
array5[num12] = new Vector4(0f, 0f, 1f, 1f);
}
array6[num12].boneIndex0 = num14;
array6[num12].boneIndex1 = num15;
array6[num12].weight0 = num16;
array6[num12].weight1 = num17;
num12++;
}
}
}
}
else
{
int num24 = 0;
FillLinkMeshIndicesSections(0, TotalLinks, ref indices2, flag2);
for (int num25 = 0; num25 < TotalLinks + 1; num25++)
{
int num26 = ((num25 >= TotalLinks) ? (TotalLinks - 1) : num25);
int num27 = num26;
float num28 = 1f;
float num29 = 1f - num28;
if (num25 < TotalLinks)
{
FillLinkMeshIndicesRope(num25, TotalLinks, ref indices, flag2);
}
bool flag3 = false;
bool flag4 = false;
int num30 = 1;
if (num25 == 0)
{
num30++;
flag3 = true;
}
if (num25 == TotalLinks)
{
num30++;
flag4 = true;
}
for (int num31 = 0; num31 < num30; num31++)
{
for (int num32 = 0; num32 < RopeSegmentSides + 1; num32++)
{
float num33 = (float)num25 / (float)TotalLinks;
float num34 = Mathf.Cos((float)num32 / (float)RopeSegmentSides * (float)Math.PI * 2f);
float num35 = Mathf.Sin((float)num32 / (float)RopeSegmentSides * (float)Math.PI * 2f);
array3[num24] = new Vector3(num34 * RopeDiameter * RopeDiameterScaleX * 0.5f, num35 * RopeDiameter * RopeDiameterScaleY * 0.5f, flag4 ? LinkLengths[TotalLinks - 1] : 0f);
array3[num24] = array[num26].TransformPoint(array3[num24]) * num28 + array[num27].TransformPoint(array3[num24]) * num29;
array3[num24] = base.transform.InverseTransformPoint(array3[num24]);
if ((flag3 && num31 == 0) || (flag4 && num31 == num30 - 1))
{
array4[num24] = new Vector2(Mathf.Clamp01((num34 + 1f) * 0.5f), Mathf.Clamp01((num35 + 1f) * 0.5f));
array5[num24] = new Vector4(1f, 0f, 0f, 1f);
}
else
{
array4[num24] = new Vector2(num33 * TotalRopeLength * RopeTextureTileMeters, (float)num32 / (float)RopeSegmentSides);
array5[num24] = new Vector4(0f, 0f, 1f, 1f);
}
array6[num24].boneIndex0 = num26;
array6[num24].boneIndex1 = num27;
array6[num24].weight0 = num28;
array6[num24].weight1 = num29;
num24++;
}
}
}
}
mesh.vertices = array3;
mesh.uv = array4;
mesh.boneWeights = array6;
mesh.bindposes = array2;
mesh.subMeshCount = 2;
mesh.SetTriangles(indices, 0);
mesh.SetTriangles(indices2, 1);
mesh.RecalculateNormals();
mesh.tangents = array5;
SkinnedMeshRenderer skinnedMeshRenderer = ((!(base.gameObject.GetComponent<SkinnedMeshRenderer>() != null)) ? base.gameObject.AddComponent<SkinnedMeshRenderer>() : base.gameObject.GetComponent<SkinnedMeshRenderer>());
skinnedMeshRenderer.materials = new Material[2] { RopeMaterial, RopeSectionMaterial };
skinnedMeshRenderer.bones = array;
skinnedMeshRenderer.sharedMesh = mesh;
skinnedMeshRenderer.updateWhenOffscreen = true;
}
Deleted = false;
if (Application.isPlaying)
{
CreateRopeJoints();
}
SetupRopeLinks();
float realtimeSinceStartup2 = Time.realtimeSinceStartup;
Status = string.Format("Rope generated in {0} seconds", realtimeSinceStartup2 - realtimeSinceStartup);
m_bLastStatusIsError = false;
return true;
}
public bool IsLastStatusError()
{
return m_bLastStatusIsError;
}
public bool ChangeRopeDiameter(float fNewDiameter, float fNewScaleX, float fNewScaleY)
{
if (RopeType != ERopeType.Procedural)
{
return false;
}
SkinnedMeshRenderer component = base.gameObject.GetComponent<SkinnedMeshRenderer>();
if (component == null)
{
return false;
}
RopeDiameter = fNewDiameter;
RopeDiameterScaleX = fNewScaleX;
RopeDiameterScaleY = fNewScaleY;
if (RopeDiameter < 0.01f)
{
RopeDiameter = 0.01f;
}
if (RopeDiameterScaleX < 0.01f)
{
RopeDiameterScaleX = 0.01f;
}
if (RopeDiameterScaleY < 0.01f)
{
RopeDiameterScaleY = 0.01f;
}
bool flag = LinkJointBreakForce != float.PositiveInfinity || LinkJointBreakTorque != float.PositiveInfinity;
Vector3[] vertices = component.sharedMesh.vertices;
Matrix4x4[] bindposes = component.sharedMesh.bindposes;
Vector2[] array = new Vector2[RopeSegmentSides + 1];
for (int i = 0; i < RopeSegmentSides + 1; i++)
{
float num = Mathf.Cos((float)i / (float)RopeSegmentSides * (float)Math.PI * 2f);
float num2 = Mathf.Sin((float)i / (float)RopeSegmentSides * (float)Math.PI * 2f);
array[i] = new Vector2(num * RopeDiameter * RopeDiameterScaleX * 0.5f, num2 * RopeDiameter * RopeDiameterScaleY * 0.5f);
}
if (flag)
{
int num3 = 0;
for (int j = 0; j < TotalLinks; j++)
{
int num4 = j;
int num5 = num4;
float num6 = 1f;
float num7 = 1f - num6;
bindposes[j] = component.bones[j].transform.worldToLocalMatrix;
if (component.bones[j].transform.parent != null)
{
bindposes[j] *= base.transform.localToWorldMatrix;
}
for (int k = 0; k < 4; k++)
{
for (int l = 0; l < RopeSegmentSides + 1; l++)
{
int num8 = ((k >= 2) ? 1 : 0);
vertices[num3] = new Vector3(array[l].x, array[l].y, LinkLengths[j] * (float)num8);
vertices[num3] = component.bones[num4].TransformPoint(vertices[num3]) * num6 + component.bones[num5].TransformPoint(vertices[num3]) * num7;
vertices[num3] = base.transform.InverseTransformPoint(vertices[num3]);
num3++;
}
}
}
}
else
{
int num9 = 0;
for (int m = 0; m < TotalLinks + 1; m++)
{
int num10 = ((m >= TotalLinks) ? (TotalLinks - 1) : m);
int num11 = num10;
float num12 = 1f;
float num13 = 1f - num12;
bool flag2 = false;
int num14 = 1;
if (m == 0)
{
num14++;
}
if (m == TotalLinks)
{
num14++;
flag2 = true;
}
if (m < TotalLinks)
{
bindposes[m] = component.bones[m].transform.worldToLocalMatrix;
if (component.bones[m].transform.parent != null)
{
bindposes[m] *= base.transform.localToWorldMatrix;
}
}
for (int n = 0; n < num14; n++)
{
for (int num15 = 0; num15 < RopeSegmentSides + 1; num15++)
{
vertices[num9] = new Vector3(array[num15].x, array[num15].y, flag2 ? LinkLengths[TotalLinks - 1] : 0f);
vertices[num9] = component.bones[num10].TransformPoint(vertices[num9]) * num12 + component.bones[num11].TransformPoint(vertices[num9]) * num13;
vertices[num9] = base.transform.InverseTransformPoint(vertices[num9]);
num9++;
}
}
}
}
component.sharedMesh.vertices = vertices;
component.sharedMesh.bindposes = bindposes;
SetupRopeLinks();
return true;
}
public bool ChangeRopeSegmentSides(int nNewSegmentSides)
{
if (RopeType != ERopeType.Procedural)
{
return false;
}
SkinnedMeshRenderer component = base.gameObject.GetComponent<SkinnedMeshRenderer>();
if (component == null)
{
return false;
}
RopeSegmentSides = nNewSegmentSides;
if (RopeSegmentSides < 3)
{
RopeSegmentSides = 3;
}
bool flag = LinkJointBreakForce != float.PositiveInfinity || LinkJointBreakTorque != float.PositiveInfinity;
Mesh mesh = new Mesh();
int num = ((!flag) ? ((TotalLinks + 1) * (RopeSegmentSides + 1) + (RopeSegmentSides + 1) * 2) : (TotalLinks * (RopeSegmentSides + 1) * 4));
int num2 = TotalLinks * RopeSegmentSides * 2;
int num3 = ((!flag) ? (2 * (RopeSegmentSides - 2)) : (TotalLinks * 2 * (RopeSegmentSides - 2)));
Vector3[] array = new Vector3[num];
Vector2[] array2 = new Vector2[num];
Vector4[] array3 = new Vector4[num];
BoneWeight[] array4 = new BoneWeight[num];
int[] indices = new int[num2 * 3];
int[] indices2 = new int[num3 * 3];
Matrix4x4[] bindposes = component.sharedMesh.bindposes;
if (flag)
{
int num4 = 0;
for (int i = 0; i < TotalLinks; i++)
{
int num5 = i;
int num6 = num5;
float num7 = 1f;
float num8 = 1f - num7;
bindposes[i] = component.bones[i].transform.worldToLocalMatrix;
if (component.bones[i].transform.parent != null)
{
bindposes[i] *= base.transform.localToWorldMatrix;
}
FillLinkMeshIndicesRope(i, TotalLinks, ref indices, flag);
FillLinkMeshIndicesSections(i, TotalLinks, ref indices2, flag);
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < RopeSegmentSides + 1; k++)
{
int num9 = ((j >= 2) ? 1 : 0);
float num10 = (float)(i + num9) / (float)TotalLinks;
float num11 = Mathf.Cos((float)k / (float)RopeSegmentSides * (float)Math.PI * 2f);
float num12 = Mathf.Sin((float)k / (float)RopeSegmentSides * (float)Math.PI * 2f);
array[num4] = new Vector3(num11 * RopeDiameter * RopeDiameterScaleX * 0.5f, num12 * RopeDiameter * RopeDiameterScaleY * 0.5f, LinkLengths[i] * (float)num9);
array[num4] = component.bones[num5].TransformPoint(array[num4]) * num7 + component.bones[num6].TransformPoint(array[num4]) * num8;
array[num4] = base.transform.InverseTransformPoint(array[num4]);
if (j == 0 || j == 3)
{
array2[num4] = new Vector2(Mathf.Clamp01((num11 + 1f) * 0.5f), Mathf.Clamp01((num12 + 1f) * 0.5f));
array3[num4] = new Vector4(1f, 0f, 0f, 1f);
}
else
{
array2[num4] = new Vector2(num10 * TotalRopeLength * RopeTextureTileMeters, (float)k / (float)RopeSegmentSides);
array3[num4] = new Vector4(0f, 0f, 1f, 1f);
}
array4[num4].boneIndex0 = num5;
array4[num4].boneIndex1 = num6;
array4[num4].weight0 = num7;
array4[num4].weight1 = num8;
num4++;
}
}
}
}
else
{
int num13 = 0;
FillLinkMeshIndicesSections(0, TotalLinks, ref indices2, flag);
for (int l = 0; l < TotalLinks + 1; l++)
{
int num14 = ((l >= TotalLinks) ? (TotalLinks - 1) : l);
int num15 = num14;
float num16 = 1f;
float num17 = 1f - num16;
if (l < TotalLinks)
{
FillLinkMeshIndicesRope(l, TotalLinks, ref indices, flag);
}
bool flag2 = false;
bool flag3 = false;
int num18 = 1;
if (l == 0)
{
num18++;
flag2 = true;
}
if (l == TotalLinks)
{
num18++;
flag3 = true;
}
if (l < TotalLinks)
{
bindposes[l] = component.bones[l].transform.worldToLocalMatrix;
if (component.bones[l].transform.parent != null)
{
bindposes[l] *= base.transform.localToWorldMatrix;
}
}
for (int m = 0; m < num18; m++)
{
for (int n = 0; n < RopeSegmentSides + 1; n++)
{
float num19 = (float)l / (float)TotalLinks;
float num20 = Mathf.Cos((float)n / (float)RopeSegmentSides * (float)Math.PI * 2f);
float num21 = Mathf.Sin((float)n / (float)RopeSegmentSides * (float)Math.PI * 2f);
array[num13] = new Vector3(num20 * RopeDiameter * RopeDiameterScaleX * 0.5f, num21 * RopeDiameter * RopeDiameterScaleY * 0.5f, flag3 ? LinkLengths[TotalLinks - 1] : 0f);
array[num13] = component.bones[num14].TransformPoint(array[num13]) * num16 + component.bones[num15].TransformPoint(array[num13]) * num17;
array[num13] = base.transform.InverseTransformPoint(array[num13]);
if ((flag2 && m == 0) || (flag3 && m == num18 - 1))
{
array2[num13] = new Vector2(Mathf.Clamp01((num20 + 1f) * 0.5f), Mathf.Clamp01((num21 + 1f) * 0.5f));
array3[num13] = new Vector4(1f, 0f, 0f, 1f);
}
else
{
array2[num13] = new Vector2(num19 * TotalRopeLength * RopeTextureTileMeters, (float)n / (float)RopeSegmentSides);
array3[num13] = new Vector4(0f, 0f, 1f, 1f);
}
array4[num13].boneIndex0 = num14;
array4[num13].boneIndex1 = num15;
array4[num13].weight0 = num16;
array4[num13].weight1 = num17;
num13++;
}
}
}
}
mesh.vertices = array;
mesh.uv = array2;
mesh.boneWeights = array4;
mesh.bindposes = bindposes;
mesh.subMeshCount = 2;
mesh.SetTriangles(indices, 0);
mesh.SetTriangles(indices2, 1);
mesh.RecalculateNormals();
mesh.tangents = array3;
if (Application.isEditor && !Application.isPlaying)
{
UnityEngine.Object.DestroyImmediate(component.sharedMesh);
}
else
{
UnityEngine.Object.Destroy(component.sharedMesh);
}
component.sharedMesh = mesh;
SetupRopeLinks();
return true;
}
public void SetupRopeMaterials()
{
if (RopeType == ERopeType.Procedural)
{
SkinnedMeshRenderer component = base.gameObject.GetComponent<SkinnedMeshRenderer>();
if (component != null)
{
component.materials = new Material[2] { RopeMaterial, RopeSectionMaterial };
}
}
}
public void SetupRopeLinks()
{
if (RopeNodes == null || RopeNodes.Count == 0 || Deleted || (RopeType == ERopeType.ImportBones && ImportedBones == null))
{
return;
}
base.gameObject.layer = RopeLayer;
if (RopeDiameter < 0.01f)
{
RopeDiameter = 0.01f;
}
for (int i = 0; i < RopeNodes.Count; i++)
{
RopeNode ropeNode = RopeNodes[i];
if (ropeNode.bIsCoil)
{
continue;
}
if (RopeType == ERopeType.ImportBones)
{
ropeNode.eColliderType = BoneColliderType;
ropeNode.nColliderSkip = BoneColliderSkip;
}
float num = ropeNode.fLength / (float)ropeNode.nNumLinks;
float linkDiameter = GetLinkDiameter();
int nColliderSkip = ropeNode.nColliderSkip;
float fValue = ((RopeType != ERopeType.Procedural) ? 0f : (num * 0.5f));
int num2 = 0;
GameObject[] segmentLinks = ropeNode.segmentLinks;
foreach (GameObject gameObject in segmentLinks)
{
if (!gameObject)
{
continue;
}
if ((bool)gameObject.GetComponent<Collider>())
{
UnityEngine.Object.DestroyImmediate(gameObject.GetComponent<Collider>());
}
bool flag = num2 % (nColliderSkip + 1) == 0;
bool flag2 = gameObject.GetComponent<Rigidbody>() != null && gameObject.GetComponent<Rigidbody>().isKinematic;
if (RopeType == ERopeType.ImportBones)
{
if (Mathf.Approximately(ImportedBones[num2].fLength, 0f))
{
flag = false;
}
else if (flag)
{
flag = ImportedBones[num2].bCreatedCollider;
}
num = ImportedBones[num2].fLength * BoneColliderLength;
fValue = num * BoneColliderOffset;
flag2 = ImportedBones[num2].bIsStatic;
}
if (flag)
{
switch (ropeNode.eColliderType)
{
case EColliderType.Capsule:
{
CapsuleCollider capsuleCollider = gameObject.AddComponent<CapsuleCollider>();
capsuleCollider.material = RopePhysicsMaterial;
capsuleCollider.center = GetLinkAxisOffset(fValue);
capsuleCollider.radius = linkDiameter * 0.5f;
capsuleCollider.height = num;
capsuleCollider.direction = GetLinkAxisIndex();
capsuleCollider.material = RopePhysicsMaterial;
capsuleCollider.enabled = flag;
break;
}
case EColliderType.Box:
{
BoxCollider boxCollider = gameObject.AddComponent<BoxCollider>();
Vector3 v3CenterInOut = GetLinkAxisOffset(fValue);
Vector3 v3SizeInOut = Vector3.zero;
boxCollider.material = RopePhysicsMaterial;
if (GetLinkBoxColliderCenterAndSize(num, linkDiameter, ref v3CenterInOut, ref v3SizeInOut))
{
boxCollider.center = v3CenterInOut;
boxCollider.size = v3SizeInOut;
boxCollider.enabled = flag;
}
else
{
boxCollider.enabled = false;
}
break;
}
}
}
if (gameObject.GetComponent<Collider>() != null)
{
gameObject.GetComponent<Collider>().enabled = !flag2;
}
Rigidbody rigidbody = ((!(gameObject.GetComponent<Rigidbody>() != null)) ? gameObject.AddComponent<Rigidbody>() : gameObject.GetComponent<Rigidbody>());
rigidbody.mass = LinkMass;
rigidbody.solverIterations = LinkSolverIterationCount;
rigidbody.isKinematic = flag2;
gameObject.layer = RopeLayer;
num2++;
}
}
}
public void SetupRopeJoints()
{
if (RopeNodes == null || RopeNodes.Count == 0 || Deleted || (RopeType == ERopeType.ImportBones && ImportedBones == null))
{
return;
}
foreach (RopeNode ropeNode6 in RopeNodes)
{
if (ropeNode6.segmentLinks == null)
{
return;
}
}
int num = 0;
Vector3[] array = new Vector3[TotalLinks];
Quaternion[] array2 = new Quaternion[TotalLinks];
Vector3 localPosition = ((!(RopeStart != null)) ? Vector3.zero : RopeStart.transform.localPosition);
Quaternion localRotation = ((!(RopeStart != null)) ? Quaternion.identity : RopeStart.transform.localRotation);
Vector3[] array3 = new Vector3[RopeNodes.Count];
Quaternion[] array4 = new Quaternion[RopeNodes.Count];
if (m_bRopeStartInitialOrientationInitialized && RopeStart != null)
{
RopeStart.transform.localPosition = m_v3InitialRopeStartLocalPos;
RopeStart.transform.localRotation = m_qInitialRopeStartLocalRot;
}
for (int i = 0; i < RopeNodes.Count; i++)
{
RopeNode ropeNode = RopeNodes[i];
if (ropeNode.bInitialOrientationInitialized && ropeNode.goNode != null)
{
array3[i] = ropeNode.goNode.transform.localPosition;
array4[i] = ropeNode.goNode.transform.localRotation;
ropeNode.goNode.transform.localPosition = ropeNode.v3InitialLocalPos;
ropeNode.goNode.transform.localRotation = ropeNode.qInitialLocalRot;
}
}
if (RopeType == ERopeType.Procedural || RopeType == ERopeType.LinkedObjects)
{
for (int j = 0; j < RopeNodes.Count; j++)
{
RopeNode ropeNode2 = RopeNodes[j];
float num2 = ropeNode2.fLength / (float)ropeNode2.nNumLinks;
float z = num2 * (float)(ropeNode2.segmentLinks.Length - 1);
for (int k = 0; k < ropeNode2.segmentLinks.Length; k++)
{
float t = (float)k / ((ropeNode2.segmentLinks.Length != 1) ? ((float)ropeNode2.segmentLinks.Length - 1f) : 1f);
array[num] = ropeNode2.segmentLinks[k].transform.position;
array2[num] = ropeNode2.segmentLinks[k].transform.rotation;
if (!ropeNode2.bIsCoil)
{
ropeNode2.segmentLinks[k].transform.position = Vector3.Lerp(new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, z), t);
ropeNode2.segmentLinks[k].transform.rotation = Quaternion.identity;
if (RopeType == ERopeType.LinkedObjects)
{
ropeNode2.segmentLinks[k].transform.rotation *= GetLinkedObjectLocalRotation(LinkTwistAngleStart + LinkTwistAngleIncrement * (float)k);
}
}
num++;
}
}
}
else if (RopeType == ERopeType.ImportBones)
{
for (int l = 0; l < ImportedBones.Length; l++)
{
array[l] = ImportedBones[l].goBone.transform.position;
array2[l] = ImportedBones[l].goBone.transform.rotation;
if (ImportedBones[l].tfNonBoneParent != null)
{
Transform parent = ImportedBones[l].goBone.transform.parent;
ImportedBones[l].goBone.transform.parent = ImportedBones[l].tfNonBoneParent;
ImportedBones[l].goBone.transform.localPosition = ImportedBones[l].v3OriginalLocalPos;
ImportedBones[l].goBone.transform.localRotation = ImportedBones[l].qOriginalLocalRot;
ImportedBones[l].goBone.transform.parent = parent;
ImportedBones[l].goBone.transform.localScale = ImportedBones[l].v3OriginalLocalScale;
}
}
}
for (int m = 0; m < RopeNodes.Count; m++)
{
RopeNode ropeNode3 = RopeNodes[m];
if (ropeNode3.bIsCoil)
{
continue;
}
ConfigurableJoint[] linkJoints = ropeNode3.linkJoints;
foreach (ConfigurableJoint configurableJoint in linkJoints)
{
if ((bool)configurableJoint)
{
SetupJoint(configurableJoint);
}
}
if ((RopeType == ERopeType.Procedural || RopeType == ERopeType.LinkedObjects) && ropeNode3.bInitialOrientationInitialized)
{
GameObject gameObject = ((m != m_nFirstNonCoilNode) ? RopeNodes[m - 1].goNode : RopeStart);
GameObject goNode = RopeNodes[m].goNode;
Vector3 vector = gameObject.transform.TransformDirection(ropeNode3.m_v3LocalDirectionForward);
Vector3 upwards = gameObject.transform.TransformDirection(ropeNode3.m_v3LocalDirectionUp);
ropeNode3.segmentLinks[0].transform.position = gameObject.transform.position;
ropeNode3.segmentLinks[0].transform.rotation = Quaternion.LookRotation(vector, upwards);
ropeNode3.segmentLinks[ropeNode3.segmentLinks.Length - 1].transform.position = goNode.transform.position - vector * (ropeNode3.fLength / (float)ropeNode3.nNumLinks);
ropeNode3.segmentLinks[ropeNode3.segmentLinks.Length - 1].transform.rotation = Quaternion.LookRotation(vector, upwards);
if (RopeType == ERopeType.LinkedObjects)
{
ropeNode3.segmentLinks[0].transform.rotation *= GetLinkedObjectLocalRotation(LinkTwistAngleStart);
ropeNode3.segmentLinks[ropeNode3.segmentLinks.Length - 1].transform.rotation *= GetLinkedObjectLocalRotation(LinkTwistAngleStart + LinkTwistAngleIncrement * (float)(ropeNode3.segmentLinks.Length - 1));
}
if (ropeNode3.linkJoints[0] != null)
{
SetupJoint(ropeNode3.linkJoints[0]);
}
if (ropeNode3.linkJoints[ropeNode3.linkJoints.Length - 1] != null)
{
SetupJoint(ropeNode3.linkJoints[ropeNode3.linkJoints.Length - 1]);
}
}
}
num = 0;
if (m_bRopeStartInitialOrientationInitialized && RopeStart != null)
{
RopeStart.transform.localPosition = localPosition;
RopeStart.transform.localRotation = localRotation;
}
for (int num3 = 0; num3 < RopeNodes.Count; num3++)
{
RopeNode ropeNode4 = RopeNodes[num3];
if (ropeNode4.bInitialOrientationInitialized && ropeNode4.goNode != null)
{
ropeNode4.goNode.transform.localPosition = array3[num3];
ropeNode4.goNode.transform.localRotation = array4[num3];
}
}
if (RopeType == ERopeType.Procedural || RopeType == ERopeType.LinkedObjects)
{
for (int num4 = 0; num4 < RopeNodes.Count; num4++)
{
RopeNode ropeNode5 = RopeNodes[num4];
for (int num5 = 0; num5 < ropeNode5.segmentLinks.Length; num5++)
{
ropeNode5.segmentLinks[num5].transform.position = array[num];
ropeNode5.segmentLinks[num5].transform.rotation = array2[num];
num++;
}
}
}
else if (RopeType == ERopeType.ImportBones)
{
for (int num6 = 0; num6 < ImportedBones.Length; num6++)
{
ImportedBones[num6].goBone.transform.position = array[num6];
ImportedBones[num6].goBone.transform.rotation = array2[num6];
}
}
}
public void CheckNeedsStartExitLockZ()
{
if (RopeType != ERopeType.Procedural)
{
return;
}
int num = 0;
for (int i = 0; i < RopeNodes.Count; i++)
{
RopeNode ropeNode = RopeNodes[i];
for (int j = 0; j < ropeNode.segmentLinks.Length; j++)
{
Transform transform = null;
Transform transform2 = null;
if (!FirstNodeIsCoil())
{
transform = ((i != m_nFirstNonCoilNode) ? RopeNodes[i - 1].goNode.transform : RopeStart.transform);
transform2 = RopeNodes[i].goNode.transform;
}
if (transform != null && transform2 != null)
{
if (j == 0)
{
ropeNode.segmentLinks[j].transform.rotation = ((!LockStartEndInZAxis) ? Quaternion.LookRotation((transform2.position - transform.position).normalized) : transform.rotation);
ropeNode.segmentLinks[j].transform.parent = ((!LockStartEndInZAxis) ? ropeNode.segmentLinks[j].transform.parent : transform);
ropeNode.segmentLinks[j].GetComponent<Rigidbody>().isKinematic = LockStartEndInZAxis || ropeNode.segmentLinks[j].GetComponent<Rigidbody>().isKinematic;
}
else if (j == ropeNode.segmentLinks.Length - 1)
{
ropeNode.segmentLinks[j].transform.position = ((!LockStartEndInZAxis) ? (transform2.position - (transform2.position - transform.position).normalized * LinkLengths[num]) : (transform2.position - transform2.forward * LinkLengths[num]));
ropeNode.segmentLinks[j].transform.rotation = ((!LockStartEndInZAxis) ? Quaternion.LookRotation((transform2.position - transform.position).normalized) : transform2.rotation);
ropeNode.segmentLinks[j].transform.parent = ((!LockStartEndInZAxis) ? ropeNode.segmentLinks[j].transform.parent : transform2);
ropeNode.segmentLinks[j].GetComponent<Rigidbody>().isKinematic = LockStartEndInZAxis || ropeNode.segmentLinks[j].GetComponent<Rigidbody>().isKinematic;
}
}
num++;
}
}
}
public void FillLinkMeshIndicesRope(int nLinearLinkIndex, int nTotalLinks, ref int[] indices, bool bBreakable, bool bBrokenLink = false)
{
if (bBreakable)
{
int num = nLinearLinkIndex * RopeSegmentSides * 2;
int num2 = nLinearLinkIndex * (RopeSegmentSides + 1) * 4 + (RopeSegmentSides + 1);
int num3 = (RopeSegmentSides + 1) * 3;
int num4 = ((!bBrokenLink && nLinearLinkIndex < nTotalLinks - 1) ? num3 : 0);
for (int i = 0; i < RopeSegmentSides + 1; i++)
{
if (i < RopeSegmentSides)
{
int num5 = num2 + i;
indices[num * 3 + 2] = num5;
indices[num * 3 + 1] = num5 + num4 + (RopeSegmentSides + 1);
indices[num * 3] = num5 + 1;
indices[num * 3 + 5] = num5 + 1;
indices[num * 3 + 4] = num5 + num4 + (RopeSegmentSides + 1);
indices[num * 3 + 3] = num5 + num4 + (RopeSegmentSides + 1) + 1;
num += 2;
}
}
return;
}
int num6 = nLinearLinkIndex * RopeSegmentSides * 2;
int num7 = nLinearLinkIndex * (RopeSegmentSides + 1) + (RopeSegmentSides + 1);
for (int j = 0; j < RopeSegmentSides + 1; j++)
{
if (j < RopeSegmentSides)
{
int num8 = num7 + j;
indices[num6 * 3 + 2] = num8;
indices[num6 * 3 + 1] = num8 + RopeSegmentSides + 1;
indices[num6 * 3] = num8 + 1;
indices[num6 * 3 + 5] = num8 + 1;
indices[num6 * 3 + 4] = num8 + RopeSegmentSides + 1;
indices[num6 * 3 + 3] = num8 + 1 + RopeSegmentSides + 1;
num6 += 2;
}
}
}
public void FillLinkMeshIndicesSections(int nLinearLinkIndex, int nTotalLinks, ref int[] indices, bool bBreakable, bool bBrokenLink = false)
{
if (bBreakable)
{
int num = nLinearLinkIndex * 2 * (RopeSegmentSides - 2);
int num2 = nLinearLinkIndex * (RopeSegmentSides + 1) * 4;
int num3 = (RopeSegmentSides + 1) * 2;
for (int i = 0; i < RopeSegmentSides - 2; i++)
{
indices[num * 3] = num2;
indices[num * 3 + 1] = num2 + (i + 2);
indices[num * 3 + 2] = num2 + (i + 1);
num++;
}
int num4 = ((!bBrokenLink && nLinearLinkIndex < nTotalLinks - 1) ? num3 : 0);
for (int j = 0; j < RopeSegmentSides - 2; j++)
{
indices[num * 3 + 2] = num2 + (RopeSegmentSides + 1) * 3 + num4;
indices[num * 3 + 1] = num2 + (RopeSegmentSides + 1) * 3 + num4 + (j + 2);
indices[num * 3] = num2 + (RopeSegmentSides + 1) * 3 + num4 + (j + 1);
num++;
}
}
else
{
int num5 = 0;
int num6 = 0;
for (int k = 0; k < RopeSegmentSides - 2; k++)
{
indices[num5 * 3] = num6;
indices[num5 * 3 + 1] = num6 + (k + 2);
indices[num5 * 3 + 2] = num6 + (k + 1);
num5++;
}
num6 = (TotalLinks + 1) * (RopeSegmentSides + 1) + (RopeSegmentSides + 1);
for (int l = 0; l < RopeSegmentSides - 2; l++)
{
indices[num5 * 3 + 2] = num6;
indices[num5 * 3 + 1] = num6 + (l + 2);
indices[num5 * 3] = num6 + (l + 1);
num5++;
}
}
}
public bool HasDynamicSegmentNodes()
{
if (RopeNodes == null)
{
return false;
}
if (RopeNodes.Count == 0)
{
return false;
}
foreach (RopeNode ropeNode in RopeNodes)
{
if ((bool)ropeNode.goNode && (bool)ropeNode.goNode.GetComponent<Rigidbody>() && !ropeNode.goNode.GetComponent<Rigidbody>().isKinematic)
{
return true;
}
}
return false;
}
public void BeforeImportedBonesObjectRespawn()
{
if (ImportedBones == null)
{
return;
}
RopeBone[] importedBones = ImportedBones;
foreach (RopeBone ropeBone in importedBones)
{
if (ropeBone.goBone != null)
{
ropeBone.goBone.transform.parent = ropeBone.tfParent;
}
}
}
public void AfterImportedBonesObjectRespawn()
{
if (ImportedBones == null)
{
return;
}
RopeBone[] importedBones = ImportedBones;
foreach (RopeBone ropeBone in importedBones)
{
if (ropeBone.goBone != null)
{
ropeBone.goBone.transform.parent = ((!ropeBone.bIsStatic) ? base.transform : ropeBone.tfNonBoneParent);
}
}
}
public void ExtendRope(ERopeExtensionMode eRopeExtensionMode, float fIncrement)
{
if (!IsExtensible)
{
Debug.LogError("Rope can not be extended since the IsExtensible property has been marked as false");
return;
}
if (eRopeExtensionMode == ERopeExtensionMode.CoilRotationIncrement && !FirstNodeIsCoil())
{
Debug.LogError("Rope can not be extended through coil rotation since no coil is present");
return;
}
float fLinearIncrement = ((eRopeExtensionMode != ERopeExtensionMode.LinearExtensionIncrement) ? 0f : fIncrement);
float fCurrentCoilRopeRadius = m_fCurrentCoilRopeRadius;
if (eRopeExtensionMode == ERopeExtensionMode.CoilRotationIncrement)
{
fLinearIncrement = m_fCurrentCoilRopeRadius * (fIncrement / 360f) * 2f * (float)Math.PI;
}
float num = ExtendRopeLinear(fLinearIncrement);
float num2 = num * 360f / ((float)Math.PI * 2f * fCurrentCoilRopeRadius);
if (!Mathf.Approximately(num, 0f) && FirstNodeIsCoil())
{
CoilObject.transform.Rotate(GetAxisVector(CoilAxisRight, 1f) * num2);
SetupCoilBones(m_fCurrentCoilLength - num);
}
}
public void RecomputeCoil()
{
SetupCoilBones(m_fCurrentCoilLength);
}
public GameObject BuildStaticMeshObject(out string strStatusMessage)
{
if (Application.isEditor && Application.isPlaying)
{
strStatusMessage = "Error: Rope can't be made static from the editor in play mode";
return null;
}
if (RopeType == ERopeType.Procedural)
{
SkinnedMeshRenderer component = GetComponent<SkinnedMeshRenderer>();
if (component == null)
{
strStatusMessage = "Error: Procedural rope has no skinned mesh renderer";
return null;
}
Mesh sharedMesh = component.sharedMesh;
Mesh mesh = new Mesh();
int vertexCount = component.sharedMesh.vertexCount;
int num = component.sharedMesh.GetTriangles(0).Length;
int num2 = component.sharedMesh.GetTriangles(1).Length;
Vector3[] vertices = sharedMesh.vertices;
Vector2[] uv = sharedMesh.uv;
Vector4[] tangents = sharedMesh.tangents;
int[] triangles = sharedMesh.GetTriangles(0);
int[] triangles2 = sharedMesh.GetTriangles(1);
Vector3[] array = new Vector3[vertexCount];
Vector2[] array2 = new Vector2[vertexCount];
Vector4[] array3 = ((sharedMesh.tangents == null) ? null : new Vector4[sharedMesh.tangents.Length]);
int[] array4 = new int[num];
int[] array5 = new int[num2];
BoneWeight[] boneWeights = sharedMesh.boneWeights;
Matrix4x4[] bindposes = sharedMesh.bindposes;
Transform[] bones = component.bones;
Vector3 position = new Vector3(0f, 0f, 0f);
for (int i = 0; i < vertexCount; i++)
{
BoneWeight boneWeight = boneWeights[i];
array[i] = new Vector3(0f, 0f, 0f);
if (Math.Abs(boneWeight.weight0) > 1E-05f)
{
Vector3 point = bindposes[boneWeight.boneIndex0].MultiplyPoint3x4(vertices[i]);
array[i] += bones[boneWeight.boneIndex0].transform.localToWorldMatrix.MultiplyPoint3x4(point) * boneWeight.weight0;
}
if (Math.Abs(boneWeight.weight1) > 1E-05f)
{
Vector3 point = bindposes[boneWeight.boneIndex1].MultiplyPoint3x4(vertices[i]);
array[i] += bones[boneWeight.boneIndex1].transform.localToWorldMatrix.MultiplyPoint3x4(point) * boneWeight.weight1;
}
if (Math.Abs(boneWeight.weight2) > 1E-05f)
{
Vector3 point = bindposes[boneWeight.boneIndex2].MultiplyPoint3x4(vertices[i]);
array[i] += bones[boneWeight.boneIndex2].transform.localToWorldMatrix.MultiplyPoint3x4(point) * boneWeight.weight2;
}
if (Math.Abs(boneWeight.weight3) > 1E-05f)
{
Vector3 point = bindposes[boneWeight.boneIndex3].MultiplyPoint3x4(vertices[i]);
array[i] += bones[boneWeight.boneIndex3].transform.localToWorldMatrix.MultiplyPoint3x4(point) * boneWeight.weight3;
}
position += array[i];
array2[i] = uv[i];
if (array3 != null && array3.Length == vertexCount)
{
array3[i] = tangents[i];
}
}
if (vertexCount > 0)
{
position /= (float)vertexCount;
}
Vector3 position2 = base.transform.position;
base.transform.position = position;
for (int j = 0; j < vertexCount; j++)
{
array[j] = base.transform.InverseTransformPoint(array[j]);
}
base.transform.position = position2;
for (int k = 0; k < num; k++)
{
array4[k] = triangles[k];
}
for (int l = 0; l < num2; l++)
{
array5[l] = triangles2[l];
}
mesh.vertices = array;
mesh.uv = array2;
mesh.subMeshCount = 2;
mesh.SetTriangles(array4, 0);
mesh.SetTriangles(array5, 1);
mesh.RecalculateNormals();
mesh.RecalculateBounds();
if (array3 != null && array3.Length == vertexCount)
{
mesh.tangents = array3;
}
GameObject gameObject = new GameObject(base.gameObject.name + " (static)");
gameObject.transform.position = position;
gameObject.transform.rotation = base.transform.rotation;
MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>();
MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();
meshFilter.sharedMesh = mesh;
meshRenderer.sharedMaterials = new Material[2] { RopeMaterial, RopeSectionMaterial };
gameObject.isStatic = true;
MeshCollider meshCollider = gameObject.AddComponent<MeshCollider>();
meshCollider.sharedMesh = mesh;
meshCollider.convex = false;
meshCollider.material = RopePhysicsMaterial;
base.gameObject.SetActive(false);
strStatusMessage = "Rope converted succesfully";
return gameObject;
}
if (RopeType == ERopeType.LinkedObjects)
{
if (LinkObject == null)
{
strStatusMessage = "Error: LinkObject not specified. Can't continue.";
return null;
}
Renderer component2 = LinkObject.GetComponent<Renderer>();
MeshFilter component3 = LinkObject.GetComponent<MeshFilter>();
if (component2 == null)
{
strStatusMessage = "Error: LinkObject has no Renderer. Can't continue.";
return null;
}
if (component3 == null)
{
strStatusMessage = "Error: LinkObject has no Mesh Filter. Can't continue.";
return null;
}
if (component3.sharedMesh == null)
{
strStatusMessage = "Error: LinkObject has no mesh. Can't continue.";
return null;
}
Material[] array6 = new Material[component2.sharedMaterials.Length];
for (int m = 0; m < component2.sharedMaterials.Length; m++)
{
array6[m] = component2.sharedMaterials[m];
}
List<CombineInstance> list = new List<CombineInstance>();
for (int n = 0; n < RopeNodes.Count; n++)
{
RopeNode ropeNode = RopeNodes[n];
for (int num3 = 0; num3 < ropeNode.segmentLinks.Length; num3++)
{
list.Add(new CombineInstance
{
mesh = component3.sharedMesh,
transform = ropeNode.segmentLinks[num3].transform.localToWorldMatrix
});
}
}
GameObject gameObject2 = new GameObject(base.gameObject.name + " (static)");
MeshFilter meshFilter2 = gameObject2.AddComponent<MeshFilter>();
MeshRenderer meshRenderer2 = gameObject2.AddComponent<MeshRenderer>();
meshFilter2.sharedMesh = new Mesh();
meshFilter2.sharedMesh.CombineMeshes(list.ToArray());
meshRenderer2.sharedMaterials = array6;
gameObject2.isStatic = true;
Vector3[] vertices2 = meshFilter2.sharedMesh.vertices;
Vector3 zero = Vector3.zero;
for (int num4 = 0; num4 < meshFilter2.sharedMesh.vertexCount; num4++)
{
vertices2[num4] = base.transform.TransformPoint(vertices2[num4]);
zero += vertices2[num4];
}
if (meshFilter2.sharedMesh.vertexCount > 1)
{
zero /= (float)meshFilter2.sharedMesh.vertexCount;
}
gameObject2.transform.position = zero;
gameObject2.transform.rotation = base.transform.rotation;
for (int num5 = 0; num5 < meshFilter2.sharedMesh.vertexCount; num5++)
{
vertices2[num5] = gameObject2.transform.InverseTransformPoint(vertices2[num5]);
}
meshFilter2.sharedMesh.vertices = vertices2;
meshFilter2.sharedMesh.RecalculateBounds();
MeshCollider meshCollider2 = gameObject2.AddComponent<MeshCollider>();
meshCollider2.sharedMesh = meshFilter2.sharedMesh;
meshCollider2.convex = false;
meshCollider2.material = RopePhysicsMaterial;
base.gameObject.SetActive(false);
strStatusMessage = "Rope converted succesfully";
return gameObject2;
}
if (RopeType == ERopeType.ImportBones)
{
strStatusMessage = "Error: ImportBones rope type not supported";
return null;
}
strStatusMessage = "Error: Unknown rope type not supported";
return null;
}
public void MoveNodeUp(int nNode)
{
if (RopeNodes != null && nNode > 0 && nNode < RopeNodes.Count)
{
RopeNode value = RopeNodes[nNode];
RopeNodes[nNode] = RopeNodes[nNode - 1];
RopeNodes[nNode - 1] = value;
}
}
public void MoveNodeDown(int nNode)
{
if (RopeNodes != null && nNode >= 0 && nNode < RopeNodes.Count - 1)
{
RopeNode value = RopeNodes[nNode];
RopeNodes[nNode] = RopeNodes[nNode + 1];
RopeNodes[nNode + 1] = value;
}
}
public void CreateNewNode(int nNode)
{
if (RopeNodes == null)
{
RopeNodes = new List<RopeNode>();
}
RopeNodes.Insert(nNode + 1, new RopeNode());
}
public void RemoveNode(int nNode)
{
if (RopeNodes != null)
{
RopeNodes.RemoveAt(nNode);
}
}
public bool FirstNodeIsCoil()
{
if (RopeNodes != null && RopeNodes.Count > 0 && RopeNodes[0].bIsCoil)
{
return true;
}
return false;
}
private void CheckAddCoilNode()
{
if (RopeType != ERopeType.Procedural || !IsExtensible || !HasACoil || !(CoilObject != null) || !RopeStart)
{
return;
}
if (!RopeNodes[0].bIsCoil)
{
RopeNodes.Insert(0, new RopeNode());
if (CoilNumBones < 1)
{
CoilNumBones = 1;
}
RopeNodes[0].goNode = CoilObject;
RopeNodes[0].fLength = ExtensibleLength;
RopeNodes[0].fTotalLength = RopeNodes[0].fLength;
RopeNodes[0].nNumLinks = CoilNumBones;
RopeNodes[0].nTotalLinks = RopeNodes[0].nNumLinks;
RopeNodes[0].eColliderType = EColliderType.None;
RopeNodes[0].nColliderSkip = 0;
RopeNodes[0].bFold = true;
RopeNodes[0].bIsCoil = true;
m_afCoilBoneRadiuses = new float[RopeNodes[0].nTotalLinks];
m_afCoilBoneAngles = new float[RopeNodes[0].nTotalLinks];
m_afCoilBoneX = new float[RopeNodes[0].nTotalLinks];
}
m_nFirstNonCoilNode = 1;
}
private void CheckDelCoilNode()
{
if (RopeNodes[0].bIsCoil)
{
RopeNodes.RemoveAt(0);
m_afCoilBoneRadiuses = null;
m_afCoilBoneAngles = null;
m_afCoilBoneX = null;
}
m_nFirstNonCoilNode = 0;
}
private void CreateRopeJoints(bool bCheckIfBroken = false)
{
if (RopeNodes == null || RopeNodes.Count == 0 || Deleted || (RopeType == ERopeType.ImportBones && (ImportedBones == null || ImportedBones.Length == 0)))
{
return;
}
foreach (RopeNode ropeNode6 in RopeNodes)
{
if (ropeNode6.segmentLinks == null)
{
return;
}
}
if (RopeStart != null && RopeStart.GetComponent<Rigidbody>() == null)
{
RopeStart.AddComponent<Rigidbody>();
RopeStart.GetComponent<Rigidbody>().isKinematic = true;
}
for (int i = 0; i < RopeNodes.Count; i++)
{
RopeNode ropeNode = RopeNodes[i];
if (ropeNode.goNode != null && ropeNode.goNode.GetComponent<Rigidbody>() == null)
{
ropeNode.goNode.AddComponent<Rigidbody>();
ropeNode.goNode.GetComponent<Rigidbody>().isKinematic = true;
}
}
int num = 0;
int num2 = 0;
Vector3[] array = new Vector3[TotalLinks];
Quaternion[] array2 = new Quaternion[TotalLinks];
Vector3 localPosition = ((!(RopeStart != null)) ? Vector3.zero : RopeStart.transform.localPosition);
Quaternion localRotation = ((!(RopeStart != null)) ? Quaternion.identity : RopeStart.transform.localRotation);
Vector3[] array3 = new Vector3[RopeNodes.Count];
Quaternion[] array4 = new Quaternion[RopeNodes.Count];
if (m_bRopeStartInitialOrientationInitialized && RopeStart != null)
{
RopeStart.transform.localPosition = m_v3InitialRopeStartLocalPos;
RopeStart.transform.localRotation = m_qInitialRopeStartLocalRot;
}
for (int j = 0; j < RopeNodes.Count; j++)
{
RopeNode ropeNode2 = RopeNodes[j];
if (ropeNode2.bInitialOrientationInitialized && ropeNode2.goNode != null)
{
array3[j] = ropeNode2.goNode.transform.localPosition;
array4[j] = ropeNode2.goNode.transform.localRotation;
ropeNode2.goNode.transform.localPosition = ropeNode2.v3InitialLocalPos;
ropeNode2.goNode.transform.localRotation = ropeNode2.qInitialLocalRot;
}
}
for (int k = 0; k < RopeNodes.Count; k++)
{
RopeNode ropeNode3 = RopeNodes[k];
GameObject gameObject = null;
GameObject gameObject2 = null;
if (FirstNodeIsCoil() && k == 0)
{
gameObject = CoilObject;
gameObject2 = RopeStart;
}
else
{
gameObject = ((k != m_nFirstNonCoilNode) ? RopeNodes[k - 1].goNode : RopeStart);
gameObject2 = RopeNodes[k].goNode;
}
float num3 = ropeNode3.fLength / (float)ropeNode3.nNumLinks;
float z = num3 * (float)(ropeNode3.segmentLinks.Length - 1);
for (int l = 0; l < ropeNode3.segmentLinks.Length; l++)
{
if (RopeType == ERopeType.Procedural || RopeType == ERopeType.LinkedObjects)
{
float t = (float)l / ((ropeNode3.segmentLinks.Length != 1) ? ((float)ropeNode3.segmentLinks.Length - 1f) : 1f);
if (l == 0)
{
ropeNode3.m_v3LocalDirectionUp = gameObject.transform.InverseTransformDirection(ropeNode3.segmentLinks[l].transform.up);
}
Vector3 normalized = (gameObject2.transform.position - gameObject.transform.position).normalized;
if (ropeNode3.nTotalLinks > ropeNode3.nNumLinks && !ropeNode3.m_bExtensionInitialized)
{
ropeNode3.segmentLinks[l].transform.rotation = Quaternion.LookRotation((gameObject2.transform.position - gameObject.transform.position).normalized);
if (l < ropeNode3.m_nExtensionLinkIn)
{
ropeNode3.segmentLinks[l].transform.position = gameObject.transform.position;
ropeNode3.segmentLinks[l].transform.parent = ((k <= m_nFirstNonCoilNode) ? RopeStart.transform : RopeNodes[k - 1].goNode.transform);
ropeNode3.segmentLinks[l].GetComponent<Rigidbody>().isKinematic = true;
UltimateRopeLink component = ropeNode3.segmentLinks[l].GetComponent<UltimateRopeLink>();
if (component != null)
{
component.ExtensibleKinematic = true;
}
}
else
{
float t2 = (float)(l - ropeNode3.m_nExtensionLinkIn) / ((ropeNode3.nNumLinks <= 1) ? 1f : ((float)(ropeNode3.nNumLinks - 1)));
ropeNode3.segmentLinks[l].transform.position = Vector3.Lerp(gameObject.transform.position + normalized * num3, gameObject2.transform.position - normalized * num3, t2);
ropeNode3.segmentLinks[l].GetComponent<Rigidbody>().isKinematic = false;
UltimateRopeLink component2 = ropeNode3.segmentLinks[l].GetComponent<UltimateRopeLink>();
if (component2 != null)
{
component2.ExtensibleKinematic = false;
}
}
}
array[num2] = ropeNode3.segmentLinks[l].transform.position;
array2[num2] = ropeNode3.segmentLinks[l].transform.rotation;
ropeNode3.segmentLinks[l].transform.position = Vector3.Lerp(new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, z), t);
ropeNode3.segmentLinks[l].transform.rotation = Quaternion.identity;
if (RopeType == ERopeType.LinkedObjects)
{
ropeNode3.segmentLinks[l].transform.rotation *= GetLinkedObjectLocalRotation(LinkTwistAngleStart + LinkTwistAngleIncrement * (float)l);
}
num2++;
}
else if (RopeType == ERopeType.ImportBones)
{
array[l] = ImportedBones[l].goBone.transform.position;
array2[l] = ImportedBones[l].goBone.transform.rotation;
if (ImportedBones[l].tfNonBoneParent != null)
{
Transform parent = ImportedBones[l].goBone.transform.parent;
ImportedBones[l].goBone.transform.parent = ImportedBones[l].tfNonBoneParent;
ImportedBones[l].goBone.transform.localPosition = ImportedBones[l].v3OriginalLocalPos;
ImportedBones[l].goBone.transform.localRotation = ImportedBones[l].qOriginalLocalRot;
ImportedBones[l].goBone.transform.parent = parent;
ImportedBones[l].goBone.transform.localScale = ImportedBones[l].v3OriginalLocalScale;
}
}
bool flag = !bCheckIfBroken || !ropeNode3.linkJointBreaksProcessed[l];
if (RopeType == ERopeType.ImportBones)
{
bool flag2 = true;
if (l > 0)
{
flag2 = !ImportedBones[l - 1].goBone.GetComponent<Rigidbody>().isKinematic;
}
if (!flag2 && ImportedBones[l].goBone.GetComponent<Rigidbody>().isKinematic)
{
flag = false;
}
}
if (flag && l > 0 && !ropeNode3.bIsCoil)
{
ropeNode3.linkJoints[l] = CreateJoint(ropeNode3.segmentLinks[l], ropeNode3.segmentLinks[l - 1], ropeNode3.segmentLinks[l].transform.position);
ropeNode3.linkJointBreaksProcessed[l] = false;
}
else
{
ropeNode3.linkJoints[l] = null;
}
}
float num4 = ((RopeType != ERopeType.ImportBones) ? (((gameObject2.transform.position - gameObject.transform.position).magnitude - num3) / (gameObject2.transform.position - gameObject.transform.position).magnitude) : 0f);
if (num4 < 0f)
{
num4 = 0f;
}
for (int m = 0; m < ropeNode3.segmentLinks.Length; m++)
{
if (RopeType == ERopeType.Procedural || RopeType == ERopeType.LinkedObjects)
{
float num5 = (float)m / ((ropeNode3.segmentLinks.Length != 1) ? ((float)ropeNode3.segmentLinks.Length - 1f) : 1f);
if (Vector3.Distance(gameObject.transform.position, gameObject2.transform.position) < 0.001f)
{
ropeNode3.segmentLinks[m].transform.position = gameObject.transform.position;
ropeNode3.segmentLinks[m].transform.rotation = gameObject.transform.rotation;
}
else
{
ropeNode3.segmentLinks[m].transform.position = Vector3.Lerp(gameObject.transform.position, gameObject2.transform.position, num5 * num4);
ropeNode3.segmentLinks[m].transform.rotation = Quaternion.LookRotation((gameObject2.transform.position - gameObject.transform.position).normalized);
}
if (RopeType == ERopeType.LinkedObjects)
{
ropeNode3.segmentLinks[m].transform.rotation *= GetLinkedObjectLocalRotation(LinkTwistAngleStart + LinkTwistAngleIncrement * (float)m);
}
}
num++;
}
if (RopeType == ERopeType.Procedural || RopeType == ERopeType.LinkedObjects)
{
if (!ropeNode3.bIsCoil)
{
if (!bCheckIfBroken || !ropeNode3.linkJointBreaksProcessed[0])
{
if (ropeNode3.nTotalLinks == ropeNode3.nNumLinks)
{
ropeNode3.linkJoints[0] = CreateJoint(ropeNode3.segmentLinks[0], gameObject, gameObject.transform.position);
ropeNode3.linkJointBreaksProcessed[0] = false;
}
else
{
ropeNode3.linkJoints[0] = null;
ropeNode3.linkJointBreaksProcessed[0] = true;
}
}
else
{
ropeNode3.linkJoints[0] = null;
}
if (!bCheckIfBroken || !ropeNode3.linkJointBreaksProcessed[ropeNode3.segmentLinks.Length])
{
ropeNode3.linkJoints[ropeNode3.segmentLinks.Length] = CreateJoint(ropeNode3.segmentLinks[ropeNode3.segmentLinks.Length - 1], gameObject2, gameObject2.transform.position);
ropeNode3.linkJointBreaksProcessed[ropeNode3.segmentLinks.Length] = false;
}
else
{
ropeNode3.linkJoints[ropeNode3.segmentLinks.Length] = null;
}
}
}
else if (RopeType == ERopeType.ImportBones)
{
ropeNode3.linkJointBreaksProcessed[0] = true;
}
if (ropeNode3.nTotalLinks > ropeNode3.nNumLinks && !ropeNode3.m_bExtensionInitialized)
{
ropeNode3.m_bExtensionInitialized = true;
}
}
if (m_bRopeStartInitialOrientationInitialized && RopeStart != null)
{
RopeStart.transform.localPosition = localPosition;
RopeStart.transform.localRotation = localRotation;
}
for (int n = 0; n < RopeNodes.Count; n++)
{
RopeNode ropeNode4 = RopeNodes[n];
if (ropeNode4.bInitialOrientationInitialized && ropeNode4.goNode != null)
{
ropeNode4.goNode.transform.localPosition = array3[n];
ropeNode4.goNode.transform.localRotation = array4[n];
}
}
num2 = 0;
if (RopeType == ERopeType.Procedural || RopeType == ERopeType.LinkedObjects)
{
for (int num6 = 0; num6 < RopeNodes.Count; num6++)
{
RopeNode ropeNode5 = RopeNodes[num6];
for (int num7 = 0; num7 < ropeNode5.segmentLinks.Length; num7++)
{
ropeNode5.segmentLinks[num7].transform.position = array[num2];
ropeNode5.segmentLinks[num7].transform.rotation = array2[num2];
num2++;
}
}
}
else if (RopeType == ERopeType.ImportBones)
{
for (int num8 = 0; num8 < ImportedBones.Length; num8++)
{
ImportedBones[num8].goBone.transform.position = array[num8];
ImportedBones[num8].goBone.transform.rotation = array2[num8];
}
}
CheckNeedsStartExitLockZ();
}
private ConfigurableJoint CreateJoint(GameObject goObject, GameObject goConnectedTo, Vector3 v3Pivot)
{
ConfigurableJoint configurableJoint = goObject.AddComponent<ConfigurableJoint>();
SetupJoint(configurableJoint);
configurableJoint.connectedBody = goConnectedTo.GetComponent<Rigidbody>();
configurableJoint.anchor = goObject.transform.InverseTransformPoint(v3Pivot);
return configurableJoint;
}
private void SetupJoint(ConfigurableJoint joint)
{
SoftJointLimit softJointLimit = new SoftJointLimit
{
contactDistance = 0f,
bounciness = 0f
};
JointDrive jointDrive = new JointDrive
{
positionSpring = LinkJointSpringValue,
positionDamper = LinkJointDamperValue,
maximumForce = LinkJointMaxForceValue
};
joint.axis = Vector3.right;
joint.secondaryAxis = Vector3.up;
joint.breakForce = LinkJointBreakForce;
joint.breakTorque = LinkJointBreakTorque;
joint.xMotion = ConfigurableJointMotion.Locked;
joint.yMotion = ConfigurableJointMotion.Locked;
joint.zMotion = ConfigurableJointMotion.Locked;
joint.angularXMotion = ((!Mathf.Approximately(LinkJointAngularXLimit, 0f)) ? ConfigurableJointMotion.Limited : ConfigurableJointMotion.Locked);
joint.angularYMotion = ((!Mathf.Approximately(LinkJointAngularYLimit, 0f)) ? ConfigurableJointMotion.Limited : ConfigurableJointMotion.Locked);
joint.angularZMotion = ((!Mathf.Approximately(LinkJointAngularZLimit, 0f)) ? ConfigurableJointMotion.Limited : ConfigurableJointMotion.Locked);
softJointLimit.limit = 0f - LinkJointAngularXLimit;
joint.lowAngularXLimit = softJointLimit;
softJointLimit.limit = LinkJointAngularXLimit;
joint.highAngularXLimit = softJointLimit;
softJointLimit.limit = LinkJointAngularYLimit;
joint.angularYLimit = softJointLimit;
softJointLimit.limit = LinkJointAngularZLimit;
joint.angularZLimit = softJointLimit;
joint.angularXDrive = jointDrive;
joint.angularYZDrive = jointDrive;
}
private Vector3 GetAxisVector(EAxis eAxis, float fLength)
{
switch (eAxis)
{
case EAxis.X:
return new Vector3(fLength, 0f, 0f);
case EAxis.Y:
return new Vector3(0f, fLength, 0f);
case EAxis.Z:
return new Vector3(0f, 0f, fLength);
case EAxis.MinusX:
return new Vector3(0f - fLength, 0f, 0f);
case EAxis.MinusY:
return new Vector3(0f, 0f - fLength, 0f);
case EAxis.MinusZ:
return new Vector3(0f, 0f, 0f - fLength);
default:
return Vector3.zero;
}
}
private float ExtendRopeLinear(float fLinearIncrement)
{
if (fLinearIncrement > 0f && Mathf.Approximately(m_fCurrentExtension, ExtensibleLength))
{
return 0f;
}
if (fLinearIncrement < 0f && Mathf.Approximately(m_fCurrentExtension, 0f))
{
return 0f;
}
RopeNode ropeNode = RopeNodes[RopeNodes.Count - 1];
bool flag = false;
float fCurrentExtension = m_fCurrentExtension;
float num = ropeNode.fLength / (float)ropeNode.nNumLinks;
Transform transform = ((RopeNodes.Count - 1 <= m_nFirstNonCoilNode) ? RopeStart.transform : RopeNodes[RopeNodes.Count - 2].goNode.transform);
Vector3 vector = transform.TransformDirection(ropeNode.m_v3LocalDirectionForward);
if (fLinearIncrement < 0f)
{
while (fLinearIncrement < 0f && ropeNode.m_nExtensionLinkIn > 0 && ropeNode.m_nExtensionLinkIn < ropeNode.segmentLinks.Length - 1 && !flag)
{
float num2 = Mathf.Max((0f - num) * 0.5f, fLinearIncrement);
if (Mathf.Abs(num2) > m_fCurrentExtension)
{
num2 = 0f - m_fCurrentExtension;
flag = true;
}
ropeNode.m_fExtensionRemainderIn += num2;
if (ropeNode.m_fExtensionRemainderIn < 0f - num)
{
num2 += Mathf.Abs(ropeNode.m_fExtensionRemainderIn - (0f - num));
ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn].transform.position = ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn - 1].transform.position;
ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn].transform.rotation = ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn - 1].transform.rotation;
SetExtensibleLinkToKinematic(ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn], true);
ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn].transform.parent = transform;
ropeNode.m_nExtensionLinkIn++;
ropeNode.m_nExtensionLinkOut = ropeNode.m_nExtensionLinkIn - 1;
ropeNode.m_fExtensionRemainderIn = 0f;
ropeNode.m_fExtensionRemainderOut = 0f;
}
else
{
float t = (0f - ropeNode.m_fExtensionRemainderIn) / num;
ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn].transform.position = transform.position + vector * (num + ropeNode.m_fExtensionRemainderIn);
ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn].transform.rotation = Quaternion.Slerp(ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn].transform.rotation, ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn - 1].transform.rotation, t);
SetExtensibleLinkToKinematic(ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn], true);
ropeNode.segmentLinks[ropeNode.m_nExtensionLinkIn].transform.parent = transform;
ropeNode.m_nExtensionLinkOut = ropeNode.m_nExtensionLinkIn;
ropeNode.m_fExtensionRemainderOut = num + ropeNode.m_fExtensionRemainderIn;
}
fLinearIncrement -= num2;
m_fCurrentExtension += num2;
}
}
else if (fLinearIncrement > 0f)
{
while (fLinearIncrement > 0f && ropeNode.m_nExtensionLinkOut > 0 && ropeNode.m_nExtensionLinkOut < ropeNode.segmentLinks.Length - 1 && !flag)
{
float num3 = Mathf.Min(num * 0.5f, fLinearIncrement);
if (m_fCurrentExtension + num3 > ExtensibleLength)
{
num3 = ExtensibleLength - m_fCurrentExtension;
flag = true;
}
ropeNode.m_fExtensionRemainderOut += num3;
if (ropeNode.m_fExtensionRemainderOut > num)
{
num3 -= ropeNode.m_fExtensionRemainderOut - num;
SetExtensibleLinkToKinematic(ropeNode.segmentLinks[ropeNode.m_nExtensionLinkOut], false);
ropeNode.segmentLinks[ropeNode.m_nExtensionLinkOut].transform.parent = base.transform;
ropeNode.m_nExtensionLinkOut--;
ropeNode.m_nExtensionLinkIn = ropeNode.m_nExtensionLinkOut + 1;
ropeNode.m_fExtensionRemainderIn = 0f;
ropeNode.m_fExtensionRemainderOut = 0f;
}
else
{
ropeNode.segmentLinks[ropeNode.m_nExtensionLinkOut].transform.position = transform.position + vector * ropeNode.m_fExtensionRemainderOut;
ropeNode.m_nExtensionLinkIn = ropeNode.m_nExtensionLinkOut;
ropeNode.m_fExtensionRemainderIn = 0f - num + ropeNode.m_fExtensionRemainderOut;
}
fLinearIncrement -= num3;
m_fCurrentExtension += num3;
}
}
return m_fCurrentExtension - fCurrentExtension;
}
private void SetExtensibleLinkToKinematic(GameObject link, bool bKinematic)
{
if (link.GetComponent<Rigidbody>().isKinematic == bKinematic)
{
return;
}
link.GetComponent<Rigidbody>().isKinematic = bKinematic;
if (link.GetComponent<Collider>() != null)
{
link.GetComponent<Collider>().enabled = !bKinematic;
}
UltimateRopeLink component = link.GetComponent<UltimateRopeLink>();
if (component != null)
{
component.ExtensibleKinematic = bKinematic;
}
ConfigurableJoint component2 = link.GetComponent<ConfigurableJoint>();
if ((bool)component2)
{
if (bKinematic)
{
component2.breakForce = float.PositiveInfinity;
component2.breakTorque = float.PositiveInfinity;
}
else
{
component2.breakForce = LinkJointBreakForce;
component2.breakTorque = LinkJointBreakTorque;
}
}
}
private void SetupCoilBones(float fCoilLength)
{
float num = 0f;
float num2 = CoilWidth * -0.5f + RopeDiameter * 0.5f;
float num3 = CoilDiameter * 0.5f + RopeDiameter * 0.5f;
float num4 = 0f;
float num5 = 1f;
float num6 = -1f;
float num7 = Vector3.Distance(CoilObject.transform.position, RopeStart.transform.position) + CoilDiameter;
float num8 = fCoilLength + num7;
float num9 = 0f;
float num10 = 0f;
float num11 = 0f;
int num12 = 0;
RopeNode ropeNode = RopeNodes[0];
Vector3 localPosition = ropeNode.goNode.transform.localPosition;
Quaternion localRotation = ropeNode.goNode.transform.localRotation;
Vector3 localScale = ropeNode.goNode.transform.localScale;
if (ropeNode.bInitialOrientationInitialized)
{
ropeNode.goNode.transform.localPosition = ropeNode.v3InitialLocalPos;
ropeNode.goNode.transform.localRotation = ropeNode.qInitialLocalRot;
ropeNode.goNode.transform.localScale = ropeNode.v3InitialLocalScale;
}
Vector3 vector = -CoilObject.transform.TransformDirection(GetAxisVector(CoilAxisRight, 1f));
Vector3 vector2 = CoilObject.transform.TransformDirection(GetAxisVector(CoilAxisUp, 1f));
Vector3 forward = Vector3.Cross(vector2, vector);
Quaternion rotation = Quaternion.LookRotation(forward, vector2);
ropeNode.goNode.transform.localPosition = localPosition;
ropeNode.goNode.transform.localRotation = localRotation;
ropeNode.goNode.transform.localScale = localScale;
float num13 = (RopeNodes[0].fLength + num7) / (float)RopeNodes[0].nNumLinks;
for (int i = 0; i < RopeNodes[0].segmentLinks.Length; i++)
{
m_afCoilBoneRadiuses[i] = num3;
m_afCoilBoneAngles[i] = num4;
m_afCoilBoneX[i] = num2;
Vector3 vector3 = CoilObject.transform.position + vector2 * num3 + vector * num2;
num9 = (vector3 - RopeStart.transform.position).magnitude;
num += num13;
num12++;
float num14 = num8 - num9;
if (num > num14)
{
num11 = num - num14;
num10 = num4 - num11 / (num3 * (float)Math.PI * 2f) * 360f;
m_fCurrentCoilRopeRadius = num3;
m_fCurrentCoilTurnsLeft = num4 / 360f;
break;
}
float num15 = num13 / (num3 * (float)Math.PI * 2f) * 360f;
float num16 = num3 * (float)Math.PI * 2f / num13;
num4 += num15;
if (num6 > 0f)
{
num3 += RopeDiameter / num16;
num6 -= num15;
}
else
{
num2 += RopeDiameter * num5 / num16;
}
if (num5 > 0f && num2 > CoilWidth * 0.5f - RopeDiameter * 0.5f)
{
num2 = CoilWidth * 0.5f - RopeDiameter * 0.5f;
num6 = 360f;
num5 = -1f;
}
if (num5 < 0f && num2 < CoilWidth * -0.5f + RopeDiameter * 0.5f)
{
num2 = CoilWidth * -0.5f + RopeDiameter * 0.5f;
num6 = 360f;
num5 = 1f;
}
}
for (int j = 0; j < num12; j++)
{
m_afCoilBoneAngles[j] -= num10;
RopeNodes[0].segmentLinks[j].transform.position = CoilObject.transform.position + vector2 * m_afCoilBoneRadiuses[j];
RopeNodes[0].segmentLinks[j].transform.rotation = rotation;
RopeNodes[0].segmentLinks[j].transform.RotateAround(CoilObject.transform.position, -vector, m_afCoilBoneAngles[j]);
RopeNodes[0].segmentLinks[j].transform.position += vector * m_afCoilBoneX[j];
}
Vector3 vector4 = CoilObject.transform.position + vector2 * num3 + vector * num2;
Vector3 normalized = (RopeStart.transform.position - vector4).normalized;
num = (RopeNodes[0].segmentLinks[num12 - 1].transform.position - vector4).magnitude;
float magnitude = (RopeStart.transform.position - vector4).magnitude;
Quaternion rotation2 = Quaternion.LookRotation((RopeStart.transform.position - CoilObject.transform.position).normalized, vector2);
for (int k = num12; k < RopeNodes[0].segmentLinks.Length; k++)
{
num += num13;
if (num < magnitude)
{
RopeNodes[0].segmentLinks[k].transform.position = vector4 + normalized * num;
RopeNodes[0].segmentLinks[k].transform.rotation = rotation2;
}
else
{
RopeNodes[0].segmentLinks[k].transform.position = RopeStart.transform.position;
RopeNodes[0].segmentLinks[k].transform.rotation = rotation2;
}
}
m_fCurrentCoilLength = fCoilLength;
}
private Quaternion GetLinkedObjectLocalRotation(float fTwistAngle = 0f)
{
if (LinkAxis == EAxis.X)
{
return Quaternion.LookRotation(Vector3.right) * Quaternion.AngleAxis(fTwistAngle, Vector3.right);
}
if (LinkAxis == EAxis.Y)
{
return Quaternion.LookRotation(Vector3.up) * Quaternion.AngleAxis(fTwistAngle, Vector3.up);
}
if (LinkAxis == EAxis.Z)
{
return Quaternion.LookRotation(Vector3.forward) * Quaternion.AngleAxis(fTwistAngle, Vector3.forward);
}
if (LinkAxis == EAxis.MinusX)
{
return Quaternion.LookRotation(-Vector3.right) * Quaternion.AngleAxis(fTwistAngle, -Vector3.right);
}
if (LinkAxis == EAxis.MinusY)
{
return Quaternion.LookRotation(-Vector3.up) * Quaternion.AngleAxis(fTwistAngle, -Vector3.up);
}
if (LinkAxis == EAxis.MinusZ)
{
return Quaternion.LookRotation(-Vector3.forward) * Quaternion.AngleAxis(fTwistAngle, -Vector3.forward);
}
return Quaternion.identity;
}
private float GetLinkedObjectScale(float fSegmentLength, int nNumLinks)
{
if (LinkObject == null)
{
return 0f;
}
MeshFilter component = LinkObject.GetComponent<MeshFilter>();
if (component == null)
{
return 0f;
}
float num = 0f;
if (RopeType == ERopeType.LinkedObjects)
{
if (LinkAxis == EAxis.X || LinkAxis == EAxis.MinusX)
{
num = component.sharedMesh.bounds.size.x;
}
if (LinkAxis == EAxis.Y || LinkAxis == EAxis.MinusY)
{
num = component.sharedMesh.bounds.size.y;
}
if (LinkAxis == EAxis.Z || LinkAxis == EAxis.MinusZ)
{
num = component.sharedMesh.bounds.size.z;
}
}
float num2 = fSegmentLength / (float)nNumLinks - LinkOffsetObject * (fSegmentLength / (float)(nNumLinks - 1));
return num2 / num;
}
private float GetLinkDiameter()
{
if (RopeType == ERopeType.Procedural)
{
return RopeDiameter;
}
if (RopeType == ERopeType.LinkedObjects)
{
if (LinkObject == null)
{
return 0f;
}
MeshFilter component = LinkObject.GetComponent<MeshFilter>();
if (component == null)
{
return 0f;
}
float result = 0f;
if (RopeType == ERopeType.LinkedObjects)
{
if (LinkAxis == EAxis.X || LinkAxis == EAxis.MinusX)
{
result = Mathf.Max(component.sharedMesh.bounds.size.y, component.sharedMesh.bounds.size.z);
}
if (LinkAxis == EAxis.Y || LinkAxis == EAxis.MinusY)
{
result = Mathf.Max(component.sharedMesh.bounds.size.x, component.sharedMesh.bounds.size.z);
}
if (LinkAxis == EAxis.Z || LinkAxis == EAxis.MinusZ)
{
result = Mathf.Max(component.sharedMesh.bounds.size.x, component.sharedMesh.bounds.size.y);
}
}
return result;
}
if (RopeType == ERopeType.ImportBones)
{
return BoneColliderDiameter;
}
return 0f;
}
private Vector3 GetLinkAxisOffset(float fValue)
{
EAxis eAxis = EAxis.Z;
if (RopeType == ERopeType.LinkedObjects)
{
eAxis = LinkAxis;
}
if (RopeType == ERopeType.ImportBones)
{
eAxis = BoneAxis;
}
switch (eAxis)
{
case EAxis.X:
return new Vector3(fValue, 0f, 0f);
case EAxis.Y:
return new Vector3(0f, fValue, 0f);
case EAxis.Z:
return new Vector3(0f, 0f, fValue);
case EAxis.MinusX:
return new Vector3(0f - fValue, 0f, 0f);
case EAxis.MinusY:
return new Vector3(0f, 0f - fValue, 0f);
case EAxis.MinusZ:
return new Vector3(0f, 0f, 0f - fValue);
default:
return new Vector3(0f, 0f, fValue);
}
}
private int GetLinkAxisIndex()
{
EAxis eAxis = EAxis.Z;
if (RopeType == ERopeType.LinkedObjects)
{
eAxis = LinkAxis;
}
if (RopeType == ERopeType.ImportBones)
{
eAxis = BoneAxis;
}
switch (eAxis)
{
case EAxis.X:
return 0;
case EAxis.Y:
return 1;
case EAxis.Z:
return 2;
case EAxis.MinusX:
return 0;
case EAxis.MinusY:
return 1;
case EAxis.MinusZ:
return 2;
default:
return 2;
}
}
private bool GetLinkBoxColliderCenterAndSize(float fLinkLength, float fRopeDiameter, ref Vector3 v3CenterInOut, ref Vector3 v3SizeInOut)
{
if (RopeType == ERopeType.Procedural)
{
v3CenterInOut = Vector3.zero;
v3SizeInOut = new Vector3(fRopeDiameter, fRopeDiameter, fLinkLength);
return true;
}
if (RopeType == ERopeType.LinkedObjects)
{
MeshFilter component = LinkObject.GetComponent<MeshFilter>();
if (component == null)
{
return false;
}
v3CenterInOut = component.sharedMesh.bounds.center;
v3SizeInOut = component.sharedMesh.bounds.size;
return true;
}
if (RopeType == ERopeType.ImportBones)
{
if (BoneAxis == EAxis.X)
{
v3SizeInOut = new Vector3(fLinkLength, fRopeDiameter, fRopeDiameter);
}
if (BoneAxis == EAxis.Y)
{
v3SizeInOut = new Vector3(fRopeDiameter, fLinkLength, fRopeDiameter);
}
if (BoneAxis == EAxis.Z)
{
v3SizeInOut = new Vector3(fRopeDiameter, fRopeDiameter, fLinkLength);
}
if (BoneAxis == EAxis.MinusX)
{
v3SizeInOut = new Vector3(fLinkLength, fRopeDiameter, fRopeDiameter);
}
if (BoneAxis == EAxis.MinusY)
{
v3SizeInOut = new Vector3(fRopeDiameter, fLinkLength, fRopeDiameter);
}
if (BoneAxis == EAxis.MinusZ)
{
v3SizeInOut = new Vector3(fRopeDiameter, fRopeDiameter, fLinkLength);
}
return true;
}
v3CenterInOut = Vector3.zero;
v3SizeInOut = new Vector3(fRopeDiameter, fRopeDiameter, fLinkLength);
return true;
}
private bool BuildImportedBoneList(GameObject goBoneFirst, GameObject goBoneLast, List<int> ListImportBonesStatic, List<int> ListImportBonesNoCollider, out List<RopeBone> outListImportedBones, out string strErrorMessage)
{
strErrorMessage = string.Empty;
outListImportedBones = new List<RopeBone>();
int num = 0;
int num2 = 0;
int num3 = 0;
int num4 = 0;
int num5 = goBoneFirst.name.Length - 1;
while (num5 >= 0 && char.IsDigit(goBoneFirst.name[num5]))
{
num++;
num5--;
}
if (num == 0)
{
strErrorMessage = "First bone name needs to end with digits in order to infer bone sequence";
return false;
}
num3 = int.Parse(goBoneFirst.name.Substring(goBoneFirst.name.Length - num));
int num6 = goBoneLast.name.Length - 1;
while (num6 >= 0 && char.IsDigit(goBoneLast.name[num6]))
{
num2++;
num6--;
}
if (num2 == 0)
{
strErrorMessage = "Last bone name needs to end with digits in order to infer bone sequence";
return false;
}
num4 = int.Parse(goBoneLast.name.Substring(goBoneLast.name.Length - num2));
string text = goBoneFirst.name.Substring(0, goBoneFirst.name.Length - num);
string text2 = goBoneLast.name.Substring(0, goBoneLast.name.Length - num2);
if (text != text2)
{
strErrorMessage = string.Format("First bone name prefix ({0}) and last bone name prefix ({1}) don't match", text, text2);
return false;
}
if (BoneFirst.transform.parent == null || BoneLast.transform.parent == null)
{
strErrorMessage = string.Format("First and last bones need to share a common parent object");
return false;
}
GameObject gameObject = ((!BoneLast.transform.IsChildOf(BoneFirst.transform)) ? BoneLast.transform.parent.gameObject : BoneFirst.transform.parent.gameObject);
if (BuildImportedBoneListTry(gameObject, text, num3, num4, num, num2, ListImportBonesStatic, ListImportBonesNoCollider, out outListImportedBones, ref strErrorMessage))
{
return true;
}
gameObject = gameObject.transform.root.gameObject;
string text3 = string.Format("Try1: {0}\nTry2: ", strErrorMessage);
if (BuildImportedBoneListTry(gameObject, text, num3, num4, num, num2, ListImportBonesStatic, ListImportBonesNoCollider, out outListImportedBones, ref strErrorMessage))
{
return true;
}
strErrorMessage = text3 + strErrorMessage;
return false;
}
private bool BuildImportedBoneListTry(GameObject goRoot, string strPrefix, int nIndexFirst, int nIndexLast, int nDigitsFirst, int nDigitsLast, List<int> ListImportBonesStatic, List<int> ListImportBonesNoCollider, out List<RopeBone> outListImportedBones, ref string strErrorMessage)
{
outListImportedBones = new List<RopeBone>();
Dictionary<string, GameObject> outHashString2GameObjects = new Dictionary<string, GameObject>();
if (!BuildBoneHashString2GameObject(goRoot, goRoot, ref outHashString2GameObjects, ref strErrorMessage))
{
return false;
}
Dictionary<GameObject, Transform> dictionary = new Dictionary<GameObject, Transform>();
int num = ((nIndexFirst <= nIndexLast) ? 1 : (-1));
for (int i = nIndexFirst; (num != 1) ? (i >= nIndexLast) : (i <= nIndexLast); i += num)
{
bool flag = false;
for (int j = nDigitsFirst; j <= nDigitsLast; j++)
{
string key = strPrefix + i.ToString("D" + j);
if (outHashString2GameObjects.ContainsKey(key))
{
RopeBone ropeBone = new RopeBone();
ropeBone.goBone = outHashString2GameObjects[key];
ropeBone.tfParent = ropeBone.goBone.transform.parent;
ropeBone.bCreatedCollider = !ListImportBonesNoCollider.Contains(i);
ropeBone.bIsStatic = ListImportBonesStatic.Contains(i);
ropeBone.nOriginalLayer = ropeBone.goBone.layer;
outListImportedBones.Add(ropeBone);
dictionary.Add(ropeBone.goBone, ropeBone.goBone.transform);
flag = true;
break;
}
}
if (!flag)
{
strErrorMessage = string.Format("Bone not found (bone number suffix {0}, trying to find below node {1}'s hierarchy)", i, goRoot.name);
return false;
}
}
foreach (RopeBone outListImportedBone in outListImportedBones)
{
Transform parent = outListImportedBone.goBone.transform.parent;
while (parent != null && dictionary.ContainsKey(parent.gameObject))
{
parent = parent.parent;
}
if (parent == null)
{
parent = goRoot.transform;
}
dictionary[outListImportedBone.goBone] = parent;
}
foreach (RopeBone outListImportedBone2 in outListImportedBones)
{
Transform transform = dictionary[outListImportedBone2.goBone];
GameObject gameObject = new GameObject();
outListImportedBone2.v3OriginalLocalScale = outListImportedBone2.goBone.transform.localScale;
gameObject.transform.position = outListImportedBone2.goBone.transform.position;
gameObject.transform.rotation = outListImportedBone2.goBone.transform.rotation;
gameObject.transform.parent = transform.transform;
outListImportedBone2.v3OriginalLocalPos = gameObject.transform.localPosition;
outListImportedBone2.qOriginalLocalRot = gameObject.transform.localRotation;
outListImportedBone2.tfNonBoneParent = transform;
UnityEngine.Object.DestroyImmediate(gameObject);
if (outListImportedBone2.bIsStatic)
{
outListImportedBone2.goBone.transform.parent = transform;
}
else
{
outListImportedBone2.goBone.transform.parent = base.transform;
}
}
return true;
}
private bool BuildBoneHashString2GameObject(GameObject goRoot, GameObject goCurrent, ref Dictionary<string, GameObject> outHashString2GameObjects, ref string strErrorMessage)
{
for (int i = 0; i < goCurrent.transform.childCount; i++)
{
GameObject goCurrent2 = goCurrent.transform.GetChild(i).gameObject;
if (!BuildBoneHashString2GameObject(goRoot, goCurrent2, ref outHashString2GameObjects, ref strErrorMessage))
{
return false;
}
}
if (outHashString2GameObjects.ContainsKey(goCurrent.name))
{
strErrorMessage = string.Format("Bone name {0} is found more than once in GameObject {1}'s hierarchy. The name must be unique.", goCurrent.name, goRoot.name);
return false;
}
outHashString2GameObjects.Add(goCurrent.name, goCurrent);
return true;
}
private bool ParseBoneIndices(string strBoneList, out List<int> outListBoneIndices, out string strErrorMessage)
{
outListBoneIndices = new List<int>();
strErrorMessage = string.Empty;
if (strBoneList.Length == 0)
{
return true;
}
string[] array = strBoneList.Split(',');
for (int i = 0; i < array.Length; i++)
{
string[] array2 = array[i].Split('-');
if (array2.Length == 1)
{
int num = 0;
try
{
num = int.Parse(array2[0]);
}
catch
{
strErrorMessage = "Field " + (i + 1) + " is invalid (error parsing number: " + array2[0] + ")";
return false;
}
outListBoneIndices.Add(num);
continue;
}
if (array2.Length == 2)
{
int num2 = 0;
int num3 = 0;
try
{
num2 = int.Parse(array2[0]);
}
catch
{
strErrorMessage = "Field " + (i + 1) + " is invalid (error parsing range start: " + array2[0] + ")";
return false;
}
try
{
num3 = int.Parse(array2[1]);
}
catch
{
strErrorMessage = "Field " + (i + 1) + " is invalid (error parsing range end: " + array2[1] + ")";
return false;
}
if (num3 < num2)
{
strErrorMessage = "Field " + (i + 1) + " has invalid range (" + num2 + " is greater than " + num3 + ")";
return false;
}
for (int j = num2; j <= num3; j++)
{
outListBoneIndices.Add(j);
}
continue;
}
strErrorMessage = "Field " + (i + 1) + " has invalid range (field content: " + array[i] + ")";
return false;
}
outListBoneIndices.Sort();
List<int> list = new List<int>();
int num4 = -1;
foreach (int outListBoneIndex in outListBoneIndices)
{
if (outListBoneIndex != num4)
{
num4 = outListBoneIndex;
list.Add(outListBoneIndex);
}
}
outListBoneIndices = list;
return true;
}
}