rise-and-swine/Assets/Scripts/Assembly-CSharp/Rope.cs
2023-02-25 23:04:03 -05:00

509 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
public class Rope : BasePart
{
public override Vector3 Position
{
get
{
return this.m_nodes[this.m_nodes.Count / 2].gameObject.transform.position;
}
}
public bool IsCut()
{
return this.m_ropeCut;
}
public bool IsLeftPart(Collider collider)
{
if (!this.m_ropeCut)
{
return true;
}
for (int i = 0; i < this.m_cutIndex; i++)
{
if (this.m_nodes[i].gameObject.GetComponent<Collider>() == collider)
{
return true;
}
}
return false;
}
public BasePart LeftPart
{
get
{
return this.m_leftPart;
}
}
public BasePart RightPart
{
get
{
return this.m_rightPart;
}
}
public GameObject FirstSegment
{
get
{
return this.m_nodes[0].gameObject;
}
}
public GameObject LastSegment
{
get
{
return this.m_nodes[this.m_nodes.Count - 1].gameObject;
}
}
public static Vector3 PositionOnSpline(List<Vector3> controlPoints, float t)
{
int count = controlPoints.Count;
int num = Mathf.FloorToInt(t * (float)(count - 1));
Vector3 a = controlPoints[Mathf.Clamp(num - 1, 0, count - 1)];
Vector3 b = controlPoints[Mathf.Clamp(num, 0, count - 1)];
Vector3 c = controlPoints[Mathf.Clamp(num + 1, 0, count - 1)];
Vector3 d = controlPoints[Mathf.Clamp(num + 2, 0, count - 1)];
float i = t * (float)(count - 1) - (float)num;
return MathsUtil.CatmullRomInterpolate(a, b, c, d, i);
}
public override void Awake()
{
base.Awake();
if (this.m_gridVisualizationNode)
{
this.m_gridVisualizationNode.SetActive(true);
}
}
private void Start()
{
if (base.rigidbody)
{
base.rigidbody.isKinematic = true;
}
this.m_lineRenderer = base.GetComponent<LineRenderer>();
if (!this.m_lineRenderer)
{
this.m_lineRenderer = base.gameObject.AddComponent<LineRenderer>();
}
this.m_lineRenderer.useWorldSpace = true;
this.m_lineRenderer.SetWidth(0.2f, 0.2f);
Color color = new Color(255f, 60f, 90f);
this.m_lineRenderer.SetColors(color, color);
this.m_lineRenderer.sharedMaterial = this.m_material;
}
private void CreateSecondLineRenderer()
{
this.m_lineRenderer2 = new GameObject
{
name = "LineRenderer2",
transform =
{
parent = base.transform
}
}.AddComponent<LineRenderer>();
this.m_lineRenderer2.useWorldSpace = true;
this.m_lineRenderer2.SetWidth(0.2f, 0.2f);
Color color = new Color(255f, 60f, 90f);
this.m_lineRenderer2.SetColors(color, color);
this.m_lineRenderer2.sharedMaterial = this.m_material;
}
public override void Initialize()
{
if (this.RightPart && this.RightPart.GetComponent<Rope>())
{
Rope.Node node = this.m_nodes[this.m_nodes.Count - 1];
node.gameObject.transform.position = this.RightPart.GetComponent<Rope>().FirstSegment.transform.position;
this.CreateJoint(node.gameObject, this.RightPart.GetComponent<Rope>().FirstSegment.GetComponent<Rigidbody>());
}
base.contraption.ChangeOneShotPartAmount(BasePart.BaseType(this.m_partType), this.EffectDirection(), 1);
if (this.m_gridVisualizationNode)
{
this.m_gridVisualizationNode.SetActive(false);
}
}
public int FindInteractiveSegment(Vector3 position)
{
int num = -1;
float num2 = 1000f;
for (int i = 0; i < this.m_nodes.Count; i++)
{
Vector3 position2 = this.m_nodes[i].gameObject.transform.position;
position2.z = 0f;
float num3 = Vector3.Distance(position2, position);
if (num3 <= this.m_interactiveRadius && num3 < num2)
{
num2 = num3;
num = i;
num = Mathf.Clamp(num, 2, this.m_nodes.Count - 2);
}
}
return num;
}
public override bool IsInInteractiveRadius(Vector3 position)
{
return this.FindInteractiveSegment(position) != -1;
}
protected override void OnTouch(bool hasPosition, Vector3 touchPosition)
{
if (!this.m_ropeCut)
{
int num = -1;
if (hasPosition)
{
num = this.FindInteractiveSegment(touchPosition);
}
if (num != -1)
{
this.Cut(num);
}
else
{
this.Cut(4);
}
}
}
private void Update()
{
if (!this.m_ropeCut)
{
this.RenderRope(this.m_lineRenderer, 0, this.m_nodes.Count);
}
else
{
this.RenderRope(this.m_lineRenderer, 0, this.m_cutIndex);
this.RenderRope(this.m_lineRenderer2, this.m_cutIndex, this.m_nodes.Count);
}
}
private void RenderRope(LineRenderer lineRenderer, int startIndex, int endIndex)
{
this.m_splinePoints.Clear();
Rope rope = null;
if (this.m_leftPart)
{
rope = this.m_leftPart.GetComponent<Rope>();
}
for (int i = startIndex; i < endIndex; i++)
{
Rigidbody rigidbody = this.m_nodes[i].rigidbody;
Vector3 position = rigidbody.gameObject.transform.position;
if (i == 0 && rope)
{
position = rope.LastSegment.transform.position;
}
position.z = -1f;
this.m_splinePoints.Add(position);
}
if (this.m_splinePoints.Count > 1)
{
lineRenderer.SetVertexCount(20);
for (int j = 0; j < 20; j++)
{
float t = (float)j / 19f;
lineRenderer.SetPosition(j, Rope.PositionOnSpline(this.m_splinePoints, t));
}
}
else
{
lineRenderer.SetVertexCount(0);
}
}
private Joint CreateJoint(GameObject target, Rigidbody connectedBody)
{
HingeJoint hingeJoint = target.AddComponent<HingeJoint>();
hingeJoint.connectedBody = connectedBody;
hingeJoint.axis = Vector3.forward;
hingeJoint.breakForce = float.PositiveInfinity;
hingeJoint.breakTorque = float.PositiveInfinity;
hingeJoint.enablePreprocessing = false;
this.AddConnectedBodyToJoint(hingeJoint, connectedBody);
return hingeJoint;
}
private void AddConnectedBodyToJoint(Joint joint, Rigidbody connectedBody)
{
joint.connectedBody = connectedBody;
if (connectedBody != null)
{
joint.anchor = connectedBody.position - joint.transform.position;
}
}
public void Create(BasePart leftPart, BasePart rightPart)
{
this.m_leftPart = leftPart;
this.m_rightPart = rightPart;
Vector3 vector = base.transform.position - 0.5f * base.transform.right;
Quaternion quaternion = base.transform.rotation;
float num = 74.4f;
quaternion = Quaternion.AngleAxis(-num, Vector3.forward);
if (this.m_gridRotation != BasePart.GridRotation.Deg_0)
{
quaternion *= Quaternion.AngleAxis(-90f, Vector3.forward);
}
int num2 = 8;
Joint joint = null;
if (leftPart && !leftPart.GetComponent<Rope>())
{
joint = this.CreateJoint(leftPart.gameObject, null);
}
for (int i = 0; i < num2; i++)
{
if (i == num2 - 1 && rightPart && !rightPart.GetComponent<Rope>())
{
vector = base.transform.position + 0.5f * base.transform.right;
}
GameObject gameObject = UnityEngine.Object.Instantiate<GameObject>(this.m_segment, vector, quaternion);
Rigidbody component = gameObject.GetComponent<Rigidbody>();
if (joint != null)
{
this.AddConnectedBodyToJoint(joint, component);
joint = null;
}
this.m_nodes.Add(new Rope.Node(gameObject, component, joint));
if (i == num2 - 1 && rightPart && !rightPart.GetComponent<Rope>())
{
joint = this.CreateJoint(rightPart.gameObject, component);
}
vector += 0.5f * (quaternion * Vector3.right);
quaternion = ((i % 2 != 0) ? Quaternion.AngleAxis(-num, Vector3.forward) : Quaternion.AngleAxis(num, Vector3.forward));
if (this.m_gridRotation != BasePart.GridRotation.Deg_0)
{
quaternion *= Quaternion.AngleAxis(-90f, Vector3.forward);
}
gameObject.transform.parent = base.transform;
}
if (base.renderer)
{
base.renderer.enabled = false;
}
}
private void Cut(int nodeIndex)
{
if (!this.m_ropeCut)
{
base.contraption.ChangeOneShotPartAmount(BasePart.BaseType(this.m_partType), this.EffectDirection(), -1);
this.m_ropeCut = true;
this.m_cutIndex = nodeIndex;
this.CreateSecondLineRenderer();
int num = this.m_cutIndex;
this.m_lineRenderer.material.mainTextureScale = new Vector2(20f * (float)(num - 1) / (float)(this.m_nodes.Count - 1), 1f);
num = this.m_nodes.Count - num;
this.m_lineRenderer2.material.mainTextureScale = new Vector2(20f * (float)(num - 1) / (float)(this.m_nodes.Count - 1), 1f);
base.contraption.FindComponentsConnectedByRope();
}
}
private float Sigmoid(float t)
{
return 1f / (1f + Mathf.Exp(-t));
}
private float ResponseCurve(float t)
{
return (this.Sigmoid(8f * (t - 0.5f)) - 0.01798f) / 0.9641f;
}
public void FixedUpdate()
{
if (this.m_nodes.Count == 0)
{
return;
}
float num = Mathf.Max(this.m_nodes[0].rigidbody.velocity.magnitude, this.m_nodes[this.m_nodes.Count - 1].rigidbody.velocity.magnitude);
Rope rope = (!(this.m_rightPart != null)) ? null : this.m_rightPart.GetComponent<Rope>();
if (rope)
{
Vector3 position = this.m_nodes[this.m_nodes.Count - 1].rigidbody.position;
Vector3 position2 = rope.FirstSegment.GetComponent<Rigidbody>().position;
if (Vector3.Distance(position, position2) > 0.1f)
{
rope.FirstSegment.GetComponent<Rigidbody>().position = position;
}
}
for (int i = 0; i < this.m_nodes.Count; i++)
{
Rigidbody rigidbody = this.m_nodes[i].rigidbody;
Rigidbody rigidbody2;
if (i == 0)
{
rigidbody2 = rigidbody;
}
else
{
rigidbody2 = this.m_nodes[i - 1].rigidbody;
}
Rigidbody rigidbody3;
if (i == this.m_nodes.Count - 1)
{
rigidbody3 = rigidbody;
}
else
{
rigidbody3 = this.m_nodes[i + 1].rigidbody;
}
float magnitude = (rigidbody.velocity - 0.4f * rigidbody2.velocity - 0.4f * rigidbody3.velocity).magnitude;
rigidbody.AddForce(-0.02f * magnitude * magnitude * rigidbody.velocity.normalized, ForceMode.Force);
rigidbody.drag = 0.5f + 6f / (1f + 4f * num * num);
}
for (int j = 1; j < this.m_nodes.Count; j++)
{
if (!this.m_ropeCut || j != this.m_cutIndex)
{
Rigidbody rigidbody4 = this.m_nodes[j - 1].rigidbody;
Rigidbody rigidbody5 = this.m_nodes[j].rigidbody;
Vector3 a = rigidbody5.gameObject.transform.position - rigidbody4.gameObject.transform.position;
float num2 = a.magnitude;
if (num2 > 0.5f)
{
num2 -= 0.5f;
if (num2 < 1f)
{
num2 = Mathf.Pow(num2, 0.75f);
}
else
{
num2 = Mathf.Pow(num2, 2f);
}
num2 = Mathf.Clamp(num2, 0f, 2f);
a = num2 * a.normalized;
Vector3 a2 = -a;
rigidbody4.AddForce(70f * a, ForceMode.Force);
rigidbody5.AddForce(70f * a2, ForceMode.Force);
}
else if (num2 < 0.4f)
{
rigidbody4.AddForce(50f * (num2 - 0.4f) * a.normalized, ForceMode.Force);
rigidbody5.AddForce(-50f * (num2 - 0.4f) * a.normalized, ForceMode.Force);
}
}
}
if (!this.m_ropeCut)
{
this.PullEndpoints();
}
}
private void PullEndpoints()
{
float num = 0f;
for (int i = 1; i < this.m_nodes.Count; i++)
{
Rigidbody rigidbody = this.m_nodes[i - 1].rigidbody;
Rigidbody rigidbody2 = this.m_nodes[i].rigidbody;
if (rigidbody && rigidbody2)
{
float num2 = Vector3.Distance(rigidbody.position, rigidbody2.position);
if (i > 1 && i < this.m_nodes.Count - 2)
{
if (num2 > 1.25f)
{
this.Cut(i);
return;
}
}
else if (num2 > 1.75f)
{
this.Cut(i);
return;
}
num += num2;
}
}
float num3 = 0.5f * (float)this.m_nodes.Count;
float num4 = num / (1.18f * num3) - 1f;
float num5 = 0.4f;
num4 = num5 * this.ResponseCurve(num4 / num5);
num4 = Mathf.Clamp(num4, 0f, num5);
float num6 = num4 - this.m_previousStretchFactor;
this.m_previousStretchFactor = num4;
if (num > 1.18f * num3)
{
Rigidbody rigidbody3 = this.m_nodes[0].rigidbody;
Rigidbody rigidbody4 = this.m_nodes[1].rigidbody;
Vector3 position = rigidbody3.position;
Vector3 position2 = rigidbody4.position;
if (num6 < 0f)
{
num4 *= 0.7f;
}
float num7 = 750f;
float num8 = num7 * num4;
num8 = Mathf.Clamp(num8, 0f, 300f);
Vector3 force = num8 * (position2 - position).normalized;
if (this.LeftPart)
{
rigidbody3.AddForceAtPosition(force, position, ForceMode.Force);
}
rigidbody3 = this.m_nodes[this.m_nodes.Count - 1].rigidbody;
rigidbody4 = this.m_nodes[this.m_nodes.Count - 2].rigidbody;
position = rigidbody3.position;
position2 = rigidbody4.position;
force = num8 * (position2 - position).normalized;
if (this.RightPart)
{
rigidbody3.AddForceAtPosition(force, position, ForceMode.Force);
}
}
}
public GameObject m_segment;
public Material m_material;
public GameObject m_gridVisualizationNode;
private BasePart m_leftPart;
private BasePart m_rightPart;
private List<Rope.Node> m_nodes = new List<Rope.Node>();
private LineRenderer m_lineRenderer;
private LineRenderer m_lineRenderer2;
private bool m_ropeCut;
private int m_cutIndex;
private List<Vector3> m_splinePoints = new List<Vector3>();
private float m_previousStretchFactor;
private struct Node
{
public Node(GameObject gameObject, Rigidbody rigidbody, Joint joint)
{
this.gameObject = gameObject;
this.rigidbody = rigidbody;
this.joint = joint;
}
public GameObject gameObject;
public Rigidbody rigidbody;
public Joint joint;
}
}