HeavenStudioPlus/Assets/Scripts/Games/CropStomp/Veggie.cs
AstrlJelly c18113de99 Crop Stomp Fix + Fork Lifter Animation Tweak (#588)
* fork lifter weird reset thingy fixed

* crop stomp code review

im gonna be fixing that weird bug where inputs aren't scheduled if crop stomp is the first game (or if you start on it) but first
some of the code in this is nearly two years old. it needed a lot of check-ups.

* oh okay that bug was really easy to fix

* convert animation playing to beat scaled playing

* crop stomp fix
2023-12-05 22:38:55 +00:00

303 lines
9.7 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NaughtyBezierCurves;
using DG.Tweening;
using HeavenStudio.Util;
namespace HeavenStudio.Games.Scripts_CropStomp
{
public class Veggie : MonoBehaviour
{
static float pickedRotationSpeed = -1080f;
public bool isMole;
public Sprite[] veggieSprites;
public Animator moleAnim;
public SpriteRenderer veggieSprite;
public Transform veggieTrans;
public BezierCurve3D curve;
private BezierCurve3D hitCurve;
public double targetBeat;
private double stompedBeat;
private double pickedBeat;
private float pickTime = 1f;
private int veggieState = 0;
private bool boinked; // Player got barely when trying to pick.
private bool pickEligible = true;
private int veggieType;
private double landBeat;
private Tween squashTween;
private CropStomp game;
public void Init()
{
game = CropStomp.instance;
// if (Conductor.instance.isPlaying)
game.ScheduleInput(targetBeat - 1, 1f, CropStomp.InputAction_BasicPress, StompJust, StompMiss, Out);
if (!isMole)
{
veggieType = UnityEngine.Random.Range(0, veggieSprites.Length);
veggieSprite.sprite = veggieSprites[veggieType];
}
else
{
pickTime = 1.5f;
}
}
private bool gotStomped; // Safeguard in case nested Update() call breaks.
private void Update()
{
if (!game.isMarching) return;
switch (veggieState)
{
case -1: MissedUpdate(); return;
// case 0:
case 2: PickedUpdate(); return;
case 1:
float airPosition = Conductor.instance.GetPositionFromBeat(stompedBeat, landBeat - stompedBeat);
veggieTrans.position = curve.GetPoint(Mathf.Clamp(airPosition, 0, 1));
if (PlayerInput.GetIsAction(CropStomp.InputAction_FlickRelease) && !game.IsExpectingInputNow(CropStomp.InputAction_FlickRelease))
{
pickEligible = false;
}
break;
// default:
}
}
private void StompJust(PlayerActionEvent caller, float state)
{
if (GameManager.instance.autoplay)
{
StompVeggie(true);
return;
}
if (state >= 1f)
veggieState = -1;
else if (state > -1f)
StompVeggie(false);
}
private void StompMiss(PlayerActionEvent caller)
{
veggieState = -1;
caller.Disable();
}
private void Out(PlayerActionEvent caller) { }
private void PickJust(PlayerActionEvent caller, float state)
{
game.bodyAnim.DoScaledAnimationAsync("Pick", 0.5f);
game.isFlicking = true;
if (!pickEligible) return;
if (GameManager.instance.autoplay)
{
PickVeggie(true);
return;
}
if (state <= -1f || state >= 1f)
{
veggieState = -1;
boinked = true;
curve.transform.localScale = Vector3.one; // Return curve to normal size in the case of mole curves.
for (int i = 0; i < 2; i++)
{
var key = curve.KeyPoints[i];
var keyPos = key.Position;
key.Position = new Vector3(keyPos.x, veggieTrans.position.y + (i * 2), keyPos.z);
}
// var key1 = curve.KeyPoints[0];
// var key1Pos = key1.Position;
// key1.Position = new Vector3(key1Pos.x, veggieTrans.position.y, key1Pos.z);
// var key2 = curve.KeyPoints[1];
// var key2Pos = key2.Position;
// key2.Position = new Vector3(key2Pos.x, veggieTrans.position.y + 2f, key2Pos.z);
pickedBeat = Conductor.instance.songPositionInBeatsAsDouble;
SoundByte.PlayOneShot("miss");
MissedUpdate();
}
else
{
PickVeggie(false);
}
}
private void PickMiss(PlayerActionEvent caller)
{
veggieState = -1;
if (!isMole) SoundByte.PlayOneShotGame("cropStomp/veggieMiss");
caller.Disable();
}
bool moleLaughing;
private void MissedUpdate()
{
if (boinked)
{
float fallPosition = Conductor.instance.GetPositionFromBeat(pickedBeat, 1f);
fallPosition = Mathf.Clamp(fallPosition, 0, 1);
veggieTrans.position = curve.GetPoint(fallPosition);
if (fallPosition < 1f)
{
var rotSpeed = isMole ? pickedRotationSpeed : -pickedRotationSpeed;
veggieTrans.rotation = Quaternion.Euler(0, 0, veggieTrans.rotation.eulerAngles.z + (rotSpeed * Time.deltaTime));
}
else
{
veggieTrans.rotation = Quaternion.Euler(0, 0, 180f);
}
}
else
{
if (isMole && !moleLaughing)
{
var distDiff = transform.position.x - game.farmerTrans.position.x;
if (distDiff > 1.5f)
{
moleAnim.DoScaledAnimationAsync("Chuckle", 0.5f);
moleLaughing = true;
}
}
}
}
private void PickedUpdate()
{
float pickPosition = Conductor.instance.GetPositionFromBeat(pickedBeat, pickTime);
pickPosition = Mathf.Clamp(pickPosition, 0, 1);
veggieTrans.position = hitCurve.GetPoint(pickPosition);
var rotSpeed = isMole ? -pickedRotationSpeed : pickedRotationSpeed;
veggieTrans.rotation = Quaternion.Euler(0, 0, veggieTrans.rotation.eulerAngles.z + (rotSpeed * Time.deltaTime));
if (!isMole)
{
var veggieScale = Mathf.Min(1.5f - pickPosition, 1f);
veggieTrans.localScale = Vector2.one * veggieScale;
if (pickPosition >= 1f)
{
game.CollectPlant(veggieType);
}
}
}
private void StompVeggie(bool autoTriggered)
{
// Juuuuuust in case.
if (gotStomped)
{
Debug.Log("Recursion moment?");
return;
}
gotStomped = true;
Debug.Log("Stomped!");
var cond = Conductor.instance;
ParticleSystem spawnedHit = Instantiate(game.hitParticle, game.hitParticle.transform.parent);
spawnedHit.Play();
veggieState = 1;
game.ScheduleInput(targetBeat, isMole ? 0.5f : 1f, CropStomp.InputAction_FlickRelease, PickJust, PickMiss, Out);
targetBeat = targetBeat + (isMole ? 0.5f : 1f);
stompedBeat = cond.songPositionInBeatsAsDouble;
landBeat = targetBeat + (float)cond.SecsToBeats(Minigame.NgLateTime() - 1, cond.GetBpmAtBeat(targetBeat));
if (autoTriggered)
{
game.Stomp();
game.bodyAnim.DoScaledAnimationAsync("Stomp", 0.5f);
}
if (!isMole)
{
MultiSound.Play(
new MultiSound.Sound[] { new MultiSound.Sound("cropStomp/veggieOh", targetBeat - 0.5f) }
);
}
else
{
moleAnim.DoScaledAnimationAsync("Idle", 0.5f);
}
var veggieScale = veggieTrans.localScale;
veggieTrans.localScale = new Vector3(veggieScale.x * 0.5f, veggieScale.y, veggieScale.z);
squashTween = veggieTrans.DOScaleX(veggieScale.x, cond.pitchedSecPerBeat * 0.5f);
Update(); // Update flying veggie state immediately.
}
private void PickVeggie(bool autoTriggered)
{
veggieState = 2;
if (autoTriggered)
{
game.bodyAnim.DoScaledAnimationAsync("Pick", 0.5f);
game.isFlicking = true;
}
var key1 = game.pickCurve.KeyPoints[0];
var keyPos = key1.Position;
key1.Position = new Vector3(keyPos.x, veggieTrans.position.y, keyPos.z);
pickedBeat = Conductor.instance.songPositionInBeatsAsDouble;
if (!isMole)
{
BeatAction.New(this, new List<BeatAction.Action>()
{
new BeatAction.Action(pickedBeat + 0.5f, delegate { veggieSprite.sortingOrder = -1; }),
new BeatAction.Action(pickedBeat + pickTime, delegate { GameObject.Destroy(gameObject); })
});
SoundByte.PlayOneShotGame("cropStomp/veggieKay");
hitCurve = game.pickCurve;
}
else
{
BeatAction.New(this, new List<BeatAction.Action>()
{
new BeatAction.Action(pickedBeat + pickTime, delegate { GameObject.Destroy(gameObject); })
});
SoundByte.PlayOneShotGame("cropStomp/GEUH");
hitCurve = game.moleCurve;
}
if (squashTween != null)
squashTween.Kill(true);
PickedUpdate();
}
}
}