Second PlayerActionEvent Pass (#206)

* fix crop stomp input scheduling bugs

* update space soccer to use PlayerActionEvent

* update spaceball to use PlayerActionEvent

make PlayerActionEvents clean themselves up on game switch

* update rhythm rally to use PlayerActionEvent

* update rhythm tweezers to use PlayerActionEvent

* update mahou tsukai to use PlayerActionEvent

* reduce logging level
This commit is contained in:
minenice55 2023-01-15 22:05:25 -05:00 committed by GitHub
parent 825c4728d6
commit a57c373dfb
13 changed files with 283 additions and 399 deletions

View file

@ -94,6 +94,7 @@ namespace HeavenStudio.Games
var entities = GameManager.instance.Beatmap.entities; var entities = GameManager.instance.Beatmap.entities;
float startBeat = cond.songPositionInBeats; float startBeat = cond.songPositionInBeats;
float endBeat = Single.MaxValue;
if (inactiveStart == -1f) if (inactiveStart == -1f)
{ {
@ -136,6 +137,21 @@ namespace HeavenStudio.Games
inactiveStart = -1f; inactiveStart = -1f;
} }
// find out when the next game switch (or remix end) happens
var allEnds = EventCaller.GetAllInGameManagerList("gameManager", new string[] { "switchGame", "end" });
allEnds.Sort((x, y) => x.beat.CompareTo(y.beat));
//get the beat of the closest end event
foreach (var end in allEnds)
{
if (end.datamodel.Split(2) == "cropStomp") continue;
if (end.beat > startBeat)
{
endBeat = end.beat;
break;
}
}
// Veggie and mole events. // Veggie and mole events.
var vegEvents = entities.FindAll(v => v.datamodel == "cropStomp/veggies"); var vegEvents = entities.FindAll(v => v.datamodel == "cropStomp/veggies");
var moleEvents = entities.FindAll(m => m.datamodel == "cropStomp/mole"); var moleEvents = entities.FindAll(m => m.datamodel == "cropStomp/mole");
@ -154,7 +170,7 @@ namespace HeavenStudio.Games
for (int b = 0; b < veggiesInEvent; b++) for (int b = 0; b < veggiesInEvent; b++)
{ {
var targetVeggieBeat = vegBeat + 2f * b; var targetVeggieBeat = vegBeat + 2f * b;
if (startBeat <= targetVeggieBeat) if (startBeat <= targetVeggieBeat && targetVeggieBeat < endBeat)
{ {
SpawnVeggie(targetVeggieBeat, startBeat, false); SpawnVeggie(targetVeggieBeat, startBeat, false);
} }
@ -167,7 +183,7 @@ namespace HeavenStudio.Games
{ {
var moleBeat = moleEvents[i].beat; var moleBeat = moleEvents[i].beat;
if (startBeat <= moleBeat) if (startBeat <= moleBeat && moleBeat < endBeat)
{ {
SpawnVeggie(moleBeat, startBeat, true); SpawnVeggie(moleBeat, startBeat, true);
} }

View file

@ -223,7 +223,7 @@ namespace HeavenStudio.Games.Scripts_CropStomp
stompedBeat = cond.songPositionInBeats; stompedBeat = cond.songPositionInBeats;
landBeat = targetBeat + (float)cond.BeatsToSecs(Minigame.EndTime()-1, cond.GetBpmAtBeat(targetBeat)); landBeat = targetBeat + (float)cond.SecsToBeats(Minigame.EndTime()-1, cond.GetBpmAtBeat(targetBeat));
if (autoTriggered) if (autoTriggered)
{ {

View file

@ -249,5 +249,12 @@ namespace HeavenStudio.Games
Debug.LogWarning($"Sound sequence {name} not found in game {game} (did you build AssetBundles?)"); Debug.LogWarning($"Sound sequence {name} not found in game {game} (did you build AssetBundles?)");
return null; return null;
} }
private void OnDestroy() {
foreach (var evt in scheduledInputs)
{
evt.Disable();
}
}
} }
} }

View file

@ -27,77 +27,62 @@ namespace HeavenStudio.Games.Scripts_RhythmRally
{ {
if (!game.served || game.missed || !game.started) return; if (!game.served || game.missed || !game.started) return;
var cond = Conductor.instance; if (PlayerInput.Pressed() && !game.IsExpectingInputNow(InputType.STANDARD_DOWN))
float stateBeat = cond.GetPositionFromMargin(game.targetBeat, 1f);
StateCheck(stateBeat);
if (PlayerInput.Pressed())
{
if (state.perfect)
{
Ace();
}
else if (state.notPerfect())
{
Miss();
Jukebox.PlayOneShot("miss");
playerAnim.Play("Swing", 0, 0);
game.missCurve.KeyPoints[0].Position = game.ball.transform.position;
game.missCurve.transform.localScale = new Vector3(state.early ? 1f : -1f, 1f, 1f);
game.missBeat = cond.songPositionInBeats;
}
else
{ {
// Play "whoosh" sound here // Play "whoosh" sound here
playerAnim.Play("Swing", 0, 0); playerAnim.Play("Swing", 0, 0);
} }
} }
if (stateBeat > Minigame.EndTime())
{
Miss();
game.ball.SetActive(false);
}
}
void Ace() void Ace()
{ {
game.served = false; game.served = false;
var hitBeat = cond.songPositionInBeats; var hitBeat = cond.songPositionInBeats;
var bounceBeat = game.targetBeat + 1f; var bounceBeat = game.serveBeat + game.targetBeat + 1f;
if (game.rallySpeed == RhythmRally.RallySpeed.Slow) if (game.rallySpeed == RhythmRally.RallySpeed.Slow)
{ {
bounceBeat = game.targetBeat + 2f; bounceBeat = game.serveBeat + game.targetBeat + 2f;
} }
else if (game.rallySpeed == RhythmRally.RallySpeed.SuperFast) else if (game.rallySpeed == RhythmRally.RallySpeed.SuperFast)
{ {
bounceBeat = game.targetBeat + 0.5f; bounceBeat = game.serveBeat + game.targetBeat + 0.5f;
} }
playerAnim.Play("Swing", 0, 0); playerAnim.Play("Swing", 0, 0);
MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("rhythmRally/Return", hitBeat), new MultiSound.Sound("rhythmRally/ReturnBounce", bounceBeat) }); MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("rhythmRally/Return", hitBeat), new MultiSound.Sound("rhythmRally/ReturnBounce", bounceBeat) });
BounceFX(bounceBeat); BounceFX(bounceBeat);
game.ball.SetActive(true);
} }
void Miss() void NearMiss(float state)
{
MissBall();
Jukebox.PlayOneShot("miss");
playerAnim.Play("Swing", 0, 0);
game.missCurve.KeyPoints[0].Position = game.ball.transform.position;
game.missCurve.transform.localScale = new Vector3(-state, 1f, 1f);
game.missBeat = cond.songPositionInBeats;
game.ball.SetActive(true);
}
void MissBall()
{ {
game.served = false; game.served = false;
game.missed = true; game.missed = true;
var whistleBeat = game.targetBeat + 1f; var whistleBeat = game.serveBeat + game.targetBeat + 1f;
if (game.rallySpeed == RhythmRally.RallySpeed.Slow) if (game.rallySpeed == RhythmRally.RallySpeed.Slow)
{ {
whistleBeat = game.targetBeat + 2f; whistleBeat = game.serveBeat + game.targetBeat + 2f;
} }
else if (game.rallySpeed == RhythmRally.RallySpeed.SuperFast) else if (game.rallySpeed == RhythmRally.RallySpeed.SuperFast)
{ {
whistleBeat = game.targetBeat + 0.5f; whistleBeat = game.serveBeat + game.targetBeat + 0.5f;
} }
MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("rhythmRally/Whistle", whistleBeat) }); MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("rhythmRally/Whistle", whistleBeat) });
@ -117,9 +102,20 @@ namespace HeavenStudio.Games.Scripts_RhythmRally
}); });
} }
public override void OnAce() public void Just(PlayerActionEvent caller, float state)
{ {
if (state >= 1f || state <= -1f) {
NearMiss(state);
return;
}
Ace(); Ace();
} }
public void Miss(PlayerActionEvent caller)
{
MissBall();
}
public void Out(PlayerActionEvent caller) {}
} }
} }

View file

@ -28,7 +28,8 @@ namespace HeavenStudio.Games.Loaders
new GameAction("toss ball", "Toss Ball") new GameAction("toss ball", "Toss Ball")
{ {
function = delegate { RhythmRally.instance.Toss(eventCaller.currentEntity.beat, eventCaller.currentEntity.length, 6f, true); }, function = delegate { RhythmRally.instance.Toss(eventCaller.currentEntity.beat, eventCaller.currentEntity.length, 6f, true); },
defaultLength = 2f defaultLength = 2f,
resizable = true
}, },
new GameAction("rally", "Rally") new GameAction("rally", "Rally")
{ {
@ -375,16 +376,16 @@ namespace HeavenStudio.Games
switch (rallySpeed) switch (rallySpeed)
{ {
case RallySpeed.Normal: case RallySpeed.Normal:
targetBeat = serveBeat + 2f; targetBeat = 2f;
bounceBeat = serveBeat + 1f; bounceBeat = serveBeat + 1f;
break; break;
case RallySpeed.Fast: case RallySpeed.Fast:
case RallySpeed.SuperFast: case RallySpeed.SuperFast:
targetBeat = serveBeat + 1f; targetBeat = 1f;
bounceBeat = serveBeat + 0.5f; bounceBeat = serveBeat + 0.5f;
break; break;
case RallySpeed.Slow: case RallySpeed.Slow:
targetBeat = serveBeat + 4f; targetBeat = 4f;
bounceBeat = serveBeat + 2f; bounceBeat = serveBeat + 2f;
break; break;
} }
@ -393,7 +394,7 @@ namespace HeavenStudio.Games
MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("rhythmRally/Serve", serveBeat), new MultiSound.Sound("rhythmRally/ServeBounce", bounceBeat) }); MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("rhythmRally/Serve", serveBeat), new MultiSound.Sound("rhythmRally/ServeBounce", bounceBeat) });
paddlers.BounceFX(bounceBeat); paddlers.BounceFX(bounceBeat);
paddlers.ResetState(); ScheduleInput(serveBeat, targetBeat, InputType.STANDARD_DOWN, paddlers.Just, paddlers.Miss, paddlers.Out);
} }
public void Toss(float beat, float length, float height, bool firstToss = false) public void Toss(float beat, float length, float height, bool firstToss = false)
@ -401,6 +402,9 @@ namespace HeavenStudio.Games
// Hide trail while tossing to prevent weirdness while teleporting ball. // Hide trail while tossing to prevent weirdness while teleporting ball.
ballTrail.gameObject.SetActive(false); ballTrail.gameObject.SetActive(false);
if (firstToss)
height *= length/2f;
tossCurve.transform.localScale = new Vector3(1f, height, 1f); tossCurve.transform.localScale = new Vector3(1f, height, 1f);
tossBeat = beat; tossBeat = beat;
tossLength = length; tossLength = length;

View file

@ -21,24 +21,12 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
tweezers = game.Tweezers; tweezers = game.Tweezers;
} }
private void Start() {
game.ScheduleInput(createBeat, game.tweezerBeatOffset + game.beatInterval, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, Just, Miss, Out);
}
private void Update() private void Update()
{ {
if (plucked) return;
float stateBeat = Conductor.instance.GetPositionFromMargin(createBeat + game.tweezerBeatOffset + game.beatInterval, 1f);
StateCheck(stateBeat);
if (PlayerInput.Pressed(true))
{
if (state.perfect)
{
Ace();
}
else if (state.notPerfect())
{
Miss();
}
}
} }
public void Ace() public void Ace()
@ -48,16 +36,27 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
plucked = true; plucked = true;
} }
public void Miss() public void NearMiss()
{ {
tweezers.Pluck(false, this); tweezers.Pluck(false, this);
tweezers.hitOnFrame++; tweezers.hitOnFrame++;
plucked = true; plucked = true;
} }
public override void OnAce() private void Just(PlayerActionEvent caller, float state)
{ {
if (state >= 1f || state <= -1f) {
NearMiss();
return;
}
Ace(); Ace();
} }
private void Miss(PlayerActionEvent caller)
{
// this is where perfect challenge breaks
}
private void Out(PlayerActionEvent caller) {}
} }
} }

View file

@ -21,6 +21,9 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
private Sound pullSound; private Sound pullSound;
PlayerActionEvent endEvent;
InputType endInput;
private void Awake() private void Awake()
{ {
game = RhythmTweezers.instance; game = RhythmTweezers.instance;
@ -28,70 +31,23 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
tweezers = game.Tweezers; tweezers = game.Tweezers;
} }
private void Start() {
game.ScheduleInput(createBeat, game.tweezerBeatOffset + game.beatInterval, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, StartJust, StartMiss, Out);
}
private void Update() private void Update()
{ {
float stateBeat;
switch (pluckState)
{
// Able to be held.
case 0:
stateBeat = Conductor.instance.GetPositionFromMargin(createBeat + game.tweezerBeatOffset + game.beatInterval, 1f);
StateCheck(stateBeat);
if (PlayerInput.Pressed(true))
{
if (state.perfect)
{
pullSound = Jukebox.PlayOneShotGame($"rhythmTweezers/longPull{UnityEngine.Random.Range(1, 5)}");
pluckState = 1;
ResetState();
}
else if (state.notPerfect())
{
// I don't know what happens if you mess up here.
pluckState = -1;
}
}
break;
// In held state. Able to be released.
case 1:
stateBeat = Conductor.instance.GetPositionFromMargin(createBeat + game.tweezerBeatOffset + game.beatInterval + 0.5f, 1f);
StateCheck(stateBeat);
if (PlayerInput.PressedUp(true))
{
// It's possible to release earlier than earlyTime,
// and the hair will automatically be released before lateTime,
// so standard state checking isn't applied here
// (though StateCheck is still used for autoplay).
if (stateBeat >= Minigame.perfectTime)
{
Ace();
}
else
{
var normalized = Conductor.instance.GetPositionFromBeat(createBeat + game.tweezerBeatOffset + game.beatInterval, 0.5f);
// Hair gets released early and returns whoops.
anim.Play("LoopPullReverse", 0, normalized);
tweezers.anim.Play("Idle", 0, 0);
if (pullSound != null)
pullSound.Stop();
pluckState = -1;
}
}
break;
// Released or missed. Can't be held or released.
default:
break;
}
if (pluckState == 1) if (pluckState == 1)
{ {
bool input = PlayerInput.PressedUp();
if (endInput == InputType.DIRECTION_UP) input = PlayerInput.GetAnyDirectionUp();
if (input && !game.IsExpectingInputNow(endInput))
{
endEvent.MakeInEligible();
EndEarly();
return;
}
Vector3 tst = tweezers.tweezerSpriteTrans.position; Vector3 tst = tweezers.tweezerSpriteTrans.position;
var hairDirection = new Vector3(tst.x + 0.173f, tst.y) - holder.transform.position; var hairDirection = new Vector3(tst.x + 0.173f, tst.y) - holder.transform.position;
holder.transform.rotation = Quaternion.FromToRotation(Vector3.down, hairDirection); holder.transform.rotation = Quaternion.FromToRotation(Vector3.down, hairDirection);
@ -102,13 +58,13 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
// Auto-release if holding at release time. // Auto-release if holding at release time.
if (normalizedBeat >= 1f) if (normalizedBeat >= 1f)
Ace(); endEvent.Hit(0f);
} }
loop.transform.localScale = Vector2.one / holder.transform.localScale; loop.transform.localScale = Vector2.one / holder.transform.localScale;
} }
public void Ace() public void EndAce()
{ {
tweezers.LongPluck(true, this); tweezers.LongPluck(true, this);
tweezers.hitOnFrame++; tweezers.hitOnFrame++;
@ -119,18 +75,52 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
pluckState = -1; pluckState = -1;
} }
public override void OnAce() public void EndEarly()
{ {
if (pluckState == 0) var normalized = Conductor.instance.GetPositionFromBeat(createBeat + game.tweezerBeatOffset + game.beatInterval, 0.5f);
anim.Play("LoopPullReverse", 0, normalized);
tweezers.anim.Play("Idle", 0, 0);
if (pullSound != null)
pullSound.Stop();
pluckState = -1;
}
private void StartJust(PlayerActionEvent caller, float state)
{ {
// don't count near misses
if (state >= 1f || state <= -1f) {
pluckState = -1;
return;
}
if (PlayerInput.GetAnyDirectionDown())
{
endInput = InputType.DIRECTION_UP;
}
else
{
endInput = InputType.STANDARD_UP;
}
pullSound = Jukebox.PlayOneShotGame($"rhythmTweezers/longPull{UnityEngine.Random.Range(1, 5)}"); pullSound = Jukebox.PlayOneShotGame($"rhythmTweezers/longPull{UnityEngine.Random.Range(1, 5)}");
pluckState = 1; pluckState = 1;
ResetState(); endEvent = game.ScheduleInput(createBeat, game.tweezerBeatOffset + game.beatInterval + 0.5f, endInput, EndJust, Out, Out);
} }
else if (pluckState == 1)
private void StartMiss(PlayerActionEvent caller)
{ {
Ace(); // this is where perfect challenge breaks
} }
private void Out(PlayerActionEvent caller) {}
private void EndJust(PlayerActionEvent caller, float state)
{
if (state <= -1f) {
EndEarly();
return;
}
EndAce();
} }
} }
} }

View file

@ -27,7 +27,8 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
public float nextAnimBeat; public float nextAnimBeat;
public float highKickSwing = 0f; public float highKickSwing = 0f;
private float lastSpriteRot; private float lastSpriteRot;
public bool canKick; //unused public bool canKick;
public bool waitKickRelease;
private bool lastKickLeft; private bool lastKickLeft;
public void Init(Kicker kicker, float dispensedBeat) public void Init(Kicker kicker, float dispensedBeat)
@ -182,14 +183,6 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
holder.transform.localPosition = dispenseCurve.GetPoint(normalizedBeatAnim); holder.transform.localPosition = dispenseCurve.GetPoint(normalizedBeatAnim);
spriteHolder.transform.eulerAngles = new Vector3(0, 0, Mathf.Lerp(0f, -1440f, normalizedBeatAnim)); spriteHolder.transform.eulerAngles = new Vector3(0, 0, Mathf.Lerp(0f, -1440f, normalizedBeatAnim));
/*if (PlayerInput.Pressed())
{
if (state.perfect)
{
Kick();
}
}*/
break; break;
} }
case State.Kicked: case State.Kicked:
@ -208,22 +201,6 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
} }
holder.transform.localPosition = kickCurve.GetPoint(normalizedBeatAnim); holder.transform.localPosition = kickCurve.GetPoint(normalizedBeatAnim);
/*if (PlayerInput.Pressed())
{
if (state.perfect)
{
if (kicker.canHighKick)
{
HighKick();
}
else if (kicker.canKick)
{
Kick();
}
// print(normalizedBeat);
}
}*/
break; break;
} }
case State.HighKicked: case State.HighKicked:
@ -234,24 +211,6 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
holder.transform.localPosition = highKickCurve.GetPoint(normalizedBeatAnim); holder.transform.localPosition = highKickCurve.GetPoint(normalizedBeatAnim);
spriteHolder.transform.eulerAngles = new Vector3(0, 0, Mathf.Lerp(lastSpriteRot, lastSpriteRot + 360f, normalizedBeatAnim)); spriteHolder.transform.eulerAngles = new Vector3(0, 0, Mathf.Lerp(lastSpriteRot, lastSpriteRot + 360f, normalizedBeatAnim));
// if (state.perfect) Debug.Break();
/*if (PlayerInput.Pressed())
{
kickPrepare = true;
kicker.Kick(this);
}
if (kickPrepare)
{
if (PlayerInput.PressedUp())
{
if (state.perfect)
{
Toe();
}
}
}*/
break; break;
} }
case State.Toe: case State.Toe:

View file

@ -8,6 +8,8 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
{ {
public class Kicker : PlayerActionObject public class Kicker : PlayerActionObject
{ {
SpaceSoccer game;
[Header("Properties")] [Header("Properties")]
public bool canKick = true; //why was this false by default??? public bool canKick = true; //why was this false by default???
public bool canHighKick; public bool canHighKick;
@ -21,40 +23,25 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
private Animator anim; private Animator anim;
public Ball ball; public Ball ball;
PlayerActionEvent nextHit;
PlayerActionEvent nextAutoKick;
private void Awake() private void Awake()
{ {
game = SpaceSoccer.instance;
anim = GetComponent<Animator>(); anim = GetComponent<Animator>();
} }
public override void OnAce() public void DispenseBall(float beat)
{ {
if (ball.state == Ball.State.HighKicked) if (player)
{ {
if (!kickPrepare) nextHit = game.ScheduleInput(beat, ball.GetAnimLength(Ball.State.Dispensing), InputType.STANDARD_DOWN, KickJust, Miss, Out);
{
Kick(false, true);
}
else
{
Toe(true);
}
}
else
{
if (canHighKick)
{
HighKick(true);
}
else
{
Kick(true);
}
} }
} }
public void Kick(bool hit, bool highKick = false) public void Kick(bool hit, bool highKick = false)
{ {
kickTimes++;
aceTimes = 0; aceTimes = 0;
if (player) if (player)
@ -87,6 +74,7 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
if (highKick == false) if (highKick == false)
{ {
kickTimes++;
if (ball != null && hit) if (ball != null && hit)
ball.Kick(player); ball.Kick(player);
} }
@ -94,8 +82,6 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
{ {
kickPrepare = true; kickPrepare = true;
} }
ResetState();
} }
public void HighKick(bool hit) public void HighKick(bool hit)
@ -123,8 +109,6 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
if (player) if (player)
Jukebox.PlayOneShotGame("spaceSoccer/highkicktoe1"); Jukebox.PlayOneShotGame("spaceSoccer/highkicktoe1");
} }
ResetState();
} }
public void Toe(bool hit) public void Toe(bool hit)
@ -153,8 +137,8 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
if (hit && ball) if (hit && ball)
ball.Toe(); ball.Toe();
kickTimes++;
kickPrepare = false; kickPrepare = false;
ResetState();
} }
private void Update() private void Update()
@ -168,21 +152,6 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
kickLeft = true; kickLeft = true;
} }
// List<Beatmap.Entity> keepUps = GameManager.instance.Beatmap.entities.FindAll(c => c.datamodel == "spaceSoccer/keep-up");
// for (int i = 0; i < keepUps.Count; i++)
// {
// if ((keepUps[i].beat - 0.15f) <= Conductor.instance.songPositionInBeats && (keepUps[i].beat + keepUps[i].length) - 0.15f > Conductor.instance.songPositionInBeats)
// {
// canKick = true;
// canHighKick = false;
// break;
// }
// else
// {
// canKick = false;
// }
// }
var highKicks = GameManager.instance.Beatmap.entities.FindAll(c => c.datamodel == "spaceSoccer/high kick-toe!"); var highKicks = GameManager.instance.Beatmap.entities.FindAll(c => c.datamodel == "spaceSoccer/high kick-toe!");
for (int i = 0; i < highKicks.Count; i++) for (int i = 0; i < highKicks.Count; i++)
{ {
@ -206,129 +175,30 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
} }
} }
if (ball)
{
switch (ball.state)
{
case Ball.State.Dispensing:
{
float normalizedBeat = Conductor.instance.GetPositionFromBeat(ball.startBeat, ball.GetAnimLength(Ball.State.Dispensing));
StateCheck(normalizedBeat, !player);
CheckIfFall(normalizedBeat);
if (player) if (player)
{ {
if (PlayerInput.Pressed()) if (PlayerInput.Pressed() && !game.IsExpectingInputNow(InputType.STANDARD_DOWN))
{
if (state.perfect)
{
KickCheck(true);
}
else
{ {
if (ball == null)
KickCheck(false, true); KickCheck(false, true);
}
}
}
break;
}
case Ball.State.Kicked:
{
float normalizedBeat = Conductor.instance.GetPositionFromBeat(ball.startBeat, ball.GetAnimLength(Ball.State.Kicked));
StateCheck(normalizedBeat, !player);
CheckIfFall(normalizedBeat);
if (player)
{
if (PlayerInput.Pressed())
{
if (state.perfect)
{
KickCheck(true);
}
else else
{ Kick(false, ball.canKick);
KickCheck(false, true);
}
}
}
break;
}
case Ball.State.HighKicked:
{
float normalizedBeat = Conductor.instance.GetPositionFromMargin(ball.startBeat + ball.GetAnimLength(Ball.State.HighKicked), 1f);
if (!kickPrepare)
{
float normalizedBeatPrepare = Conductor.instance.GetPositionFromBeat(ball.startBeat, 1f);
StateCheck(normalizedBeatPrepare, !player);
CheckIfFall(normalizedBeat);
if (player) }
if (PlayerInput.PressedUp() && ball != null)
{ {
if (PlayerInput.Pressed() || PlayerInput.AltPressed()) if (ball.waitKickRelease)
{ {
Kick(false, true); ball.waitKickRelease = false;
} }
} else if (ball.canKick && !game.IsExpectingInputNow(InputType.STANDARD_UP))
}
else
{ {
StateCheck(normalizedBeat, !player); ball.canKick = false;
CheckIfFall(normalizedBeat); Kick(false);
if (player)
{
if (PlayerInput.PressedUp() || PlayerInput.AltPressedUp())
{
if (state.perfect)
{
Toe(true);
}
else
{
Toe(false);
} }
} }
} }
} }
break;
}
case Ball.State.Toe:
{
float normalizedBeat = Conductor.instance.GetPositionFromMargin(ball.startBeat + ball.GetAnimLength(Ball.State.Toe), 1f);
StateCheck(normalizedBeat, !player);
CheckIfFall(normalizedBeat);
if (player)
{
if (PlayerInput.Pressed())
{
if (state.perfect)
{
KickCheck(true);
}
else
{
KickCheck(false, true);
}
}
}
break;
}
}
}
else
{
if (player)
{
if (PlayerInput.Pressed())
{
KickCheck(false, true);
}
}
}
}
private void KickCheck(bool hit, bool overrideState = false) private void KickCheck(bool hit, bool overrideState = false)
{ {
@ -346,14 +216,71 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
} }
} }
private void CheckIfFall(float normalizedBeat) void MissBall(float targetBeat)
{ {
if (normalizedBeat > Minigame.LateTime() && (!GameManager.instance.autoplay || !GameManager.instance.canInput)) var cond = Conductor.instance;
{
Jukebox.PlayOneShotGame("spaceSoccer/missNeutral");
ball = null; ball = null;
ResetState(); // queue the miss sound
MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("spaceSoccer/missNeutral", targetBeat + (float)cond.SecsToBeats(Minigame.EndTime()-1, cond.GetBpmAtBeat(targetBeat))) });
} }
private void KickJust(PlayerActionEvent caller, float state)
{
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), InputType.STANDARD_UP, ToeJust, Miss, Out);
nextAutoKick = game.ScheduleAutoplayInput(caller.startBeat + caller.timer, ball.GetAnimLength(Ball.State.Kicked), InputType.STANDARD_DOWN, 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), InputType.STANDARD_DOWN, KickJust, Miss, Out);
}
}
private void Miss(PlayerActionEvent caller)
{
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 (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, InputType.STANDARD_DOWN, KickJust, Miss, Out);
ball.canKick = false;
}
private void ToePrepareJust(PlayerActionEvent caller, float state)
{
//autoplay only
Kick(true, true);
}
private void Out(PlayerActionEvent caller) {}
void OnDestroy()
{
if (nextHit != null)
nextHit.Disable();
if (nextAutoKick != null)
nextAutoKick.Disable();
} }
} }
} }

View file

@ -116,6 +116,7 @@ namespace HeavenStudio.Games
{ {
DispenseSound(beat); DispenseSound(beat);
} }
kicker.DispenseBall(beat);
kicker.canKick = true; kicker.canKick = true;
} }

View file

@ -35,15 +35,12 @@ namespace HeavenStudio.Games.Scripts_Spaceball
float rot = Random.Range(0, 360); float rot = Random.Range(0, 360);
Sprite.gameObject.transform.eulerAngles = new Vector3(0, 0, rot); Sprite.gameObject.transform.eulerAngles = new Vector3(0, 0, rot);
// PlayerActionInit(this.gameObject, startBeat, Spaceball.instance.EligibleHits);
isEligible = true; isEligible = true;
} }
public override void OnAce() private void Start()
{ {
this.Hit(); Spaceball.instance.ScheduleInput(startBeat, high ? 2f : 1f, InputType.STANDARD_DOWN, Just, Miss, Out);
} }
private void Hit() private void Hit()
@ -67,7 +64,7 @@ namespace HeavenStudio.Games.Scripts_Spaceball
SpaceballPlayer.instance.Swing(this); SpaceballPlayer.instance.Swing(this);
} }
private void Miss() private void NearMiss()
{ {
Holder.transform.GetChild(0).gameObject.AddComponent<Rotate>().rotateSpeed = -55; Holder.transform.GetChild(0).gameObject.AddComponent<Rotate>().rotateSpeed = -55;
@ -85,9 +82,10 @@ namespace HeavenStudio.Games.Scripts_Spaceball
private void Update() private void Update()
{ {
var cond = Conductor.instance;
if (hit) if (hit)
{ {
float nba = Conductor.instance.GetPositionFromBeat(hitBeat, 14); float nba = cond.GetPositionFromBeat(hitBeat, 14);
Holder.transform.localPosition = Vector3.Lerp(hitPos, new Vector3(randomEndPosX, 0f, -600f), nba); Holder.transform.localPosition = Vector3.Lerp(hitPos, new Vector3(randomEndPosX, 0f, -600f), nba);
Holder.transform.eulerAngles = Vector3.Lerp(new Vector3(0, 0, hitRot), new Vector3(0, 0, -2260), nba); Holder.transform.eulerAngles = Vector3.Lerp(new Vector3(0, 0, hitRot), new Vector3(0, 0, -2260), nba);
} }
@ -96,8 +94,7 @@ namespace HeavenStudio.Games.Scripts_Spaceball
float beatLength = 1f; float beatLength = 1f;
if (high) beatLength = 2f; if (high) beatLength = 2f;
float normalizedBeatAnim = Conductor.instance.GetPositionFromBeat(startBeat, beatLength + 0.15f); float normalizedBeatAnim = cond.GetPositionFromBeat(startBeat, beatLength + (float)cond.SecsToBeats(Minigame.EndTime()-1, cond.GetBpmAtBeat(startBeat + beatLength)));
// print(normalizedBeatAnim + " " + Time.frameCount);
if (high) if (high)
{ {
@ -109,35 +106,25 @@ namespace HeavenStudio.Games.Scripts_Spaceball
} }
anim.speed = 0; anim.speed = 0;
}
}
float normalizedBeat = Conductor.instance.GetPositionFromBeat(startBeat, beatLength); private void Just(PlayerActionEvent caller, float state)
StateCheck(normalizedBeat);
if (PlayerInput.Pressed())
{
if (state.perfect)
{ {
if (state >= 1f || state <= -1f) {
NearMiss();
return;
}
Hit(); Hit();
} }
else if (state.notPerfect())
{
Miss();
}
}
// too lazy to make a proper fix for this private void Miss(PlayerActionEvent caller)
float endTime = 1.2f;
if (high) endTime = 1.1f;
if (normalizedBeat > endTime)
{ {
Jukebox.PlayOneShotGame("spaceball/fall"); Jukebox.PlayOneShotGame("spaceball/fall");
Instantiate(Spaceball.instance.Dust, Spaceball.instance.Dust.transform.parent).SetActive(true); Instantiate(Spaceball.instance.Dust, Spaceball.instance.Dust.transform.parent).SetActive(true);
Destroy(this.gameObject); Destroy(this.gameObject);
} }
}
}
}
private void Out(PlayerActionEvent caller) {}
}
} }

View file

@ -24,6 +24,10 @@ namespace HeavenStudio.Games.Scripts_WizardsWaltz
animator.Play("Appear", 0, 0); animator.Play("Appear", 0, 0);
} }
private void Start() {
game.ScheduleInput(createBeat, game.beatInterval, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, Just, Miss, Out);
}
private void Update() private void Update()
{ {
if (!passed && Conductor.instance.songPositionInBeats > createBeat + game.beatInterval) if (!passed && Conductor.instance.songPositionInBeats > createBeat + game.beatInterval)
@ -31,23 +35,6 @@ namespace HeavenStudio.Games.Scripts_WizardsWaltz
StartCoroutine(FadeOut()); StartCoroutine(FadeOut());
passed = true; passed = true;
} }
if (hit) return;
float stateBeat = Conductor.instance.GetPositionFromMargin(createBeat + game.beatInterval, 1f);
StateCheck(stateBeat);
if (PlayerInput.Pressed(true))
{
if (state.perfect)
{
Ace();
} else if (state.notPerfect())
{
Miss();
}
}
} }
public void Bloom() public void Bloom()
@ -81,17 +68,28 @@ namespace HeavenStudio.Games.Scripts_WizardsWaltz
hit = true; hit = true;
} }
public void Miss() public void NearMiss()
{ {
game.wizard.Magic(this, false); game.wizard.Magic(this, false);
hit = true; hit = true;
} }
public override void OnAce() private void Just(PlayerActionEvent caller, float state)
{ {
if (state >= 1f || state <= -1f) {
NearMiss();
return;
}
Ace(); Ace();
} }
private void Miss(PlayerActionEvent caller)
{
// this is where perfect challenge breaks
}
private void Out(PlayerActionEvent caller) {}
public IEnumerator FadeOut() public IEnumerator FadeOut()
{ {
yield return new WaitForSeconds(Conductor.instance.secPerBeat * game.beatInterval / 2f); yield return new WaitForSeconds(Conductor.instance.secPerBeat * game.beatInterval / 2f);

View file

@ -51,7 +51,7 @@ PlayerSettings:
m_MTRendering: 1 m_MTRendering: 1
mipStripping: 0 mipStripping: 0
numberOfMipsStripped: 0 numberOfMipsStripped: 0
m_StackTraceTypes: 020000000200000002000000020000000200000001000000 m_StackTraceTypes: 010000000100000001000000010000000100000001000000
iosShowActivityIndicatorOnLoading: -1 iosShowActivityIndicatorOnLoading: -1
androidShowActivityIndicatorOnLoading: -1 androidShowActivityIndicatorOnLoading: -1
iosUseCustomAppBackgroundBehavior: 0 iosUseCustomAppBackgroundBehavior: 0