mirror of
https://github.com/RHeavenStudioPlus/HeavenStudioPlus.git
synced 2024-11-23 10:05:14 +00:00
3a4279ce5e
* Air Rally Text Update * Blue Bear Text Update * Board Meeting Text Update * Built To Scale DS Text Update also changed Air Rally's assetbundle tag from "normal" to "keep" * Catchy Tune Text Update also changed some minor wording in Board Meeting and Built To Scale DS * Cheer Readers Text Update * The Clappy Trio Text Update * Coin Toss Text Update * Crop Stomp Text Update * DJ School Text Update * Dog Ninja Text Update * Double Date Text Update * Drumming Practice Text Update * Fan Club Text Update * Fireworks Text Update * Second Contact Text Update * Flipper-Flop Text Update also fix an error in Catchy Tune * Fork Lifter Text Update * Glee Club Text Update * Karate Man Text Update also minor updates to other games * Kitties! Text Update * Launch Party Text Update * Lockstep Text Update * Marching Orders Text Update * Meat Grinder Text Update also fixed an error in Second Contact * Mr. Upbeat Text Update * Munchy Monk Text Update * Octopus Machine Text Update * Pajama Party Text Update * Quiz Show Text Update also changed some wording in meat grinder * Rhythm Rally Text Update * Rhythm Somen Text Update that was easy * Rhythm Tweezers Text Update * Ringside Text Update * Rockers Text Update this sucked * Samurai Slice DS Text Update * See Saw Text Update * Sneaky Spirits Text Update * Spaceball Text Update * Space Dance Text Update * Space Soccer Text Update * Splashdown Text Update * Tambourine Text Update * Tap Trial Text Update * Tap Troupe Text Update * The Dazzles Text Update * Toss Boys Text Update * Tram & Pauline Text Update also added translation for Fireworks * Tunnel Text Update * Wizard's Waltz Text Update * Working Dough Text Update * fix compiler errors * fix editor offset bug(?) * fix missing param in second contact * Ball Redispense text * remove space soccer swing * Trick on the Class Text Update * Non-Game Text Update * fix pre-function sorting * camera shake ease * remove a bunch of prints * rhythm tweezers bug fix * Update Credits.txt * ssds nop samurai bop * swap order of shake properties * Update FirstContact.cs --------- Co-authored-by: minenice55 <star.elementa@gmail.com>
431 lines
No EOL
14 KiB
C#
431 lines
No EOL
14 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
using HeavenStudio.Util;
|
|
using HeavenStudio.InputSystem;
|
|
|
|
namespace HeavenStudio.Games.Scripts_SpaceSoccer
|
|
{
|
|
public class Kicker : MonoBehaviour
|
|
{
|
|
SpaceSoccer game;
|
|
|
|
[Header("Properties")]
|
|
public bool canKick = true; //why was this false by default???
|
|
public bool canHighKick;
|
|
private bool kickPrepare = false;
|
|
public bool kickLeft;
|
|
bool kickLeftWhiff;
|
|
public double dispenserBeat; //unused
|
|
public int kickTimes = 0;
|
|
public bool player;
|
|
private string animName = "Enter";
|
|
private float animLength;
|
|
private double animStartBeat;
|
|
private EasingFunction.Ease ease;
|
|
bool stopBall;
|
|
|
|
[Header("Components")]
|
|
private Animator anim;
|
|
public Ball ball;
|
|
[SerializeField] private Animator enterExitAnim;
|
|
|
|
PlayerActionEvent nextHit;
|
|
PlayerActionEvent nextAutoKick;
|
|
|
|
private void Awake()
|
|
{
|
|
game = SpaceSoccer.instance;
|
|
anim = GetComponent<Animator>();
|
|
}
|
|
|
|
public void SetAnimParams(double beat, float length, string anim, int easeToPut)
|
|
{
|
|
animStartBeat = beat;
|
|
animLength = length;
|
|
animName = anim;
|
|
ease = (EasingFunction.Ease)easeToPut;
|
|
EasingFunction.Function func = EasingFunction.GetEasingFunction(ease);
|
|
float newAnimPos = func(0, 1, 0);
|
|
enterExitAnim.DoNormalizedAnimation(animName, newAnimPos);
|
|
}
|
|
|
|
public void DispenseBall(double beat)
|
|
{
|
|
if (player)
|
|
{
|
|
nextHit = game.ScheduleInput(beat, ball.GetAnimLength(Ball.State.Dispensing), SpaceSoccer.InputAction_BasicPress, KickJust, Miss, Out);
|
|
}
|
|
else
|
|
{
|
|
double beatToKick = beat + ball.GetAnimLength(Ball.State.Dispensing);
|
|
if (beatToKick < Conductor.instance.songPositionInBeatsAsDouble) beatToKick = ball.nextAnimBeat;
|
|
if (ball.state == Ball.State.HighKicked)
|
|
{
|
|
BeatAction.New(this, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beatToKick - 0.5f, delegate { Kick(true, true); }),
|
|
new BeatAction.Action(beatToKick, delegate { Toe(true); }),
|
|
new BeatAction.Action(beatToKick + ball.GetAnimLength(Ball.State.Toe), delegate { KickCheck(true, false, beatToKick + ball.GetAnimLength(Ball.State.Toe)); }),
|
|
});
|
|
}
|
|
else
|
|
{
|
|
BeatAction.New(this, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beatToKick, delegate { KickCheck(true, false, beatToKick); }),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Kick(bool hit, bool highKick = false)
|
|
{
|
|
if (stopBall) return;
|
|
|
|
if (player)
|
|
{
|
|
SoundByte.PlayOneShotGame("spaceSoccer/kick");
|
|
}
|
|
|
|
if (hit)
|
|
{
|
|
if (highKick)
|
|
{
|
|
if (kickLeft)
|
|
{
|
|
anim.DoScaledAnimationAsync("HighKickLeft_0", 0.5f);
|
|
}
|
|
else
|
|
{
|
|
anim.DoScaledAnimationAsync("HighKickRight_0", 0.5f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (kickLeft)
|
|
{
|
|
anim.DoScaledAnimationAsync("KickLeft", 0.5f);
|
|
}
|
|
else
|
|
{
|
|
anim.DoScaledAnimationAsync("KickRight", 0.5f);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (highKick)
|
|
{
|
|
if (kickLeftWhiff)
|
|
{
|
|
anim.DoScaledAnimationAsync("HighKickLeft_0", 0.5f);
|
|
}
|
|
else
|
|
{
|
|
anim.DoScaledAnimationAsync("HighKickRight_0", 0.5f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (kickLeftWhiff)
|
|
{
|
|
anim.DoScaledAnimationAsync("KickLeft", 0.5f);
|
|
}
|
|
else
|
|
{
|
|
anim.DoScaledAnimationAsync("KickRight", 0.5f);
|
|
}
|
|
}
|
|
kickLeftWhiff = !kickLeftWhiff;
|
|
}
|
|
|
|
|
|
if (ball == null) return;
|
|
|
|
if (highKick == false)
|
|
{
|
|
kickTimes++;
|
|
if (ball != null && hit)
|
|
ball.Kick(player);
|
|
}
|
|
else
|
|
{
|
|
kickPrepare = true;
|
|
}
|
|
}
|
|
|
|
public void HighKick(bool hit)
|
|
{
|
|
if (stopBall) return;
|
|
kickTimes++;
|
|
if (hit)
|
|
{
|
|
if (kickLeft)
|
|
{
|
|
anim.DoScaledAnimationAsync("HighKickLeft_0", 0.5f);
|
|
}
|
|
else
|
|
{
|
|
anim.DoScaledAnimationAsync("HighKickRight_0", 0.5f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (kickLeftWhiff)
|
|
{
|
|
anim.DoScaledAnimationAsync("HighKickLeft_0", 0.5f);
|
|
}
|
|
else
|
|
{
|
|
anim.DoScaledAnimationAsync("HighKickRight_0", 0.5f);
|
|
}
|
|
kickLeftWhiff = !kickLeftWhiff;
|
|
}
|
|
|
|
if (player) SoundByte.PlayOneShotGame("spaceSoccer/highkicktoe1");
|
|
if (hit && ball)
|
|
{
|
|
ball.HighKick();
|
|
|
|
if (player) SoundByte.PlayOneShotGame("spaceSoccer/highkicktoe1_hit");
|
|
}
|
|
|
|
}
|
|
|
|
public void Toe(bool hit, bool flick = false)
|
|
{
|
|
if (stopBall) return;
|
|
if (kickLeft)
|
|
{
|
|
anim.DoScaledAnimationAsync("ToeLeft", 0.5f);
|
|
}
|
|
else
|
|
{
|
|
anim.DoScaledAnimationAsync("ToeRight", 0.5f);
|
|
}
|
|
|
|
if (player)
|
|
{
|
|
SoundByte.PlayOneShotGame("spaceSoccer/highkicktoe3");
|
|
if (hit && ball)
|
|
{
|
|
SoundByte.PlayOneShotGame("spaceSoccer/highkicktoe3_hit");
|
|
}
|
|
}
|
|
|
|
if (hit && ball)
|
|
ball.Toe();
|
|
|
|
if (!flick)
|
|
{
|
|
kickTimes++;
|
|
kickPrepare = false;
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
float normalizedBeat = Conductor.instance.GetPositionFromBeat(animStartBeat, animLength);
|
|
if (normalizedBeat >= 0 && normalizedBeat <= 1)
|
|
{
|
|
EasingFunction.Function func = EasingFunction.GetEasingFunction(ease);
|
|
float newAnimPos = func(0, 1, normalizedBeat);
|
|
enterExitAnim.DoNormalizedAnimation(animName, newAnimPos);
|
|
}
|
|
if (kickTimes % 2 == 0)
|
|
{
|
|
kickLeft = false;
|
|
}
|
|
else
|
|
{
|
|
kickLeft = true;
|
|
}
|
|
|
|
var highKicks = GameManager.instance.Beatmap.Entities.FindAll(c => c.datamodel == "spaceSoccer/high kick-toe!");
|
|
for (int i = 0; i < highKicks.Count; i++)
|
|
{
|
|
if ((highKicks[i].beat - 0.15f) <= Conductor.instance.songPositionInBeatsAsDouble && highKicks[i].beat + 1f > Conductor.instance.songPositionInBeatsAsDouble)
|
|
{
|
|
canHighKick = true;
|
|
canKick = false;
|
|
|
|
if (ball)
|
|
{
|
|
ball.highKickSwing = 0.5f;
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
canKick = true;
|
|
canHighKick = false;
|
|
}
|
|
}
|
|
|
|
if (player)
|
|
{
|
|
if (stopBall) return;
|
|
if (PlayerInput.GetIsAction(SpaceSoccer.InputAction_BasicPress)
|
|
&& !game.IsExpectingInputNow(SpaceSoccer.InputAction_BasicPress))
|
|
{
|
|
if (ball == null)
|
|
KickCheck(false, true);
|
|
else
|
|
Kick(false, ball.canKick);
|
|
|
|
}
|
|
if (PlayerInput.GetIsAction(SpaceSoccer.InputAction_FlickRelease))
|
|
{
|
|
if (PlayerInput.CurrentControlStyle == InputController.ControlStyles.Touch)
|
|
{
|
|
if (ball == null || !(game.IsExpectingInputNow(SpaceSoccer.InputAction_FlickRelease) || ball.canKick))
|
|
{
|
|
Toe(false);
|
|
}
|
|
}
|
|
if (ball != null)
|
|
{
|
|
if (ball.waitKickRelease)
|
|
{
|
|
ball.waitKickRelease = false;
|
|
}
|
|
else if (ball.canKick && !game.IsExpectingInputNow(SpaceSoccer.InputAction_FlickRelease))
|
|
{
|
|
ball.canKick = false;
|
|
Kick(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void KickCheck(bool hit, bool overrideState = false, double beat = 0f)
|
|
{
|
|
if (stopBall) return;
|
|
if (canHighKick)
|
|
{
|
|
HighKick(hit);
|
|
if (!player)
|
|
{
|
|
BeatAction.New(this, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beat + ball.GetAnimLength(Ball.State.Kicked), delegate { Kick(true, true); }),
|
|
new BeatAction.Action(beat + ball.GetAnimLength(Ball.State.Toe), delegate { Toe(true); }),
|
|
new BeatAction.Action(beat + ball.GetAnimLength(Ball.State.Toe) + 1.5f, delegate { KickCheck(true, false, beat + ball.GetAnimLength(Ball.State.Toe) + 1.5f); }),
|
|
});
|
|
}
|
|
}
|
|
else if (canKick)
|
|
{
|
|
Kick(hit);
|
|
if (!player)
|
|
{
|
|
BeatAction.New(this, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beat + ball.GetAnimLength(Ball.State.Kicked), delegate { KickCheck(true, false, beat + ball.GetAnimLength(Ball.State.Kicked)); }),
|
|
});
|
|
}
|
|
}
|
|
else if (!canKick && !canHighKick && overrideState)
|
|
{
|
|
Kick(hit);
|
|
if (!player)
|
|
{
|
|
BeatAction.New(this, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beat + ball.GetAnimLength(Ball.State.Kicked), delegate { KickCheck(true, false, beat + ball.GetAnimLength(Ball.State.Kicked)); }),
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
public void StopBall(bool stop)
|
|
{
|
|
stopBall = stop;
|
|
if (ball != null && stop) Destroy(ball.gameObject);
|
|
}
|
|
|
|
void MissBall(double targetBeat)
|
|
{
|
|
if (stopBall) return;
|
|
|
|
var cond = Conductor.instance;
|
|
ball = null;
|
|
// queue the miss sound
|
|
MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("spaceSoccer/missNeutral", targetBeat + (float)cond.SecsToBeats(Minigame.NgLateTime()-1,
|
|
cond.GetBpmAtBeat(targetBeat)), SoundByte.GetPitchFromCents(UnityEngine.Random.Range(-75, 75), false)) });
|
|
}
|
|
|
|
private void KickJust(PlayerActionEvent caller, float state)
|
|
{
|
|
if (stopBall) return;
|
|
if (ball == null || state >= 1f || state <= -1f) { //todo: proper near miss feedback
|
|
KickCheck(false, true);
|
|
MissBall(caller.startBeat + caller.timer);
|
|
return;
|
|
}
|
|
KickCheck(true);
|
|
if (canHighKick)
|
|
{
|
|
// queue high kick inputs
|
|
nextHit = game.ScheduleInput(caller.startBeat + caller.timer, ball.GetAnimLength(Ball.State.Toe), SpaceSoccer.InputAction_FlickRelease, ToeJust, Miss, Out);
|
|
nextAutoKick = game.ScheduleAutoplayInput(caller.startBeat + caller.timer, ball.GetAnimLength(Ball.State.Kicked), SpaceSoccer.InputAction_BasicPress, ToePrepareJust, Out, Out);
|
|
ball.canKick = true;
|
|
ball.waitKickRelease = true;
|
|
}
|
|
else
|
|
{
|
|
// queue normal kick input
|
|
nextHit = game.ScheduleInput(caller.startBeat + caller.timer, ball.GetAnimLength(Ball.State.Kicked), SpaceSoccer.InputAction_BasicPress, KickJust, Miss, Out);
|
|
}
|
|
game.hitBeats.Add(caller.startBeat + caller.timer);
|
|
}
|
|
|
|
private void Miss(PlayerActionEvent caller)
|
|
{
|
|
if (stopBall) return;
|
|
if (ball != null)
|
|
MissBall(caller.startBeat + caller.timer);
|
|
|
|
// if this were any other keep the beat game you'd cue the next input here
|
|
}
|
|
|
|
private void ToeJust(PlayerActionEvent caller, float state)
|
|
{
|
|
if (stopBall) return;
|
|
|
|
if (ball == null || (!ball.canKick) || state >= 1f || state <= -1f) { //todo: proper near miss feedback
|
|
Toe(false);
|
|
MissBall(caller.startBeat + caller.timer);
|
|
return;
|
|
}
|
|
Toe(true);
|
|
nextHit = game.ScheduleInput(caller.startBeat, 3f, SpaceSoccer.InputAction_BasicPress, KickJust, Miss, Out);
|
|
ball.canKick = false;
|
|
game.hitBeats.Add(caller.startBeat + caller.timer);
|
|
}
|
|
|
|
private void ToePrepareJust(PlayerActionEvent caller, float state)
|
|
{
|
|
if (stopBall) return;
|
|
|
|
//autoplay only
|
|
Kick(true, true);
|
|
}
|
|
|
|
private void Out(PlayerActionEvent caller) {}
|
|
|
|
void OnDestroy()
|
|
{
|
|
if (nextHit != null)
|
|
nextHit.Disable();
|
|
if (nextAutoKick != null)
|
|
nextAutoKick.Disable();
|
|
if (ball != null) Destroy(ball.gameObject);
|
|
}
|
|
}
|
|
} |