using UnityEngine; public class FishMovement : MonoBehaviour { public enum Stage { freeMove = 0, attackBait = 1, hooked = 2, onCut = 3, getFish = 4, onPodbierak = 5, onChwytak = 6 } public float currentSpeed = 1f; public bool isFeeding; public bool mustFeeding; private Vector3 dstPoint = Vector3.zero; [HideInInspector] public Vector3 deepProbe = Vector3.zero; private GameObject dstPointObject; [HideInInspector] public Vector3 startPosition = Vector3.zero; private FishFeedingZone[] fishFeedingZones; [HideInInspector] public int currentFeedingZoneIndex; [HideInInspector] public FishStats fishStats; private float randSpeed = 0.2f; private float animationFishSpeed = 1f; public Animator contentAnimator; private float nextJumpDelay; private int jumpAnimCount = 2; private BaitStats baitTarget; [HideInInspector] public BaitStats baitInJaw; public Stage stage; private GameObject controlCastFishPoint; private float timeNextPoint = 3f; private float timeIsCatch; public ParticleSystem smuuggeParticle; private Rigidbody rigibody; public Vector3 massCenter = Vector3.zero; private BoxCollider boxCollider; private bool isReeling; private float angleSpeed; public float RollStrenght = 2f; private void Start() { rigibody = GetComponent(); fishStats = GetComponent(); boxCollider = GetComponent(); fishFeedingZones = Object.FindObjectsOfType(); startPosition = base.transform.position; CreateDstPoint(); if (smuuggeParticle != null && smuuggeParticle.isPlaying) { smuuggeParticle.Stop(); } boxCollider.enabled = false; } private void Update() { ShowWaterFX(); isReeling = InputManager.isReelReeling; } private void FixedUpdate() { rigibody.centerOfMass = massCenter; switch (stage) { case Stage.attackBait: SearchTargetBait(); AttackBait(); Move(); Jump(); FishAnimatorControler(); break; case Stage.freeMove: SearchTargetBait(); AttackBait(); Move(); Jump(); FishAnimatorControler(); break; case Stage.getFish: fishStats.fishAnimator.SetBool("fight", value: false); GetFish(); break; case Stage.hooked: MoveByCatch(); Jump(); FishAnimatorControler(); timeIsCatch += Time.deltaTime; break; case Stage.onPodbierak: if (GetComponent() != null) { fishStats.fishAnimator.SetBool("fight", value: false); animationFishSpeed = 0f; fishStats.fishAnimator.SetBool("podbierak", value: true); baitInJaw.SetBaitOffFishJaw(); } FishAnimatorControler(); break; case Stage.onChwytak: fishStats.fishAnimator.SetBool("fight", value: false); fishStats.fishAnimator.SetBool("podbierak", value: false); fishStats.fishAnimator.SetBool("outhook", value: true); break; } if (deepProbe.y > 0f) { fishStats.AddFishToFishSystem(); } else { fishStats.DeleteFishfromFishSystem(); } } private void FishAnimatorControler() { fishStats.fishAnimator.SetFloat("speed", animationFishSpeed); } private void Jump() { if (deepProbe.z == 0f) { return; } nextJumpDelay += Time.deltaTime; if (deepProbe.z - GetMinDeepFish() * 4f <= base.transform.position.y && nextJumpDelay > 10f && !contentAnimator.GetCurrentAnimatorStateInfo(0).IsTag("Jump")) { contentAnimator.SetInteger("Jump", Random.Range(0, jumpAnimCount)); contentAnimator.SetTrigger("ForceJump"); nextJumpDelay = 0f; currentSpeed *= 1.5f; fishStats.current_strenght += 0.05f; if (fishStats.current_strenght > 1f) { fishStats.current_strenght = 1f; } } } private void CreateDstPoint() { dstPointObject = new GameObject(base.transform.name + " - DstPoint"); dstPointObject.transform.position = base.transform.position; dstPointObject.transform.localScale = Vector3.one * 0.05f; } private void ManualFishTake() { if (!ScriptsHandler.Instance.m_PlayerMain.currentRod.fishingLine.fishObject) { if ((bool)ScriptsHandler.Instance.m_PlayerMain.currentRod.fishingLine.hook) { baitTarget = ScriptsHandler.Instance.m_PlayerMain.currentRod.fishingLine.hook.GetComponent(); } if ((bool)ScriptsHandler.Instance.m_PlayerMain.currentRod.fishingLine.lure) { baitTarget = ScriptsHandler.Instance.m_PlayerMain.currentRod.fishingLine.lure.GetComponent(); } base.transform.position = baitTarget.transform.position; baitTarget.SetBaitOnFishJaw(fishStats); baitInJaw = baitTarget; fishStats.fishAnimator.Play("JawOpen", 2, 0f); fishStats.fishAnimator.SetBool("jaw", value: false); baitTarget = null; } } private void AttackBait() { if (baitTarget == null) { fishStats.fishAnimator.Play("JawOpen", 2, 0f); fishStats.fishAnimator.SetBool("jaw", value: false); } else { if (baitInJaw != null) { return; } if ((bool)baitTarget.hook) { if ((bool)baitTarget.hook.takeFish) { baitTarget = null; return; } } else if ((bool)baitTarget.lure && (bool)baitTarget.lure.takeFish) { baitTarget = null; return; } dstPoint = baitTarget.transform.position; base.transform.Translate(Vector3.forward * Time.deltaTime * currentSpeed); Vector3 vector = dstPoint - base.transform.position; Quaternion b = Quaternion.LookRotation(vector * Time.deltaTime); float num = Vector3.Angle(vector, base.transform.forward); base.transform.rotation = Quaternion.Slerp(base.transform.rotation, b, Time.deltaTime * (Mathf.Clamp(num, 0f, 10f) + currentSpeed)); animationFishSpeed = currentSpeed; if (num > 60f || baitTarget.deepProbe.y == 0f) { baitTarget = null; timeNextPoint = 0f; return; } float num2 = Vector3.Distance(fishStats.fishObjectConfig.JawJointPoint.position, dstPoint); if (num2 <= 0.06f) { baitTarget.SetBaitOnFishJaw(fishStats); baitInJaw = baitTarget; fishStats.fishAnimator.Play("JawOpen", 2, 0f); fishStats.fishAnimator.SetBool("jaw", value: false); baitTarget = null; randSpeed *= 2f; } else if (num2 <= 6f) { if (num < 10f && fishStats.fishType == FishStats.FishType.Drapieżnik) { randSpeed += Time.deltaTime; if (randSpeed > 1f) { randSpeed = 1f; } } fishStats.fishAnimator.SetBool("jaw", value: true); fishStats.fishAnimator.Play("JawOpen", 2, Mathf.Clamp01(1f - num2)); if (fishStats.fishType == FishStats.FishType.Drapieżnik && baitTarget.baitType == BaitStats.BaitType.Lure && (float)Random.Range(0, 100) > baitTarget.lure.percentEfficacy * 100f) { baitTarget = null; timeNextPoint = 0f; DstPointProbe(); return; } } currentSpeed = Mathf.MoveTowards(currentSpeed, randSpeed, Time.deltaTime * 0.5f); stage = Stage.attackBait; } } private void Move() { if (baitTarget != null) { return; } if ((bool)baitInJaw && isReeling && baitInJaw.baitType == BaitStats.BaitType.Hook) { baitInJaw.SetBaitOffFishJaw(); baitInJaw = null; return; } base.transform.Translate(Vector3.forward * Time.deltaTime * currentSpeed); if (base.transform.position.y + GetMinDeepFish() * 2f >= deepProbe.z) { base.transform.Translate(-Vector3.up * Time.deltaTime); if (Random.Range(0, 10) == 0) { contentAnimator.SetTrigger("RotateRight"); } } dstPoint = dstPointObject.transform.position; Vector3 vector = dstPoint - base.transform.position; float num = Vector3.Angle(vector, base.transform.forward); Quaternion b = Quaternion.LookRotation(vector * Time.deltaTime); base.transform.rotation = Quaternion.Slerp(base.transform.rotation, b, Time.deltaTime * (2f + currentSpeed)); if (num > 10f && currentSpeed > 0.2f) { float target = randSpeed * (Mathf.Clamp(num, 1f, 50f) * 0.05f); if (num > 60f) { fishStats.fishAnimator.SetBool("fight", value: true); } else { fishStats.fishAnimator.SetBool("fight", value: false); } angleSpeed = Mathf.MoveTowards(angleSpeed, target, Time.deltaTime); } else { angleSpeed = Mathf.MoveTowards(angleSpeed, 0f, Time.deltaTime * 0.03f); } animationFishSpeed = (currentSpeed + angleSpeed) * 1f; if (Vector3.Distance(base.transform.position, dstPoint) <= 0.3f || timeNextPoint == 0f) { DstPointProbe(); if (!isFeeding) { fishStats.currentFeed -= fishStats.hungryFactor; } else if (fishStats.currentFeed < 100f) { fishStats.currentFeed += 1f; } fishStats.currentFeed = Mathf.Clamp(fishStats.currentFeed, 0f, 100f); if (fishStats.currentFeed <= 50f) { if (!mustFeeding) { GetNearFeedingZone(); } mustFeeding = true; } if (fishStats.currentFeed >= 100f) { mustFeeding = false; } if (fishStats.fishDeepType == FishStats.FishDeepType.Denny) { float maxInclusive = Mathf.Clamp(deepProbe.x, 0.1f, 1f); randSpeed = Random.Range(0f, maxInclusive) * Mathf.Clamp(fishStats.current_weight, 0.2f, 0.6f); } else { randSpeed = Random.Range(0.1f, 0.5f) * Mathf.Clamp(fishStats.current_weight, 0.5f, 1f); } } if (timeNextPoint == 0f) { CheckEatDropBait(); if (fishStats.fishDeepType == FishStats.FishDeepType.Denny) { timeNextPoint = 15f; } else { timeNextPoint = 5f; } } else { timeNextPoint = Mathf.MoveTowards(timeNextPoint, 0f, Time.deltaTime); } if (nextJumpDelay < 2f) { randSpeed = Mathf.MoveTowards(randSpeed, 1f, Time.deltaTime * 0.5f); } currentSpeed = Mathf.MoveTowards(currentSpeed, randSpeed + angleSpeed, Time.deltaTime * 0.5f); contentAnimator.SetFloat("SwimSpeed", (currentSpeed + angleSpeed) * 3f); if (fishFeedingZones.Length != 0) { if (Vector3.Distance(base.transform.position, fishFeedingZones[currentFeedingZoneIndex].transform.position) < fishFeedingZones[currentFeedingZoneIndex].rangeZone) { isFeeding = true; } else { isFeeding = false; } } stage = Stage.freeMove; } public void SetIsCatch() { stage = Stage.hooked; controlCastFishPoint = new GameObject(base.transform.name + " - DstPoint"); controlCastFishPoint.transform.position = base.transform.position; controlCastFishPoint.transform.localScale = Vector3.one * 0.05f; timeIsCatch = 0f; boxCollider.enabled = true; } public void unHook() { stage = Stage.freeMove; boxCollider.enabled = false; if (baitInJaw != null) { baitInJaw.SetBaitOffFishJaw(); } Object.Destroy(controlCastFishPoint); } public void onCut() { ScriptsHandler.Instance.m_PlayerMain.CutFish(); } private void MoveByCatch() { if (controlCastFishPoint == null) { return; } float num = ScriptsHandler.Instance.m_PlayerMain.currentRod.fishingLine.ropeTension * ScriptsHandler.Instance.m_PlayerMain.currentRod.fishingLine.lineMaxStrength; float num2 = fishStats.current_weight * fishStats.current_strenght; _ = ScriptsHandler.Instance.m_PlayerMain.currentRod.fishingLine.ropeOut; Vector3 position = ScriptsHandler.Instance.m_PlayerMain.currentRod.fishingLine.toRodConnector.position; Vector3 forward = position - controlCastFishPoint.transform.position; forward.y = 0f; Quaternion rotation = Quaternion.LookRotation(forward); controlCastFishPoint.transform.rotation = rotation; base.transform.Translate(Vector3.forward * Time.deltaTime * currentSpeed); if (base.transform.position.y + GetMinDeepFish() * 2f >= deepProbe.z) { base.transform.Translate(-Vector3.up * Time.deltaTime); if (Random.Range(0, 5) == 0) { contentAnimator.SetTrigger("RotateRight"); } fishStats.fishAnimator.SetBool("fight", value: true); if (timeIsCatch > 300f && Random.Range(0, 3) == 2) { onCut(); return; } } dstPoint = dstPointObject.transform.position; Vector3 vector = position - base.transform.position; Vector3 vector2 = dstPoint - base.transform.position; Quaternion b = Quaternion.LookRotation(vector2); float num3 = Vector3.Angle(vector2, base.transform.forward); base.transform.rotation = Quaternion.Slerp(base.transform.rotation, b, Time.deltaTime * currentSpeed); if (num3 > 10f) { float target = randSpeed * (Mathf.Clamp(num3, 1f, 50f) * 0.05f); if (num3 > 60f) { fishStats.fishAnimator.SetBool("fight", value: true); } else { fishStats.fishAnimator.SetBool("fight", value: false); } angleSpeed = Mathf.MoveTowards(angleSpeed, target, Time.deltaTime); } else { angleSpeed = Mathf.MoveTowards(angleSpeed, 0f, Time.deltaTime * 0.01f); } animationFishSpeed = (currentSpeed + angleSpeed) * 0.5f; fishStats.current_strenght = Mathf.MoveTowards(fishStats.current_strenght, 0.3f, Time.deltaTime * num * 0.003f); Vector3.Angle(vector, base.transform.forward); float num4 = num - num2; if (num4 < 0f) { num4 = 0f; } if (num4 > 0.2f) { Quaternion b2 = Quaternion.LookRotation(vector); base.transform.rotation = Quaternion.Slerp(base.transform.rotation, b2, Time.deltaTime * (num4 * 20f)); } if (Vector3.Distance(base.transform.position, dstPoint) <= 0.3f || timeNextPoint == 0f) { DstPointProbeByCatch(controlCastFishPoint.transform); randSpeed = Random.Range(0.4f, 0.6f) * Mathf.Clamp(fishStats.current_weight, 0.2f, 0.6f) * fishStats.current_strenght; timeNextPoint = 3f; } else { timeNextPoint = Mathf.MoveTowards(timeNextPoint, 0f, Time.deltaTime); } currentSpeed = Mathf.MoveTowards(currentSpeed, randSpeed + angleSpeed, Time.deltaTime * 0.5f); contentAnimator.SetFloat("SwimSpeed", (currentSpeed + angleSpeed) * 2f); base.transform.position = Vector3.MoveTowards(base.transform.position, controlCastFishPoint.transform.position, Time.deltaTime * num4 * 4f); Vector3 position2 = base.transform.position; position2.y = controlCastFishPoint.transform.position.y; controlCastFishPoint.transform.position = Vector3.MoveTowards(controlCastFishPoint.transform.position, position2, Time.deltaTime * Mathf.Clamp01(Vector3.Distance(base.transform.position, controlCastFishPoint.transform.position))); controlCastFishPoint.transform.Translate(Vector3.forward * Time.deltaTime * num4 * 4f); } private void GetFish() { GetComponent().isKinematic = false; GetComponent().useGravity = true; animationFishSpeed = 1f; contentAnimator.SetFloat("SwimSpeed", 0f); } private void DstPointProbeByCatch(Transform orginPoint) { float num = 3f; Vector3 position = orginPoint.position + (orginPoint.right * Random.Range((0f - num) * 2f, num * 2f) + orginPoint.forward * Random.Range(0f - num, 0f)); position.y = orginPoint.position.y; dstPointObject.transform.position = position; Vector3 direction = dstPointObject.transform.position - orginPoint.position; if (Physics.Raycast(base.transform.position, direction, out var _, 6.2f, 1 << LayerMask.NameToLayer("Terrain"))) { dstPointObject.transform.position = orginPoint.position; } deepProbe = ProbeDeep(); switch (fishStats.fishDeepType) { case FishStats.FishDeepType.Denny: dstPointObject.transform.position = new Vector3(dstPointObject.transform.position.x, deepProbe.z - Random.Range((deepProbe.x + deepProbe.y) * 0.5f, deepProbe.x + deepProbe.y), dstPointObject.transform.position.z); break; case FishStats.FishDeepType.Powierzchowny: dstPointObject.transform.position = new Vector3(dstPointObject.transform.position.x, deepProbe.z - Random.Range(GetMinDeepFish(), (deepProbe.x + deepProbe.y) * 0.3f), dstPointObject.transform.position.z); break; case FishStats.FishDeepType.Ogólny: dstPointObject.transform.position = new Vector3(dstPointObject.transform.position.x, deepProbe.z - Random.Range(GetMinDeepFish(), deepProbe.x + deepProbe.y), dstPointObject.transform.position.z); break; } } private void DstPointProbe() { float num = Random.Range(1f, 5f); dstPointObject.transform.position += dstPointObject.transform.forward * num; Vector3 vector = dstPointObject.transform.position - base.transform.position; if (Physics.Raycast(base.transform.position, vector, out var hitInfo, num, (1 << LayerMask.NameToLayer("Water")) | (1 << LayerMask.NameToLayer("Terrain")) | (1 << LayerMask.NameToLayer("UnderwaterObject")) | (1 << LayerMask.NameToLayer("Default")))) { dstPointObject.transform.position -= dstPointObject.transform.forward * (num + 0.5f); dstPointObject.transform.Rotate(Vector3.up, 160f); Debug.DrawRay(base.transform.position, vector * hitInfo.distance, Color.yellow); } else { if (mustFeeding && fishFeedingZones.Length != 0) { if (deepProbe.x + deepProbe.y >= 1f) { float y = Quaternion.LookRotation(fishFeedingZones[currentFeedingZoneIndex].transform.position - dstPointObject.transform.position, Vector3.up).eulerAngles.y; Quaternion rotation = Quaternion.Euler(0f, y, 0f); dstPointObject.transform.rotation = rotation; } } else { float num2 = Random.Range(-50, 50); float y2 = dstPointObject.transform.eulerAngles.y + num2; Quaternion rotation2 = Quaternion.Euler(0f, y2, 0f); dstPointObject.transform.rotation = rotation2; } Debug.DrawRay(base.transform.position, vector * 1.2f, Color.white); } deepProbe = ProbeDeep(); if (deepProbe.x == 0f && deepProbe.z > 0f) { dstPointObject.transform.position = startPosition; return; } switch (fishStats.fishDeepType) { case FishStats.FishDeepType.Denny: dstPointObject.transform.position = new Vector3(dstPointObject.transform.position.x, deepProbe.z - Random.Range((deepProbe.x + deepProbe.y) * 0.95f, (deepProbe.x + deepProbe.y) * 0.8f), dstPointObject.transform.position.z); break; case FishStats.FishDeepType.Powierzchowny: dstPointObject.transform.position = new Vector3(dstPointObject.transform.position.x, deepProbe.z - Random.Range(GetMinDeepFish(), (deepProbe.x + deepProbe.y) * 0.5f), dstPointObject.transform.position.z); break; case FishStats.FishDeepType.Ogólny: dstPointObject.transform.position = new Vector3(dstPointObject.transform.position.x, deepProbe.z - Random.Range(GetMinDeepFish(), deepProbe.x + deepProbe.y), dstPointObject.transform.position.z); break; } } private float GetMinDeepFish() { return base.transform.localScale.y / 15f; } private void GetNearFeedingZone() { float num = 1000f; int num2 = 0; for (int i = 0; i < fishFeedingZones.Length; i++) { float num3 = Vector3.Distance(base.transform.position, fishFeedingZones[i].transform.position); if (num3 < num && currentFeedingZoneIndex != i) { num = num3; num2 = i; } } currentFeedingZoneIndex = num2; } private Vector3 ProbeDeep() { int mask = LayerMask.GetMask("Terrain"); Vector3 zero = Vector3.zero; if (Physics.Raycast(dstPointObject.transform.position, -Vector3.up, out var hitInfo, float.PositiveInfinity, mask)) { zero.x = hitInfo.distance; } int mask2 = LayerMask.GetMask("WaterObject"); if (Physics.Raycast(dstPointObject.transform.position, Vector3.up, out var hitInfo2, float.PositiveInfinity, mask2)) { zero.y = hitInfo2.distance; zero.z = hitInfo2.point.y; } return zero; } private Vector3 ProbeDeepFish() { int mask = LayerMask.GetMask("Terrain"); Vector3 zero = Vector3.zero; if (Physics.Raycast(base.transform.position, -Vector3.up, out var hitInfo, float.PositiveInfinity, mask)) { zero.x = hitInfo.distance; } int mask2 = LayerMask.GetMask("WaterObject"); if (Physics.Raycast(base.transform.position, Vector3.up, out var hitInfo2, float.PositiveInfinity, mask2)) { zero.y = hitInfo2.distance; zero.z = hitInfo2.point.y; } return zero; } private void SearchTargetBait() { if (!(fishStats.fishSystem == null) && !(fishStats.currentFeed > 80f) && !(baitTarget != null) && !(baitInJaw != null) && !(nextJumpDelay < 3f)) { baitTarget = fishStats.fishSystem.DetectNearBaitByDistance(base.transform, 5f); if ((bool)baitTarget && !GameManager.Instance.gameBaits[GameManager.Instance.GetIndexByItemId(GameManager.ItemType.Bait, baitTarget.baitID)].CheckIsFishAccept(fishStats.fishSpecies, fishStats.current_weight)) { baitTarget = null; } } } private void ShowWaterFX() { if (smuuggeParticle == null) { return; } if (base.transform.position.y >= deepProbe.z - GetMinDeepFish() * 4f && deepProbe.z + GetMinDeepFish() * 4f >= base.transform.position.y) { smuuggeParticle.gameObject.transform.localScale = Vector3.one * (0.1f + base.transform.localScale.y * 0.05f); if (!smuuggeParticle.isEmitting) { smuuggeParticle.Play(); } } else if (smuuggeParticle.isPlaying) { smuuggeParticle.Stop(); } } private void CheckEatDropBait() { if (baitInJaw == null) { return; } switch (baitInJaw.baitType) { case BaitStats.BaitType.None: if (Random.Range(0, 100) < 100) { baitInJaw.SetBaitOffFishJaw(); baitInJaw = null; } break; case BaitStats.BaitType.Feed: if (Random.Range(0, 100) < 20) { baitInJaw.SetBaitOffFishJaw(); baitInJaw = null; } else { Object.Destroy(baitInJaw.gameObject); baitInJaw = null; fishStats.currentFeed += 2f; } break; case BaitStats.BaitType.Hook: { int num = 40; if (Random.Range(0, 100) < num && stage != Stage.hooked) { baitInJaw.SetBaitOffFishJaw(); baitInJaw = null; } break; } case BaitStats.BaitType.Lure: if (Random.Range(0, 100) < 40 && stage != Stage.hooked) { baitInJaw.SetBaitOffFishJaw(); baitInJaw = null; } break; case BaitStats.BaitType.LiveFish: break; } } private void OnDestroy() { if (baitInJaw != null) { baitInJaw.SetBaitOffFishJaw(); } Object.Destroy(dstPointObject); Object.Destroy(controlCastFishPoint); } private void OnTriggerStay(Collider other) { if (other.tag == "Terrain") { contentAnimator.SetTrigger("RotateRight"); base.transform.Translate(Vector3.up * Time.deltaTime); } } }