Files
Ultimate-Fishing-Simulator-…/Assets/Scripts/Assembly-CSharp/FishingSetController.cs
2026-03-04 09:37:33 +08:00

665 lines
17 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using Obi;
using Obvious.Soap;
using UFS3;
using UnityEngine;
public class FishingSetController : MonoBehaviour, IInitializable<FishingSetData>
{
public float rodPullValue;
public BobberController attachedBobber;
public FloatVariable groundSetting;
public FloatVariable damageTimeReaction;
public BoolVariable IsIndestructible_Debug;
public FloatVariable throwDistance;
public ObiSolver Solver;
[SerializeField]
private Reel attachedReel;
[SerializeField]
private Rod attachedRod;
[SerializeField]
private Lure attachedLure;
private Hook attachedHook;
[SerializeField]
private FishingLine attachedLine;
private FishingSetData fishingSetData;
private float apliedTension;
private RodIK _IK;
[SerializeField]
private FloatVariable gearTimeMaxDamage;
[SerializeField]
private ScriptableEventGameObject onLureInit;
private FishController _hookedFish;
private float lureDistance;
private bool isPlayerControlling;
private float _Tension;
[SerializeField]
private float strength = 5f;
private float gearTimeDamage;
private bool isGearDamaged;
private float _damageScale = 0.015f;
private float reelDamageTime;
private float rodDamageTime;
private float lineDamageTime;
public float LureDistance;
public Action lureCastEnded;
private string sfxFishingReel = "fishing-reel-fast";
private bool isTensionThresholdReached;
private float lastReeledLineLength;
public Action OnDrop;
public float Tension
{
get
{
return _Tension;
}
private set
{
if (_Tension != value)
{
_Tension = value;
this.OnTensionChanged?.Invoke(_Tension);
}
}
}
public Reel AttachedReel => attachedReel;
public Rod AttachedRod => attachedRod;
public Lure AttachedLure => attachedLure;
public Hook AttachedHook => attachedHook;
public FishingLine AttachedLine => attachedLine;
public FishController HookedFish => _hookedFish;
public FishingSetData FishingSetData => fishingSetData;
public event Action<float> OnLineLengthChanged;
public event Action OnLinePulled;
public event Action OnLureTouchWater;
public event Action OnGearDestroyed;
public event Action OnCutLine;
public event Action<float> OnRodDamage;
public event Action<float> OnLineDamage;
public event Action<float> OnReelDamage;
public event Action<FishData> OnFishCatch;
public event Action<float> OnTensionChanged;
public event Action<float> OnDragSettingChanged;
public event Action<float> OnLineReeled;
public event Action OnFishDetached;
public void OpenBail()
{
attachedReel.OpenBail();
}
public void CloseBail()
{
attachedReel.CloseBail();
}
public void Drop()
{
base.transform.parent = null;
OnDrop?.Invoke();
}
public void PutRodOnStack()
{
throw new NotImplementedException();
}
public bool CompareFishingSetData(FishingSetData data)
{
return fishingSetData == data;
}
private void LateUpdate()
{
UpdateGearDurability();
HandleFishCatching();
_IK.SetIkWeight(_Tension / attachedRod.RodPower);
rodPullValue = 0f;
TensionHandler();
if (lastReeledLineLength > 0f)
{
lastReeledLineLength = 0f;
this.OnLineReeled?.Invoke(lastReeledLineLength);
}
}
public void Cast(Transform targetFromCast)
{
StartCoroutine(CastingLure(targetFromCast));
}
private IEnumerator CastingLure(Transform startTarget)
{
_ = attachedRod.RodTipBone.position;
float num = throwDistance.Value * 0.5f;
Vector3 end = startTarget.forward * num;
end.y = startTarget.position.y;
float height = 5f;
_ = throwDistance.Value;
Debug.Log("Throwing Lure Start");
while (true)
{
_ = attachedLure.RBody.position;
Vector3 position = attachedLure.RBody.position + end * Time.deltaTime;
position.y += height * Time.deltaTime;
height -= Time.deltaTime * 8f;
height = Mathf.Clamp(height, -10f, 100f);
attachedLure.RBody.isKinematic = true;
attachedLure.RBody.linearVelocity = Vector3.zero;
attachedLure.RBody.MovePosition(position);
float num2 = Vector3.Distance(attachedRod.RodTipBone.position, (attachedBobber != null) ? attachedBobber.transform.position : attachedLure.RBody.position);
SetLineLength(num2);
AttachedLine.SetObiRopeStretch(num2);
if (attachedLure.IsCollide() || attachedLure.isInWater)
{
break;
}
yield return null;
}
attachedLure.RBody.isKinematic = false;
lureCastEnded?.Invoke();
Debug.Log("Throwing Lure End");
}
private void UpdateGearDurability()
{
if (IsIndestructible_Debug.Value)
{
return;
}
float max = 5f;
if ((bool)FishingSetData.Reel && Tension > FishingSetData.Reel.MaxDrag)
{
this.OnReelDamage?.Invoke(FishingSetData.Reel.Durabilty);
if (Time.time >= reelDamageTime)
{
float num = Mathf.Clamp(Tension / FishingSetData.Reel.MaxDrag, 0f, max) * Time.deltaTime * _damageScale;
FishingSetData.Reel.Durabilty -= num;
if (FishingSetData.Reel.Durabilty <= 0f)
{
FishingSetData.Reel = null;
FishingSetData.Line = null;
FishingSetData.Bobber = null;
FishingSetData.Hook = null;
fishingSetData.Weight = null;
FishingSetData.Lure = null;
FishingSetData.Bait = null;
Debug.Log("Reel is Damaged");
SFXGameManagement.PlaySound("reel damaged", base.transform);
DestroyGear();
}
}
}
else
{
reelDamageTime = Time.time + damageTimeReaction.Value;
}
if ((bool)FishingSetData.Rod && Tension > FishingSetData.Rod.strength)
{
this.OnRodDamage?.Invoke(FishingSetData.Rod.Durabilty);
if (Time.time >= rodDamageTime)
{
float num2 = Mathf.Clamp(Tension / FishingSetData.Rod.strength, 0f, max) * Time.deltaTime * _damageScale;
FishingSetData.Rod.Durabilty -= num2;
if (FishingSetData.Rod.Durabilty <= 0f)
{
FishingSetData.Rod = null;
FishingSetData.Line = null;
FishingSetData.Bobber = null;
FishingSetData.Hook = null;
fishingSetData.Weight = null;
FishingSetData.Lure = null;
FishingSetData.Bait = null;
Debug.Log("Rod is Damaged");
SFXGameManagement.PlaySound("rod damaged", base.transform);
DestroyGear();
}
}
}
else
{
rodDamageTime = Time.time + damageTimeReaction.Value;
}
if ((bool)FishingSetData.Line && Tension > FishingSetData.Line.Strength)
{
this.OnLineDamage?.Invoke(FishingSetData.Line.Durabilty);
if (Time.time >= lineDamageTime)
{
float num3 = Mathf.Clamp(Tension / FishingSetData.Line.Strength, 0f, 5f) * Time.deltaTime * _damageScale;
DamageFishingLine(0f - num3);
}
}
else
{
lineDamageTime = Time.time + damageTimeReaction.Value;
}
}
private void DamageFishingLine(float amount)
{
FishingSetData.Line.Durabilty += amount;
if (FishingSetData.Line.Durabilty <= 0f)
{
FishingSetData.Line = null;
FishingSetData.Bobber = null;
FishingSetData.Hook = null;
fishingSetData.Weight = null;
FishingSetData.Lure = null;
FishingSetData.Bait = null;
Debug.Log("Line is Damaged");
SFXGameManagement.PlaySound("line damaged", base.transform);
DestroyGear();
}
}
public void CutLine()
{
if ((bool)_hookedFish)
{
DamageFishingLine(-1f);
}
SetLineLength(0.5f);
attachedReel.CloseBail();
this.OnCutLine?.Invoke();
}
private void TensionHandler()
{
LureDistance = Vector3.Distance(attachedRod.RodTipBone.position, attachedLure.transform.position);
float num = ((fishingSetData.SetType == FishingMethodType.Float) ? groundSetting.Value : 0f);
float num2 = 0.1f;
float num3 = attachedLine.LineLength + num - num2;
float num4 = (LureDistance - num3) * (1f - attachedReel.DragSetting);
bool isLineUnrolled = false;
if (_hookedFish != null)
{
float tension = Tension;
float num5 = _hookedFish.stamina + 0.1f;
float mass = _hookedFish.Mass;
float maxDrag = fishingSetData.Reel.MaxDrag;
if (num3 <= LureDistance)
{
tension = mass * num5 * attachedReel.DragSetting;
float num6 = maxDrag * attachedReel.DragSetting;
if (mass >= num6)
{
UnwindLine(num4);
isLineUnrolled = true;
attachedLine.SetObiRopeStretch(0f);
}
}
else
{
tension = 0f;
}
if (attachedLine.LineLength >= fishingSetData.Line.Length)
{
tension = mass;
}
if (tension > Tension)
{
Tension = Mathf.Lerp(Tension, tension, Time.deltaTime * 5f);
}
else
{
Tension = Mathf.Lerp(Tension, 0f, Time.deltaTime);
}
}
else
{
Tension = 0f;
}
UpdateTensionSfx(isLineUnrolled, num4);
}
private void UpdateTensionSfx(bool isLineUnrolled, float lineUnrollDelta)
{
if (fishingSetData.Rod != null)
{
if (Tension < fishingSetData.Rod.strength * 0.8f && isTensionThresholdReached)
{
isTensionThresholdReached = false;
}
if (Tension > fishingSetData.Rod.strength * 0.8f && !isTensionThresholdReached)
{
SFXGameManagement.PlaySound("tension", base.transform);
isTensionThresholdReached = true;
}
}
if (isLineUnrolled && lineUnrollDelta > 0f)
{
SFXGameManagement.PlaySound(sfxFishingReel, base.transform);
}
else
{
SFXGameManagement.StopSound(sfxFishingReel);
}
if (SFXGameManagement.IsSoundPlaying(sfxFishingReel))
{
float t = lineUnrollDelta * 16f;
float pitchValue = Mathf.Lerp(0.8f, 3f, t);
SFXGameManagement.ChangePitch(sfxFishingReel, pitchValue);
}
}
private void TensionHandler2()
{
LureDistance = Vector3.Distance(attachedRod.RodTipBone.position, attachedLure.transform.position);
float num = ((fishingSetData.SetType == FishingMethodType.Float) ? groundSetting.Value : 0f);
float num2 = 0.1f;
float num3 = attachedLine.LineLength + num - num2;
float num4 = (LureDistance - num3) * (1f - attachedReel.DragSetting);
bool isLineUnrolled = false;
if (_hookedFish != null)
{
float tension = Tension;
float num5 = _hookedFish.stamina + 0.1f;
float mass = _hookedFish.Mass;
float num6 = fishingSetData.Reel.MaxDrag * attachedReel.DragSetting;
if (num3 <= LureDistance)
{
tension = mass * num5 * attachedReel.DragSetting;
if (mass >= num6)
{
UnwindLine(num4);
isLineUnrolled = true;
attachedLine.SetObiRopeStretch(0f);
}
}
else
{
tension = 0f;
}
if (attachedLine.LineLength >= fishingSetData.Line.Length)
{
tension = mass;
}
if (tension > Tension)
{
Tension = Mathf.Lerp(Tension, tension, Time.deltaTime * 5f);
}
else
{
Tension = Mathf.Lerp(Tension, 0f, Time.deltaTime);
}
}
else
{
Tension = 0f;
}
UpdateTensionSfx(isLineUnrolled, num4);
}
private void HandleFishCatching()
{
if (_hookedFish != null)
{
bool flag = LureDistance < attachedRod.Length && rodPullValue >= 1f;
bool flag2 = !_hookedFish.inWater && Vector3.Distance(_hookedFish.transform.position, base.transform.position) < 2f;
bool flag3 = _hookedFish.transform.position.y > base.transform.position.y && flag;
bool flag4 = attachedLine.LineLength < 1.5f;
if ((flag && flag2) || flag3 || flag4)
{
_hookedFish.Catch();
this.OnFishCatch?.Invoke(_hookedFish.FishData);
DetachFish();
}
}
}
public void Initialize(FishingSetData fishingSet)
{
fishingSetData = fishingSet;
attachedRod = UnityEngine.Object.Instantiate(fishingSetData.Rod.GetPrefab, base.transform).GetComponent<Rod>();
attachedReel = UnityEngine.Object.Instantiate(fishingSetData.Reel.GetPrefab, base.transform).GetComponent<Reel>();
attachedReel.Initialize(fishingSet.Reel);
attachedRod.Initialize(fishingSet.Rod);
base.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
attachedRod.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
attachedRod.AttachReel(attachedReel.transform);
List<Transform> guides = attachedRod.RodGuides.Guides;
guides.Add(attachedReel.RopeAnchorOnRoller);
onLureInit.OnRaised += OnLureInit_OnRaised;
LineType lineType = ((fishingSetData.SetType != FishingMethodType.Spinning) ? LineType.Float : LineType.Spinning);
MonoBehaviourSingleton<FishingLineManager>.Instance.OnFishingLineCreated += OnFishingLineCreated;
MonoBehaviourSingleton<FishingLineManager>.Instance.CreateLine(lineType, guides, this);
attachedLure.transform.parent = GameObject.FindWithTag("Gameplay").transform;
if (lineType == LineType.Float)
{
attachedLure.Initialize(fishingSet.Bait);
}
else
{
attachedLure.Initialize(fishingSet.Lure);
}
attachedLure.lookTarget = base.transform;
attachedLure.OnFishEat += delegate(FishController x)
{
AttachFish(x);
};
attachedLure.OnFishSpit += delegate
{
DetachFish();
};
attachedLure.OnWaterStateChanged += delegate
{
Debug.Log("water collision");
this.OnLureTouchWater?.Invoke();
};
attachedLure.OnGroundCollisionChangeState += delegate
{
Debug.Log("Touch collision");
this.OnLureTouchWater?.Invoke();
};
attachedLine.OnLinePulled += delegate
{
if (!_hookedFish)
{
this.OnLinePulled?.Invoke();
}
};
switch (lineType)
{
case LineType.Spinning:
{
GameObject gameObject2 = UnityEngine.Object.Instantiate(fishingSetData.Lure.GetPrefab, attachedLure.transform);
gameObject2.transform.localPosition = Vector3.zero;
attachedLure.lureMeshRenderer = gameObject2.GetComponentInChildren<MeshRenderer>();
Debug.Log("attached lure mesh: " + attachedLure.lureMeshRenderer.gameObject.name);
break;
}
case LineType.Float:
{
GameObject obj = UnityEngine.Object.Instantiate(fishingSetData.Bobber.GetPrefab, attachedBobber.transform);
attachedHook = UnityEngine.Object.Instantiate(fishingSetData.Hook.GetPrefab, attachedLure.transform).GetComponent<Hook>();
GameObject gameObject = UnityEngine.Object.Instantiate(fishingSetData.Bait.GetPrefab);
obj.transform.localPosition = Vector3.zero;
attachedHook.transform.localPosition = Vector3.zero;
attachedLure.lureMeshRenderer = attachedHook.GetComponentInChildren<MeshRenderer>();
attachedLure.lureSize = fishingSet.Hook.size;
attachedLure.transform.localPosition = Vector3.zero;
gameObject.transform.parent = attachedHook.baitPlace;
gameObject.transform.localPosition = Vector3.zero;
gameObject.transform.localRotation = Quaternion.identity;
break;
}
default:
throw new ArgumentOutOfRangeException();
}
_IK = GetComponentInChildren<RodIK>();
_IK.SetIKTarget(attachedLure.transform);
_IK.action = fishingSet.Rod.GetAction;
StartCoroutine(SetRendererLine());
void OnFishingLineCreated(FishingLine fishingLine)
{
attachedLine = fishingLine;
attachedBobber = fishingLine.GetComponentInChildren<BobberController>();
MonoBehaviourSingleton<FishingLineManager>.Instance.OnFishingLineCreated -= OnFishingLineCreated;
}
}
private IEnumerator SetRendererLine()
{
yield return new WaitForSeconds(1f);
AttachedLine.EnableLineRenderers();
}
private void AttachFish(FishController fishController)
{
_hookedFish = fishController;
_hookedFish.AttachToFishingSet(this);
attachedBobber?.SetDetectCollisionEnabled(enabled: false);
}
private void DestroyGear()
{
if (_hookedFish == null)
{
Debug.Log("Fish was not attached to rod");
}
_hookedFish.FishDestroy();
_hookedFish = null;
SetLineLength(0.5f);
this.OnGearDestroyed?.Invoke();
}
private void DetachFish()
{
if (_hookedFish == null)
{
Debug.Log("Fish was not attached to rod");
}
attachedBobber?.SetDetectCollisionEnabled(enabled: true);
_hookedFish = null;
this.OnFishDetached?.Invoke();
}
private void OnDestroy()
{
SFXGameManagement.StopSound(sfxFishingReel);
FishingLineManager.KillSolver(Solver);
}
public void SetFishingSetToCatchedFish()
{
}
private void OnGearUpdated_OnRaised(BaseItemData obj)
{
if (!(obj == null))
{
if ((bool)((RodData)obj).AttachedReel)
{
attachedReel.gameObject.SetActive(value: true);
}
else
{
attachedReel.gameObject.SetActive(value: false);
}
}
}
private void OnLureInit_OnRaised(GameObject obj)
{
attachedLure = obj.transform.GetComponent<Lure>();
onLureInit.OnRaised -= OnLureInit_OnRaised;
}
public void UnwindLine(float lengthToUnwind, bool useReel = false)
{
float num = attachedLine.LineLength + lengthToUnwind;
SetLineLength(num);
if (useReel)
{
attachedReel.SpinReel(lengthToUnwind);
if (lengthToUnwind < 0f)
{
lastReeledLineLength = Mathf.Abs(num);
this.OnLineReeled?.Invoke(lengthToUnwind);
}
}
else
{
attachedReel.SpoolUnwind(lengthToUnwind);
}
}
public void SetLineLength(float length, bool strechRope = true)
{
attachedLine.SetUnrolledLineValue(length);
attachedLure.SetLureJointDistance(attachedLine.LineLength);
if (strechRope)
{
attachedLine.SetObiRopeStretch((Tension > 0f) ? 0f : attachedLine.LineLength);
}
this.OnLineLengthChanged?.Invoke(attachedLine.LineLength);
}
public void ApplyVariables()
{
this.OnDragSettingChanged?.Invoke(AttachedReel.DragSetting);
}
public void AddDrag(float value)
{
AttachedReel.SetDrag(Mathf.Clamp01(AttachedReel.DragSetting + value));
this.OnDragSettingChanged?.Invoke(AttachedReel.DragSetting);
}
}