using System.Collections; using System.Collections.Generic; using UnityEngine; using HeavenStudio.Util; using System.Resources; using System.Net; using System; namespace HeavenStudio.Games.Scripts_SeeSaw { public class SeeSawGuy : SuperCurveObject { public enum LandType { Big, Miss, Barely, Normal } public enum JumpState { None, StartJump, StartJumpIn, OutOut, InIn, InOut, OutIn, EndJumpOut, EndJumpIn, HighOutOut, HighOutIn, HighInOut, HighInIn } [SerializeField] bool see; [NonSerialized] public bool dead = false; public bool strum; public Animator anim; JumpState lastState; JumpState currentState; Path currentPath; Path cameraPath; SeeSaw game; double startBeat; double heightLastFrame; [NonSerialized] public bool canBop = true; [SerializeField] Transform landOutTrans; public Transform landInTrans; [SerializeField] Transform groundTrans; bool hasChangedAnimMidAir; [SerializeField] ParticleSystem deathParticle; double wantChoke = -1; float wantChokeLength; [SerializeField] private Animator invertAnim; private void Awake() { anim = transform.GetChild(0).GetComponent(); anim.Play(see ? "NeutralSee" : "NeutralSaw", 0, 0); game = SeeSaw.instance; cameraPath = game.GetPath("Camera"); } private void Update() { var cond = Conductor.instance; double currentBeat = cond.songPositionInBeatsAsDouble; if (cond.isPlaying && !cond.isPaused) { switch (currentState) { default: return; case JumpState.StartJump: transform.position = GetPathPositionFromBeat(currentPath, Math.Max(startBeat, currentBeat), out double height, startBeat); if (height < heightLastFrame && !hasChangedAnimMidAir) { anim.Play("Jump_OutOut_Fall", 0, 0); hasChangedAnimMidAir = true; } heightLastFrame = height; break; case JumpState.StartJumpIn: transform.position = GetPathPositionFromBeat(currentPath, Math.Max(startBeat, currentBeat), out double heightIn, startBeat); if (heightIn < heightLastFrame && !hasChangedAnimMidAir) { anim.Play("Jump_InIn_Fall", 0, 0); hasChangedAnimMidAir = true; } heightLastFrame = heightIn; break; case JumpState.OutOut: transform.position = GetPathPositionFromBeat(currentPath, Math.Max(startBeat, currentBeat), startBeat); if (currentBeat >= startBeat + 1 && !hasChangedAnimMidAir) { anim.Play("Jump_OutOut_Fall", 0, 0); hasChangedAnimMidAir = true; } break; case JumpState.InIn: transform.position = GetPathPositionFromBeat(currentPath, Math.Max(startBeat, currentBeat), startBeat); if (currentBeat >= startBeat + 0.5f && !hasChangedAnimMidAir) { anim.Play("Jump_InIn_Fall", 0, 0); hasChangedAnimMidAir = true; } break; case JumpState.InOut: transform.position = GetPathPositionFromBeat(currentPath, Math.Max(startBeat, currentBeat), startBeat); if (currentBeat >= startBeat + 0.5f) { if (!hasChangedAnimMidAir) anim.Play("Jump_InOut_Tuck", 0, 0); hasChangedAnimMidAir = true; transform.rotation = Quaternion.Euler(0, 0, (see ? 1 : -1) * Mathf.Lerp(0, 360, cond.GetPositionFromBeat(startBeat + 0.5f, 0.75f))); } break; case JumpState.OutIn: transform.position = GetPathPositionFromBeat(currentPath, Math.Max(startBeat, currentBeat), startBeat); if (currentBeat >= startBeat + 1f) { if (!hasChangedAnimMidAir) anim.Play("Jump_OutIn_Tuck", 0, 0); hasChangedAnimMidAir = true; transform.rotation = Quaternion.Euler(0, 0, (see ? -1 : 1) * Mathf.Lerp(0, 360, cond.GetPositionFromBeat(startBeat + 1f, 1f))); } break; case JumpState.EndJumpOut: case JumpState.EndJumpIn: transform.position = GetPathPositionFromBeat(currentPath, Math.Max(startBeat, currentBeat), startBeat); break; case JumpState.HighOutOut: case JumpState.HighOutIn: case JumpState.HighInOut: case JumpState.HighInIn: transform.position = GetPathPositionFromBeat(currentPath, Math.Max(startBeat, currentBeat), startBeat); break; } } } private void LateUpdate() { var cond = Conductor.instance; double currentBeat = cond.songPositionInBeatsAsDouble; if (!see && game.cameraMove && cond.isPlaying && !cond.isPaused) { switch (currentState) { default: return; case JumpState.HighOutOut: case JumpState.HighOutIn: case JumpState.HighInOut: case JumpState.HighInIn: float newCamY = Math.Max(GetPathPositionFromBeat(cameraPath, Math.Max(startBeat, currentBeat), startBeat).y, 0); GameCamera.additionalPosition = new Vector3(0, newCamY, 0); break; } } } public void Choke(double beat, float length) { if (!canBop || currentState != JumpState.None || dead) { wantChoke = beat; wantChokeLength = length; return; } dead = true; anim.DoScaledAnimationAsync("Choke_" + (see ? "See" : "Saw") + "_Intro", 0.5f); SoundByte.PlayOneShotGame("seeSaw/explosion" + (see ? "Black" : "White"), beat + length); BeatAction.New(gameObject, new List() { new BeatAction.Action(beat + length - 1, delegate { invertAnim.DoScaledAnimationAsync("Invert", 0.5f); }), new BeatAction.Action(beat + length, delegate { anim.DoScaledAnimationAsync("Explode", 0.5f); deathParticle.Play();}) }); } public void Bop() { if (!canBop || currentState != JumpState.None || dead) return; anim.DoScaledAnimationAsync("Bop" + (see ? "See" : "Saw") + (strum ? "_Strum" : ""), 0.5f); } public void Land(LandType landType, bool getUpOut) { transform.rotation = Quaternion.Euler(0, 0, 0); GameCamera.additionalPosition = Vector3.zero; bool landedOut = false; switch (currentState) { default: break; case JumpState.InOut: case JumpState.OutOut: case JumpState.StartJump: case JumpState.HighOutOut: case JumpState.HighInOut: landedOut = true; break; case JumpState.EndJumpOut: case JumpState.EndJumpIn: transform.position = groundTrans.position; SetState(JumpState.None, 0); if (wantChoke >= Conductor.instance.songPositionInBeatsAsDouble - 0.25f && wantChoke <= Conductor.instance.songPositionInBeatsAsDouble + 0.25f) { Choke(wantChoke, wantChokeLength); } else if (see ? game.seeShouldBop : game.sawShouldBop) { Bop(); } else { anim.Play("NeutralSee", 0, 0); } return; } if (landType is LandType.Big && !see) { game.SpawnOrbs(!landedOut, Conductor.instance.songPositionInBeatsAsDouble); } string landOut = landedOut ? "Out" : "In"; string typeOfLanding = ""; switch (landType) { case LandType.Big: typeOfLanding = "_Big"; break; case LandType.Miss: typeOfLanding = "_Miss"; break; case LandType.Barely: typeOfLanding = "_Barely"; break; default: break; } string animName = "Land_" + landOut + typeOfLanding; anim.DoScaledAnimationAsync(animName, 0.5f); if (landType is not LandType.Barely) { string getUpAnim = "GetUp_" + landOut + typeOfLanding; BeatAction.New(gameObject, new List() { new BeatAction.Action(Conductor.instance.songPositionInBeatsAsDouble + (getUpOut ? 1f : 0.5f), delegate { anim.DoScaledAnimationAsync(getUpAnim, 0.5f); }) }); } transform.position = landedOut ? landOutTrans.position : landInTrans.position; SetState(JumpState.None, 0); } public bool ShouldEndJumpOut() { switch (lastState) { default: return false; case JumpState.InOut: case JumpState.OutOut: case JumpState.StartJump: case JumpState.HighOutOut: case JumpState.HighInOut: return true; } } public void SetState(JumpState state, double beat, bool miss = false, float height = 0) { lastState = currentState; currentState = state; startBeat = beat; heightLastFrame = 0; hasChangedAnimMidAir = false; switch (currentState) { case JumpState.OutOut: currentPath = game.GetPath(see ? "SeeJumpOutOut" : "SawJumpOutOut"); anim.DoScaledAnimationAsync(miss ? "BadOut_SeeReact" : "Jump_OutOut_Start", 0.5f); break; case JumpState.StartJump: currentPath = game.GetPath("SeeStartJump"); anim.DoScaledAnimationAsync(miss ? "BadOut_SeeReact" : "Jump_OutOut_Start", 0.5f); break; case JumpState.InIn: anim.DoScaledAnimationAsync(miss ? "BadIn_SeeReact" : "Jump_InIn_Start", 0.5f); currentPath = game.GetPath(see ? "SeeJumpInIn" : "SawJumpInIn"); break; case JumpState.InOut: anim.DoScaledAnimationAsync(miss ? "BadIn_SeeReact" : "Jump_InIn_Start", 0.5f); currentPath = game.GetPath(see ? "SeeJumpInOut" : "SawJumpInOut"); break; case JumpState.StartJumpIn: currentPath = game.GetPath("SeeStartJumpIn"); anim.DoScaledAnimationAsync(miss ? "BadIn_SeeReact" : "Jump_InIn_Start", 0.5f); break; case JumpState.OutIn: currentPath = game.GetPath(see ? "SeeJumpOutIn" : "SawJumpOutIn"); anim.DoScaledAnimationAsync(miss ? "BadOut_SeeReact" : "Jump_OutIn_Start", 0.5f); break; case JumpState.EndJumpOut: currentPath = game.GetPath("SeeEndJumpOut"); anim.DoScaledAnimationAsync(miss ? "BadOut_SeeReact" : "Jump_OutIn_Start", 0.5f); break; case JumpState.EndJumpIn: anim.DoScaledAnimationAsync(miss ? "BadOut_SeeReact" : "Jump_OutIn_Start", 0.5f); currentPath = game.GetPath("SeeEndJumpIn"); break; case JumpState.HighOutOut: currentPath = game.GetPath(see ? "SeeHighOutOut" : "SawHighOutOut"); currentPath.positions[0].height = Mathf.Lerp(12, 28, height); cameraPath.positions[0].height = Mathf.Lerp(10, 26, height); cameraPath.positions[0].duration = 2f; anim.DoScaledAnimationAsync(miss ? "BadOut_SeeReact" : "Jump_OutOut_Start", 0.5f); if (see) return; BeatAction.New(gameObject, new List() { new BeatAction.Action(beat + 1, delegate { anim.DoScaledAnimationAsync("Jump_OutOut_Transform", 0.5f); }) }); break; case JumpState.HighOutIn: currentPath = game.GetPath(see ? "SeeHighOutIn" : "SawHighOutIn"); currentPath.positions[0].height = Mathf.Lerp(12, 28, height); cameraPath.positions[0].height = Mathf.Lerp(10, 26, height); cameraPath.positions[0].duration = 2f; anim.DoScaledAnimationAsync(miss ? "BadOut_SeeReact" : "Jump_OutIn_Start", 0.5f); if (see) return; BeatAction.New(gameObject, new List() { new BeatAction.Action(beat + 1, delegate { anim.DoScaledAnimationAsync("Jump_OutIn_Transform", 0.5f); }) }); break; case JumpState.HighInOut: currentPath = game.GetPath(see ? "SeeHighInOut" : "SawHighInOut"); currentPath.positions[0].height = Mathf.Lerp(9, 20, height); cameraPath.positions[0].height = Mathf.Lerp(7, 18, height); cameraPath.positions[0].duration = 1f; anim.DoScaledAnimationAsync(miss ? "BadIn_SeeReact" : "Jump_InIn_Start", 0.5f); if (see) return; BeatAction.New(gameObject, new List() { new BeatAction.Action(beat + 0.5f, delegate { anim.DoScaledAnimationAsync("Jump_OutOut_Transform", 0.5f); }) }); break; case JumpState.HighInIn: currentPath = game.GetPath(see ? "SeeHighInIn" : "SawHighInIn"); currentPath.positions[0].height = Mathf.Lerp(9, 20, height); cameraPath.positions[0].height = Mathf.Lerp(7, 18, height); cameraPath.positions[0].duration = 1f; anim.DoScaledAnimationAsync(miss ? "BadIn_SeeReact" : "Jump_InIn_Start", 0.5f); if (see) return; BeatAction.New(gameObject, new List() { new BeatAction.Action(beat + 0.5f, delegate { anim.DoScaledAnimationAsync("Jump_OutIn_Transform", 0.5f); }) }); break; default: break; } } } }