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

263 lines
5.8 KiB
C#

using System;
using UnityEngine;
[AddComponentMenu("Modifiers/Attractor Shape")]
public class MegaAttractorShape : MegaModifier
{
public MegaShape shape;
public int curve;
public MegaAttractType attractType;
public float distance;
public float rotate;
public float force;
public float slide;
public AnimationCurve crv = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(1f, 1f));
public int itercount = 4;
private int k;
private Vector3 tangent;
private float alpha;
private Vector3 delta;
private Vector3 nvp;
private Vector3 dir = Vector3.zero;
private Matrix4x4 rottm = Matrix4x4.identity;
private float slidealpha;
private Matrix4x4 swtm;
private Matrix4x4 swltm;
private Matrix4x4 lwtm;
private Matrix4x4 wltm;
public float limit = 1f;
private float limit2;
private Vector3 shapepos;
public bool flat = true;
public bool splinechanged = true;
private float positiveInfinity;
private float num2;
public Vector3[] points;
private Vector3 tp = Vector3.zero;
private Vector3 qc = Vector3.zero;
public override string ModName()
{
return "Attractor Shape";
}
public override string GetHelpURL()
{
return "?page_id=338";
}
public Vector3 FindNearestPointWorld(Vector3 p, int iterations, ref float alpha)
{
return swtm.MultiplyPoint3x4(FindNearestPoint(swltm.MultiplyPoint3x4(p), iterations, ref alpha));
}
private void Start()
{
PrepareShape();
}
private void PrepareShape()
{
if (points == null || points.Length == 0)
{
points = new Vector3[101];
}
int num = 0;
int num2 = 0;
for (float num3 = 0f; num3 <= 1f; num3 += 0.01f)
{
points[num2++] = shape.splines[curve].Interpolate(num3, true, ref num);
}
}
private void Find(Vector3 p)
{
positiveInfinity = float.PositiveInfinity;
num2 = 0f;
for (int i = 0; i < 101; i++)
{
float num = (float)i / 100f;
float sqrMagnitude = (points[i] - p).sqrMagnitude;
if (positiveInfinity > sqrMagnitude)
{
positiveInfinity = sqrMagnitude;
num2 = num;
}
}
}
public Vector3 FindNearestPoint(Vector3 p, int iterations, ref float alpha)
{
int num = 0;
Find(p);
MegaSpline megaSpline = shape.splines[curve];
for (int i = 0; i < itercount; i++)
{
float num2 = 0.01f * Mathf.Pow(10f, 0f - (float)i);
float num3 = num2 * 0.1f;
for (float num4 = Mathf.Clamp01(this.num2 - num2); num4 <= Mathf.Clamp01(this.num2 + num2); num4 += num3)
{
float sqrMagnitude = (megaSpline.Interpolate(num4, true, ref num) - p).sqrMagnitude;
if (positiveInfinity > sqrMagnitude)
{
positiveInfinity = sqrMagnitude;
this.num2 = num4;
}
}
}
alpha = this.num2;
return shape.InterpCurve3D(curve, this.num2, true);
}
public override Vector3 Map(int i, Vector3 p)
{
p = tm.MultiplyPoint3x4(p);
Vector3 vector = lwtm.MultiplyPoint3x4(p);
qc.x = vector.x - shapepos.x;
qc.y = vector.y - shapepos.y;
qc.z = vector.z - shapepos.z;
if (qc.sqrMagnitude < limit2)
{
Vector3 point = FindNearestPointWorld(vector, itercount, ref alpha);
if (attractType == MegaAttractType.Repulse)
{
delta.x = vector.x - point.x;
delta.y = vector.y - point.y;
delta.z = vector.z - point.z;
}
else
{
delta.x = point.x - vector.x;
delta.y = point.y - vector.y;
delta.z = point.z - vector.z;
}
float magnitude = delta.magnitude;
if (magnitude < distance)
{
float num = distance - magnitude;
float time = num / distance;
float num2 = crv.Evaluate(time);
if (attractType == MegaAttractType.Attract || attractType == MegaAttractType.Repulse)
{
Vector3 vector2 = delta.normalized * num * num2 * force;
if (attractType == MegaAttractType.Attract)
{
if (vector2.magnitude <= magnitude)
{
nvp = wltm.MultiplyPoint3x4(vector + vector2);
}
else
{
nvp = wltm.MultiplyPoint3x4(point);
}
}
else
{
nvp = wltm.MultiplyPoint3x4(vector + vector2);
}
}
else
{
float num3 = ((!(slide >= 0f)) ? (alpha + alpha * slidealpha * num2) : (alpha + (1f - alpha) * slidealpha * num2));
if (num3 < 0f)
{
num3 = 0f;
}
else if (num3 >= 1f)
{
num3 = 0.99999f;
}
Vector3 vector3 = swtm.MultiplyPoint3x4(shape.splines[curve].InterpCurve3D(num3, true, ref k));
float num4 = num3 + 0.01f;
if (num3 + 0.01f >= 1f)
{
num4 = num3 - 0.01f;
}
Vector3 vector4 = swtm.MultiplyPoint3x4(shape.splines[curve].InterpCurve3D(num4, true, ref k));
if (alpha + 0.01f < 1f)
{
dir = (vector3 - vector4).normalized;
}
else
{
dir = (vector4 - vector3).normalized;
}
Vector3 normalized = Vector3.Cross(delta, dir).normalized;
rottm.SetColumn(0, normalized);
rottm.SetColumn(1, Vector3.Cross(-normalized, dir));
rottm.SetColumn(2, dir);
rottm.SetColumn(3, vector3);
float f = (-90f + rotate * num * num2) * ((float)Math.PI / 180f);
tp.x = magnitude * Mathf.Cos(f);
tp.y = magnitude * Mathf.Sin(f);
tp.z = ((!flat) ? p.z : 0f);
nvp = rottm.MultiplyPoint3x4(tp);
nvp = wltm.MultiplyPoint3x4(nvp);
}
}
else
{
nvp = p;
}
p = nvp;
}
return invtm.MultiplyPoint3x4(p);
}
public override bool ModLateUpdate(MegaModContext mc)
{
return Prepare(mc);
}
public override bool Prepare(MegaModContext mc)
{
if ((bool)shape)
{
if (splinechanged || points == null || points.Length == 0)
{
PrepareShape();
splinechanged = false;
}
limit2 = limit * limit;
shapepos = shape.transform.position;
slidealpha = slide * 0.01f;
swtm = shape.transform.localToWorldMatrix;
swltm = shape.transform.worldToLocalMatrix;
lwtm = base.transform.localToWorldMatrix;
wltm = base.transform.worldToLocalMatrix;
return true;
}
return false;
}
}