using DG.Tweening; using ECM2.Examples.FirstPerson; using Obvious.Soap; using SoapCustomVariable; using UnityEngine; public class PlayerHandsController : MonoBehaviour { public FSMVariable PlayerState; public BoolVariable IsLeftButtonPressed; public BoolVariable IsRightButtonPressed; public BoolVariable IsRunButtonPressed; public Vector2Variable RodPosition; public FloatVariable LineTension; public FloatVariable ReelSpeed; public FloatVariable PlayerArmsStrength; public FloatVariable ThrowDistance; public FloatVariable CastPower; public FloatVariable DragSettingInput; public ScriptableEventBool OnFishingSetEquiped; public Waga waga; public float PullUpRodSpeed; public float pullDownRodSpeed; [SerializeField] private float _LineRollSpeedMultiplier = 5f; private PlayerFishingGearController _Equipment; private bool _IsHandsControllsEnabled; [SerializeField] private HoldAction _HoldAction; private PlayerIK _IK; public Transform HandPreciseThrowTarget; public Rigidbody PrecisePickBone; private TrajectoryThrow _TrajectoryThrow; public AnimationCurve PreciseThrowCurve; private PlayerAnimator _playerAnimator; private CharacterLook _characterLook; private bool isFishingSeat; private bool isInVehicle; private bool isThrowLoad; private bool isPreciseCast; private bool lureInHand; private Vector3 lastPosition; private float handReelingStrength = 30f; private float minReelRatio = 0.125f; private string sfxReelingName = "Reeling 2"; private float pullingStrength = 25f; private float minPullingStrength = 0.125f; public AimTarget aimTarget; private bool isPreciseCastingInProgress; [SerializeField] private Vector2 _RangeMin; [SerializeField] private Vector2 _RangeMax; [SerializeField] private Vector2 _RodDefaultPosition = Vector2.zero; [SerializeField] private Vector2 _RodNeutralPosition = Vector2.zero; private float undwindLineOnPrecise => _Equipment.EquipedFishingSet.AttachedRod.Length; [SerializeField] private Vector3 _RodCatchPosition => new Vector2(0f, 1f); private void Awake() { _characterLook = GetComponent(); _playerAnimator = GetComponentInChildren(); _TrajectoryThrow = GetComponentInChildren(); _IK = GetComponentInChildren(); _Equipment = GetComponent(); _Equipment.OnFishingSetEquiped += delegate { OnFishingSetEquiped.Raise(param: true); }; _Equipment.OnFishingSetUnequip += delegate { OnFishingSetEquiped.Raise(param: false); }; _Equipment.OnGearDestroyed += delegate { if (isFishingSeat) { PlayerState.Value = State.vehicleFishing; } else if (isInVehicle && !isFishingSeat) { PlayerState.Value = State.vehicle; } else { PlayerState.Value = State.idle; } }; _Equipment.OnLinePulled += delegate { if (isFishingSeat) { PlayerState.Value = State.vehicleFishing; } else if (isInVehicle && !isFishingSeat) { PlayerState.Value = State.vehicle; } else { PlayerState.Value = State.idle; } }; } private void OnEnable() { PlayerState.OnValueChanged += PlayerStateOnOnValueChanged; DragSettingInput.OnValueChanged += DragSettingInputOnOnValueChanged; IsRightButtonPressed.OnValueChanged += OnPreciseCast_ButtonPressed; } private void OnDisable() { PlayerState.OnValueChanged -= PlayerStateOnOnValueChanged; DragSettingInput.OnValueChanged -= DragSettingInputOnOnValueChanged; IsRightButtonPressed.OnValueChanged -= OnPreciseCast_ButtonPressed; } private void ResetToIdle() { State state = (isInVehicle ? State.vehicle : State.idle); state = (isFishingSeat ? State.vehicleFishing : state); PlayerState.Value = state; } private void OnPreciseCast_ButtonPressed(bool isPressed) { switch (PlayerState.Value) { case State.idle: case State.move: case State.vehicleFishing: if (isPressed && (bool)_Equipment.EquipedFishingSet) { isPreciseCast = true; PlayerState.Value = State.preciseCastIdle; } break; case State.preciseCastIdle: if (isPressed && !isPreciseCastingInProgress) { ResetToIdle(); } break; } } private void DragSettingInputOnOnValueChanged(float value) { switch (PlayerState.Value) { case State.idle: case State.move: case State.fishing: case State.fight: case State.vehicle: case State.vehicleFishing: if (_Equipment.IsEquipped.Value) { if (IsRunButtonPressed.Value) { ReelSpeed.Value += value * 0.015f; } else { _Equipment.EquipedFishingSet?.AddDrag(value * 0.015f); } } break; } } private void PlayerStateOnOnValueChanged(State state) { switch (PlayerState.PreviousValue) { case State.baitFlies: _HoldAction.ResetHold(); break; case State.fishing: ThrowDistance.Value = 0f; _IK.SetBipedLeftHandIK(enabled: false); _IK.SetAimIK(enabled: false); if (SFXGameManagement.IsSoundPlaying(sfxReelingName)) { SFXGameManagement.StopSound(sfxReelingName); } break; case State.fight: if (SFXGameManagement.IsSoundPlaying(sfxReelingName)) { SFXGameManagement.StopSound(sfxReelingName); } _IK.SetAimIK(enabled: false); break; case State.vehicleFishing: isInVehicle = false; break; case State.vehicle: isInVehicle = false; break; case State.preciseCastIdle: isPreciseCast = false; _TrajectoryThrow.targetCylinderEnabled = false; if (state != State.fishing) { _Equipment.EquipedFishingSet.SetLineLength(0.5f); } _Equipment.EquipedFishingSet.AttachedLure.SetJoint(_Equipment.EquipedFishingSet.AttachedRod.RodTipBone); _Equipment.EquipedFishingSet.AttachedLure.EnableCollision(enable: true); _Equipment.EquipedFishingSet.AttachedLure.SetKinematic(value: false); _Equipment.EquipedFishingSet.attachedBobber?.SetDetectCollisionEnabled(enabled: true); _IK.SetFishingLeftArm(enabled: false, _Equipment.EquipedFishingSet.AttachedReel.FingersIKAnchor); isPreciseCastingInProgress = false; lureInHand = false; break; case State.collectFish: _Equipment.EquipedFishingSet?.AttachedLure?.SetRenderersVisbile(isVisbile: true); waga.gameObject.SetActive(value: false); _Equipment.EquipedFishingSet.AttachedLure.EnableCollision(enable: true); _Equipment.EquipedFishingSet.attachedBobber?.SetDetectCollisionEnabled(enabled: true); break; } switch (state) { case State.idle: isInVehicle = false; if (SFXGameManagement.IsSoundPlaying(sfxReelingName)) { SFXGameManagement.StopSound(sfxReelingName); } isFishingSeat = false; LineTension.Value = 0f; RodPosition.Value = Vector3.zero; _IK.SetAimIK(enabled: false); _IK.SetBipedLeftHandIK(enabled: false); _IK.SetFishingLeftArm(enabled: false); break; case State.vehicle: isInVehicle = true; isFishingSeat = false; break; case State.prepare: if (SFXGameManagement.IsSoundPlaying(sfxReelingName)) { SFXGameManagement.StopSound(sfxReelingName); } break; case State.vehicleFishing: if (SFXGameManagement.IsSoundPlaying(sfxReelingName)) { SFXGameManagement.StopSound(sfxReelingName); } isFishingSeat = true; isInVehicle = true; _IK.SetFishingLeftArm(enabled: false); break; case State.preciseCastIdle: _TrajectoryThrow.targetCylinderEnabled = true; _IK.SetBipedRightHandIK(enabled: false, null); _Equipment.EquipedFishingSet.SetLineLength(SetLineLengthBasedOnGround()); _Equipment.EquipedFishingSet.AttachedLure.EnableCollision(enable: false); _Equipment.EquipedFishingSet.attachedBobber?.SetDetectCollisionEnabled(enabled: false); lureInHand = true; break; case State.fishing: case State.fight: _IK.SetBipedRightHandIK(enabled: false, null); _IK.SetFishingLeftArm(enabled: true, _Equipment.EquipedFishingSet.AttachedReel.FingersIKAnchor); _IK.SetAimIK(enabled: true); break; case State.casting: isThrowLoad = true; _Equipment.EquipedFishingSet.OpenBail(); break; case State.baitFlies: _Equipment.EquipedFishingSet.Cast(base.transform); break; case State.collectFish: waga.gameObject.SetActive(value: true); waga.SetText(_Equipment.EquipedFishingSet.HookedFish.Mass); _Equipment.EquipedFishingSet.HookedFish.SetJoint(waga.hookRbody); _Equipment.EquipedFishingSet.AttachedLure.EnableCollision(enable: false); _Equipment.EquipedFishingSet.attachedBobber?.SetDetectCollisionEnabled(enabled: false); break; case State.move: case State.fishView: case State.throwFish: case State.swiming: case State.flyModeDebug: break; } } private float SetLineLengthBasedOnGround() { float value = _Equipment.EquipedFishingSet.groundSetting.Value; Vector3 position = _Equipment.EquipedFishingSet.AttachedRod.RodTipBone.position; Vector3 position2 = PrecisePickBone.position; return Mathf.Clamp(Vector3.Distance(position, position2) - value, 0.51f, 50f); } private void Update() { if (_Equipment.EquipedFishingSet == null) { return; } _ = CastPower.Value; switch (PlayerState.Value) { case State.idle: case State.move: case State.vehicleFishing: if (IsLeftButtonPressed.Value && _HoldAction.IsZero()) { isPreciseCast = false; PlayerState.Value = State.prepare; } break; case State.prepare: if (!IsLeftButtonPressed.Value && !isPreciseCast) { ResetToIdle(); } break; case State.casting: if (isThrowLoad) { _HoldAction.Hold(); ThrowDistance.Value = Mathf.Lerp(0f, CastPower.Value, _HoldAction.CurrentValue * 1.35f); } if (!IsLeftButtonPressed.Value && _HoldAction.CurrentValue > 0.1f) { isThrowLoad = false; } break; case State.fishing: case State.fight: RodControllClassicMethod(); UnwindFishingLine(); break; case State.preciseCastIdle: { Lure lure = _Equipment.EquipedFishingSet.AttachedLure; BobberController bobber = _Equipment.EquipedFishingSet.attachedBobber; float delay = 0.95f; lastPosition = lure.transform.position; float distance = 0f; float lineMinus = ((bobber != null) ? (0f - _Equipment.EquipedFishingSet.groundSetting.Value) : 0f); if (!isPreciseCastingInProgress) { _Equipment.EquipedFishingSet.SetLineLength(SetLineLengthBasedOnGround()); } else if (_Equipment.EquipedFishingSet.AttachedLure.IsCollide()) { lure.transform.DOKill(); float magnitude = (_Equipment.EquipedFishingSet.AttachedRod.RodTipBone.position - lure.transform.position).magnitude; lure.RBody.detectCollisions = true; lure.RBody.freezeRotation = false; lure.RBody.linearVelocity = Vector3.zero; lure.SetKinematic(value: false); if ((bool)bobber) { bobber.transform.position = lure.transform.position; bobber.SetVelocity(Vector3.zero); } _Equipment.EquipedFishingSet.SetLineLength(magnitude + lineMinus + 0.5f); _Equipment.EquipedFishingSet.AttachedLine.SetObiRopeStretch(magnitude + lineMinus + 0.5f); PlayerState.Value = State.fishing; } if (IsLeftButtonPressed.Value && !isPreciseCastingInProgress) { isPreciseCastingInProgress = true; _characterLook.isLookingEnabled = false; _playerAnimator.PlayPreciseCastAnimation(); lure.transform.DOJump(_TrajectoryThrow.cylinderPosition, 1f, 1, 1f).OnStart(delegate { lure.SetJoint(_Equipment.EquipedFishingSet.AttachedRod.RodTipBone); lure.RBody.freezeRotation = true; lureInHand = false; _characterLook.isLookingEnabled = true; _TrajectoryThrow.targetCylinderEnabled = false; SFXGameManagement.PlaySound("hand throw", base.transform); }).SetDelay(delay, asPrependedIntervalIfSequence: false) .OnUpdate(delegate { distance = Vector3.Distance(lure.transform.position, lastPosition); lastPosition = lure.transform.position; float magnitude2 = (_Equipment.EquipedFishingSet.AttachedRod.RodTipBone.position - lure.transform.position).magnitude; _Equipment.EquipedFishingSet.SetLineLength(magnitude2 + lineMinus); _Equipment.EquipedFishingSet.AttachedLine.SetObiRopeStretch(0f); }) .OnComplete(delegate { float magnitude2 = (_Equipment.EquipedFishingSet.AttachedRod.RodTipBone.position - lure.transform.position).magnitude; _Equipment.EquipedFishingSet.SetLineLength(magnitude2 + lineMinus); _Equipment.EquipedFishingSet.AttachedLine.SetObiRopeStretch(magnitude2 + lineMinus); lure.RBody.detectCollisions = true; lure.RBody.freezeRotation = false; lure.RBody.linearVelocity = Vector3.zero; lure.SetKinematic(value: false); if ((bool)bobber) { bobber.transform.position = lure.transform.position; bobber.SetVelocity(Vector3.zero); } PlayerState.Value = State.fishing; }); } if (lureInHand) { lure.transform.position = PrecisePickBone.transform.position; if ((bool)bobber) { lure.RBody.isKinematic = true; lure.RBody.detectCollisions = false; lure.transform.position = PrecisePickBone.transform.position; lure.transform.rotation = PrecisePickBone.transform.rotation; } else if (lure.Joint.connectedBody != PrecisePickBone) { lure.SetJoint(PrecisePickBone); lure.SetLureJointDistance(0f); lure.RBody.linearVelocity = Vector3.zero; } } break; } case State.collectFish: { Vector3 eulerAngles = waga.transform.eulerAngles; RodPosition.Value = Vector3.MoveTowards(RodPosition.Value, _RodCatchPosition, Time.deltaTime); waga.transform.eulerAngles = new Vector3(eulerAngles.x, PrecisePickBone.transform.eulerAngles.y, eulerAngles.z); break; } case State.baitFlies: case State.fishView: case State.throwFish: case State.vehicle: case State.swiming: case State.flyModeDebug: break; } } private void UnwindFishingLine() { if (!IsLeftButtonPressed.Value) { if (SFXGameManagement.IsSoundPlaying(sfxReelingName)) { SFXGameManagement.StopSound(sfxReelingName); } return; } float num = Mathf.Lerp(1f, minReelRatio, LineTension.Value / handReelingStrength); float num2 = (IsRunButtonPressed.Value ? 1f : ReelSpeed.Value); float num3 = (0f - Time.deltaTime) * num2 * _LineRollSpeedMultiplier * num; float lineLength = _Equipment.EquipedFishingSet.AttachedLine.LineLength; float lureDistance = _Equipment.EquipedFishingSet.LureDistance; float num4 = lineLength - lureDistance; num = num3 * Mathf.Clamp01(1f + Mathf.Clamp(num4 * 1f, -0.9f, 0f) + Random.Range(0f, 0.1f)); _Equipment.EquipedFishingSet.UnwindLine(num, useReel: true); float t = (0f - num) * 100f; float pitchValue = Mathf.Lerp(0.4f, 1.2f, t); if (!SFXGameManagement.IsSoundPlaying(sfxReelingName)) { SFXGameManagement.PlaySound(sfxReelingName, base.transform); } SFXGameManagement.ChangePitch(sfxReelingName, pitchValue); } private void RodControllClassicMethod() { FishController hookedFish = _Equipment.EquipedFishingSet.HookedFish; float num = 0f; if ((bool)hookedFish) { Vector3 normalized = (hookedFish.transform.position - _Equipment.EquipedFishingSet.transform.position).normalized; Vector3 vector = Vector3.Cross(base.transform.forward, normalized); num = vector.y; _ = vector.y; _ = 0f; } float num2 = Mathf.Lerp(1.75f, minPullingStrength, LineTension.Value / pullingStrength); if (IsRightButtonPressed.Value) { RodPosition.Value = Vector3.MoveTowards(RodPosition.Value, new Vector3(0f, 1f, 0f), Time.deltaTime * num2); Mathf.Lerp(aimTarget.pullPower, 1f, Time.deltaTime * num2); aimTarget.Pull(RodPosition.Value.y, (LineTension.Value > 0f) ? (num * 1f) : 0f); } else { RodPosition.Value = Vector3.MoveTowards(RodPosition.Value, new Vector3(0f, 0f, 0f), Time.deltaTime * 5f); } _Equipment.EquipedFishingSet.rodPullValue = RodPosition.Value.y; } private void HandsMovementHandler(bool value, bool isFishOnHook = false) { } }