CNR API Internal Rework (#488)

* Prep stuff

* Tweezers now spawn in

* Started converting tweezers

* I hate <1 beat intervals

* Actually nvm

* fixed a bug

* You can chain intervals now, stack them if you really wanted

* Pass turn checks if crhandlerinstance exists

* Fixed hairs being deleted by onion switch

* Rockers rerewritten

* working dough rerewritten
This commit is contained in:
Rapandrasmus 2023-06-28 06:51:53 +02:00 committed by GitHub
parent dde1a3a287
commit 00c58d5487
10 changed files with 531 additions and 523 deletions

View file

@ -1334,7 +1334,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!4 &3942464277001988917 --- !u!4 &3942464277001988917
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View file

@ -10665,9 +10665,9 @@ MonoBehaviour:
doughDudesHolderAnim: {fileID: 9020148957407720643} doughDudesHolderAnim: {fileID: 9020148957407720643}
gandwAnim: {fileID: 2284918768942303106} gandwAnim: {fileID: 2284918768942303106}
bgObjects: bgObjects:
- {fileID: 8366664867673554297}
- {fileID: 2959293411470963612} - {fileID: 2959293411470963612}
- {fileID: 9159990749478636517} - {fileID: 9159990749478636517}
shipObject: {fileID: 8366664867673554297}
bigMode: 0 bigMode: 0
bigModePlayer: 0 bigModePlayer: 0
spaceshipRisen: 0 spaceshipRisen: 0

View file

@ -76,13 +76,6 @@ namespace HeavenStudio.Games
public double intervalStartBeat = -1; // the first beat of the interval public double intervalStartBeat = -1; // the first beat of the interval
public float intervalLength = -1; // the duration of the interval in beats public float intervalLength = -1; // the duration of the interval in beats
public float defaultIntervalLength; // when an event is queued and the interval has not started yet, it will use this as the interval length.
public CallAndResponseHandler(float defaultIntervalLength)
{
this.defaultIntervalLength = defaultIntervalLength;
}
public List<CallAndResponseEvent> queuedEvents = new List<CallAndResponseEvent>(); public List<CallAndResponseEvent> queuedEvents = new List<CallAndResponseEvent>();
/// <summary> /// <summary>
@ -95,7 +88,7 @@ namespace HeavenStudio.Games
public float GetIntervalProgressFromBeat(double beat, float lengthOffset = 0) public float GetIntervalProgressFromBeat(double beat, float lengthOffset = 0)
{ {
return (float)((beat - intervalStartBeat) / ((intervalStartBeat + intervalLength - lengthOffset) - intervalStartBeat)); return (float)((beat - intervalStartBeat) / Mathf.Max(1, intervalLength - lengthOffset));
} }
/// <summary> /// <summary>
@ -114,28 +107,20 @@ namespace HeavenStudio.Games
/// <param name="length">The length of the interval.</param> /// <param name="length">The length of the interval.</param>
public void StartInterval(double beat, float length) public void StartInterval(double beat, float length)
{ {
if (!IntervalIsActive()) if (queuedEvents.Count > 0) queuedEvents.Clear();
{
if (queuedEvents.Count > 0) queuedEvents.Clear();
}
intervalStartBeat = beat; intervalStartBeat = beat;
intervalLength = length; intervalLength = length;
defaultIntervalLength = length;
} }
/// <summary> /// <summary>
/// Adds an event to the queued events list. /// Adds an event to the queued events list.
/// </summary> /// </summary>
/// <param name="beat">The current beat.</param> /// <param name="beat">The current beat.</param>
/// <param name="length">The length of the event.</param>>
/// <param name="tag">The tag of the event.</param>
/// <param name="crParams">Extra properties to add to the event.</param> /// <param name="crParams">Extra properties to add to the event.</param>
/// <param name="ignoreInterval">If true, this function will not start a new interval if the interval isn't active.</param> public void AddEvent(double beat, float length = 0, string tag = "", List<CallAndResponseEventParam> crParams = null)
/// <param name="overrideInterval">If true, overrides the current interval.</param>
public void AddEvent(double beat, float length = 0, string tag = "", List<CallAndResponseEventParam> crParams = null, bool ignoreInterval = false, bool overrideInterval = false)
{ {
if ((!IntervalIsActive() && !ignoreInterval) || overrideInterval) CallAndResponseEvent addedEvent = new(beat, beat - intervalStartBeat, tag, length);
{
StartInterval(beat, defaultIntervalLength);
}
CallAndResponseEvent addedEvent = new CallAndResponseEvent(beat, beat - intervalStartBeat, tag, length);
if (crParams != null && crParams.Count > 0) if (crParams != null && crParams.Count > 0)
{ {
foreach (var param in crParams) foreach (var param in crParams)
@ -163,7 +148,7 @@ namespace HeavenStudio.Games
/// <summary> /// <summary>
/// Check if an event exists at relativeBeat. /// Check if an event exists at relativeBeat.
/// </summary> /// </summary>
/// <param name="beat">The beat to check.</param> /// <param name="relativeBeat">The relativeBeat to check.</param>
public bool EventExistsAtRelativetBeat(double relativeBeat) public bool EventExistsAtRelativetBeat(double relativeBeat)
{ {
if (queuedEvents.Count == 0) if (queuedEvents.Count == 0)

View file

@ -7,22 +7,17 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
{ {
public class Hair : MonoBehaviour public class Hair : MonoBehaviour
{ {
public double createBeat; [NonSerialized] public double createBeat;
public GameObject hairSprite; public GameObject hairSprite;
public GameObject stubbleSprite; public GameObject stubbleSprite;
public GameObject missedSprite; public GameObject missedSprite;
private RhythmTweezers game; private RhythmTweezers game;
private Tweezers tweezers; private Tweezers tweezers;
private bool plucked;
private void Awake() public void StartInput(double beat, double length, Tweezers tweezer)
{ {
game = RhythmTweezers.instance; game = RhythmTweezers.instance;
tweezers = game.Tweezers; tweezers = tweezer;
}
public void StartInput(double beat, double length)
{
game.ScheduleInput(beat, length, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, Just, Miss, Out); game.ScheduleInput(beat, length, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, Just, Miss, Out);
} }
@ -30,14 +25,12 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
{ {
tweezers.Pluck(true, this); tweezers.Pluck(true, this);
tweezers.hitOnFrame++; tweezers.hitOnFrame++;
plucked = true;
} }
public void NearMiss() public void NearMiss()
{ {
tweezers.Pluck(false, this); tweezers.Pluck(false, this);
tweezers.hitOnFrame++; tweezers.hitOnFrame++;
plucked = true;
} }
private void Just(PlayerActionEvent caller, float state) private void Just(PlayerActionEvent caller, float state)

View file

@ -26,15 +26,11 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
PlayerActionEvent endEvent; PlayerActionEvent endEvent;
private void Awake() public void StartInput(double beat, double length, Tweezers tweezer)
{ {
game = RhythmTweezers.instance; game = RhythmTweezers.instance;
anim = GetComponent<Animator>(); anim = GetComponent<Animator>();
tweezers = game.Tweezers; tweezers = tweezer;
}
public void StartInput(double beat, double length)
{
inputBeat = beat + length; inputBeat = beat + length;
game.ScheduleInput(beat, length, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, StartJust, StartMiss, Out); game.ScheduleInput(beat, length, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, StartJust, StartMiss, Out);
} }

View file

@ -17,22 +17,20 @@ namespace HeavenStudio.Games.Loaders
{ {
new GameAction("start interval", "Start Interval") new GameAction("start interval", "Start Interval")
{ {
function = delegate { RhythmTweezers.instance.SetIntervalStart(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); }, preFunction = delegate { RhythmTweezers.PreInterval(eventCaller.currentEntity.beat, eventCaller.currentEntity.length, eventCaller.currentEntity["auto"]); },
defaultLength = 4f, defaultLength = 4f,
resizable = true, resizable = true,
priority = 1, parameters = new List<Param>()
inactiveFunction = delegate { RhythmTweezers.InactiveInterval(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); } {
new Param("auto", true, "Auto Pass Turn", "Will the turn automatically be passed at the end of this event?")
}
}, },
new GameAction("short hair", "Short Hair") new GameAction("short hair", "Short Hair")
{ {
inactiveFunction = delegate { RhythmTweezers.SpawnHairInactive(eventCaller.currentEntity.beat); },
function = delegate { RhythmTweezers.instance.SpawnHair(eventCaller.currentEntity.beat); },
defaultLength = 0.5f defaultLength = 0.5f
}, },
new GameAction("long hair", "Curly Hair") new GameAction("long hair", "Curly Hair")
{ {
inactiveFunction = delegate { RhythmTweezers.SpawnLongHairInactive(eventCaller.currentEntity.beat); },
function = delegate { RhythmTweezers.instance.SpawnLongHair(eventCaller.currentEntity.beat); },
defaultLength = 0.5f defaultLength = 0.5f
}, },
new GameAction("passTurn", "Pass Turn") new GameAction("passTurn", "Pass Turn")
@ -131,6 +129,7 @@ namespace HeavenStudio.Games.Loaders
namespace HeavenStudio.Games namespace HeavenStudio.Games
{ {
using Jukebox;
using Scripts_RhythmTweezers; using Scripts_RhythmTweezers;
public class RhythmTweezers : Minigame public class RhythmTweezers : Minigame
@ -162,6 +161,7 @@ namespace HeavenStudio.Games
public Animator VegetableAnimator; public Animator VegetableAnimator;
public SpriteRenderer bg; public SpriteRenderer bg;
public Tweezers Tweezers; public Tweezers Tweezers;
private Tweezers currentTweezers;
public GameObject hairBase; public GameObject hairBase;
public GameObject longHairBase; public GameObject longHairBase;
public GameObject pluckedHairBase; public GameObject pluckedHairBase;
@ -169,7 +169,6 @@ namespace HeavenStudio.Games
public GameObject HairsHolder; public GameObject HairsHolder;
public GameObject DroppedHairsHolder; public GameObject DroppedHairsHolder;
[NonSerialized] public int hairsLeft = 0;
[Header("Variables")] [Header("Variables")]
private double passTurnBeat; private double passTurnBeat;
@ -182,8 +181,6 @@ namespace HeavenStudio.Games
public Sprite onionSprite; public Sprite onionSprite;
public Sprite potatoSprite; public Sprite potatoSprite;
[NonSerialized] public int eyeSize = 0;
Tween transitionTween; Tween transitionTween;
bool transitioning = false; bool transitioning = false;
Tween bgColorTween; Tween bgColorTween;
@ -225,15 +222,18 @@ namespace HeavenStudio.Games
private List<LongHair> spawnedLongs = new List<LongHair>(); private List<LongHair> spawnedLongs = new List<LongHair>();
private static List<double> passedTurns = new(); private static List<double> passedTurns = new();
private struct QueuedInterval
{
public double beat;
public float interval;
public bool autoPassTurn;
}
private static List<QueuedInterval> queuedIntervals = new List<QueuedInterval>();
private void Awake() private void Awake()
{ {
instance = this; instance = this;
if (crHandlerInstance == null) if (crHandlerInstance != null && crHandlerInstance.queuedEvents.Count > 0)
{
crHandlerInstance = new CallAndResponseHandler(4);
}
if (crHandlerInstance.queuedEvents.Count > 0)
{ {
foreach (var crEvent in crHandlerInstance.queuedEvents) foreach (var crEvent in crHandlerInstance.queuedEvents)
{ {
@ -261,9 +261,14 @@ namespace HeavenStudio.Games
} }
} }
public override void OnPlay(double beat)
{
crHandlerInstance = null;
}
private void OnDestroy() private void OnDestroy()
{ {
if (crHandlerInstance != null && !Conductor.instance.isPlaying) if (!Conductor.instance.isPlaying)
{ {
crHandlerInstance = null; crHandlerInstance = null;
} }
@ -273,24 +278,30 @@ namespace HeavenStudio.Games
} }
} }
public static void SpawnHairInactive(double beat) private void SpawnHairInactive(double beat)
{ {
if (crHandlerInstance == null)
{
crHandlerInstance = new CallAndResponseHandler(4);
}
if (crHandlerInstance.queuedEvents.Count > 0 && crHandlerInstance.queuedEvents.Find(x => x.beat == beat || (beat >= x.beat && beat <= x.beat + x.length)) != null) return; if (crHandlerInstance.queuedEvents.Count > 0 && crHandlerInstance.queuedEvents.Find(x => x.beat == beat || (beat >= x.beat && beat <= x.beat + x.length)) != null) return;
crHandlerInstance.AddEvent(beat, 0, "Hair"); crHandlerInstance.AddEvent(beat, 0, "Hair");
Hair hair = Instantiate(hairBase, HairsHolder.transform).GetComponent<Hair>();
spawnedHairs.Add(hair);
hair.gameObject.SetActive(true);
hair.GetComponent<Animator>().Play("SmallAppear", 0, 1);
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot);
hair.createBeat = beat;
} }
public static void SpawnLongHairInactive(double beat) private void SpawnLongHairInactive(double beat)
{ {
if (crHandlerInstance == null)
{
crHandlerInstance = new CallAndResponseHandler(4);
}
if (crHandlerInstance.queuedEvents.Count > 0 && crHandlerInstance.queuedEvents.Find(x => x.beat == beat || (beat >= x.beat && beat <= x.beat + x.length)) != null) return; if (crHandlerInstance.queuedEvents.Count > 0 && crHandlerInstance.queuedEvents.Find(x => x.beat == beat || (beat >= x.beat && beat <= x.beat + x.length)) != null) return;
crHandlerInstance.AddEvent(beat, 0.5f, "Long"); crHandlerInstance.AddEvent(beat, 0.5f, "Long");
LongHair hair = Instantiate(longHairBase, HairsHolder.transform).GetComponent<LongHair>();
spawnedLongs.Add(hair);
hair.gameObject.SetActive(true);
hair.GetComponent<Animator>().Play("LongAppear", 0, 1);
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot);
hair.createBeat = beat;
} }
public void SpawnHair(double beat) public void SpawnHair(double beat)
@ -302,10 +313,18 @@ namespace HeavenStudio.Games
crHandlerInstance.AddEvent(beat, 0, "Hair"); crHandlerInstance.AddEvent(beat, 0, "Hair");
SoundByte.PlayOneShotGame("rhythmTweezers/shortAppear", beat); SoundByte.PlayOneShotGame("rhythmTweezers/shortAppear", beat);
Hair hair = Instantiate(hairBase, HairsHolder.transform).GetComponent<Hair>(); Hair hair = Instantiate(hairBase, transform).GetComponent<Hair>();
spawnedHairs.Add(hair); spawnedHairs.Add(hair);
hair.gameObject.SetActive(true);
hair.GetComponent<Animator>().Play("SmallAppear", 0, 0); BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{
new BeatAction.Action(beat, delegate
{
hair.gameObject.SetActive(true);
hair.GetComponent<Animator>().Play("SmallAppear", 0, 0);
hair.transform.SetParent(HairsHolder.transform, false);
})
});
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1); float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot); hair.transform.eulerAngles = new Vector3(0, 0, rot);
@ -320,88 +339,136 @@ namespace HeavenStudio.Games
crHandlerInstance.AddEvent(beat, 0.5f, "Long"); crHandlerInstance.AddEvent(beat, 0.5f, "Long");
SoundByte.PlayOneShotGame("rhythmTweezers/longAppear", beat); SoundByte.PlayOneShotGame("rhythmTweezers/longAppear", beat);
LongHair hair = Instantiate(longHairBase, HairsHolder.transform).GetComponent<LongHair>(); LongHair hair = Instantiate(longHairBase, transform).GetComponent<LongHair>();
spawnedLongs.Add(hair); spawnedLongs.Add(hair);
hair.gameObject.SetActive(true); BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
hair.GetComponent<Animator>().Play("LongAppear", 0, 0); {
new BeatAction.Action(beat, delegate
{
hair.gameObject.SetActive(true);
hair.GetComponent<Animator>().Play("LongAppear", 0, 0);
hair.transform.SetParent(HairsHolder.transform, false);
})
});
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1); float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot); hair.transform.eulerAngles = new Vector3(0, 0, rot);
hair.createBeat = beat; hair.createBeat = beat;
} }
public void SetIntervalStart(double beat, float interval = 4f) private void SetIntervalStart(double beat, double gameSwitchBeat, float interval = 4f, bool autoPassTurn = true)
{ {
StopTransitionIfActive(); StopTransitionIfActive();
hairsLeft = 0; CallAndResponseHandler newHandler = new();
eyeSize = 0; crHandlerInstance = newHandler;
crHandlerInstance.StartInterval(beat, interval); crHandlerInstance.StartInterval(beat, interval);
} List<RiqEntity> relevantHairEvents = GetAllHairsInBetweenBeat(beat, beat + interval);
foreach (var hairEvent in relevantHairEvents)
public static void InactiveInterval(double beat, float interval)
{
if (crHandlerInstance == null)
{ {
crHandlerInstance = new CallAndResponseHandler(4); if (hairEvent.beat >= gameSwitchBeat)
}
crHandlerInstance.StartInterval(beat, interval);
}
public void PassTurn(double beat)
{
if (crHandlerInstance.queuedEvents.Count > 0)
{
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{ {
new BeatAction.Action(beat - 1, delegate if (hairEvent.datamodel == "rhythmTweezers/short hair")
{ {
hairsLeft = crHandlerInstance.queuedEvents.Count; SpawnHair(hairEvent.beat);
foreach (var crEvent in crHandlerInstance.queuedEvents) }
else
{
SpawnLongHair(hairEvent.beat);
}
}
else
{
if (hairEvent.datamodel == "rhythmTweezers/short hair")
{
SpawnHairInactive(hairEvent.beat);
}
else
{
SpawnLongHairInactive(hairEvent.beat);
}
}
}
if (autoPassTurn)
{
PassTurn(beat + interval, interval, newHandler);
}
}
public static void PreInterval(double beat, float interval = 4f, bool autoPassTurn = true)
{
if (GameManager.instance.currentGame == "rhythmTweezers")
{
instance.SetIntervalStart(beat, beat, interval, autoPassTurn);
}
else
{
queuedIntervals.Add(new QueuedInterval()
{
beat = beat,
interval = interval,
autoPassTurn = autoPassTurn
});
}
}
private static List<RiqEntity> GetAllHairsInBetweenBeat(double beat, double endBeat)
{
List<RiqEntity> hairEvents = EventCaller.GetAllInGameManagerList("rhythmTweezers", new string[] { "short hair", "long hair"});
List<RiqEntity> tempEvents = new();
foreach (var entity in hairEvents)
{
if (entity.beat >= beat && entity.beat < endBeat)
{
tempEvents.Add(entity);
}
}
return tempEvents;
}
private void PassTurnStandalone(double beat)
{
if (crHandlerInstance != null) PassTurn(beat, crHandlerInstance.intervalLength, crHandlerInstance);
}
private void PassTurn(double beat, double length, CallAndResponseHandler crHandler)
{
Tweezers spawnedTweezers = Instantiate(Tweezers, transform);
spawnedTweezers.gameObject.SetActive(true);
spawnedTweezers.Init(beat, beat + length);
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{
new BeatAction.Action(beat - 0.25, delegate
{
if (crHandler.queuedEvents.Count > 0)
{
currentTweezers = spawnedTweezers;
spawnedTweezers.hairsLeft = crHandler.queuedEvents.Count;
foreach (var crEvent in crHandler.queuedEvents)
{ {
if (crEvent.tag == "Hair") if (crEvent.tag == "Hair")
{ {
Hair hairToInput = spawnedHairs.Find(x => x.createBeat == crEvent.beat); Hair hairToInput = spawnedHairs.Find(x => x.createBeat == crEvent.beat);
hairToInput.StartInput(beat, crEvent.relativeBeat); hairToInput.StartInput(beat, crEvent.relativeBeat, spawnedTweezers);
} }
else if (crEvent.tag == "Long") else if (crEvent.tag == "Long")
{ {
LongHair hairToInput = spawnedLongs.Find(x => x.createBeat == crEvent.beat); LongHair hairToInput = spawnedLongs.Find(x => x.createBeat == crEvent.beat);
hairToInput.StartInput(beat, crEvent.relativeBeat); hairToInput.StartInput(beat, crEvent.relativeBeat, spawnedTweezers);
} }
} }
crHandlerInstance.queuedEvents.Clear(); crHandler.queuedEvents.Clear();
}), }
new BeatAction.Action(beat, delegate
{ }),
if (crHandlerInstance.queuedEvents.Count > 0) });
{
hairsLeft += crHandlerInstance.queuedEvents.Count;
foreach (var crEvent in crHandlerInstance.queuedEvents)
{
if (crEvent.tag == "Hair")
{
Hair hairToInput = spawnedHairs.Find(x => x.createBeat == crEvent.beat);
hairToInput.StartInput(beat, crEvent.relativeBeat);
}
else if (crEvent.tag == "Long")
{
LongHair hairToInput = spawnedLongs.Find(x => x.createBeat == crEvent.beat);
hairToInput.StartInput(beat, crEvent.relativeBeat);
}
}
crHandlerInstance.queuedEvents.Clear();
}
})
});
}
} }
public static void PrePassTurn(double beat) public static void PrePassTurn(double beat)
{ {
if (GameManager.instance.currentGame == "rhythmTweezers") if (GameManager.instance.currentGame == "rhythmTweezers")
{ {
instance.SetPassTurnValues(beat); instance.PassTurnStandalone(beat);
instance.PassTurn(beat);
} }
else else
{ {
@ -409,13 +476,6 @@ namespace HeavenStudio.Games
} }
} }
private void SetPassTurnValues(double startBeat)
{
if (crHandlerInstance.intervalLength <= 0) return;
passTurnBeat = startBeat - 1;
passTurnEndBeat = startBeat + crHandlerInstance.intervalLength;
}
const float vegDupeOffset = 16.7f; const float vegDupeOffset = 16.7f;
public void NextVegetable(double beat, int type, Color onionColor, Color potatoColor) public void NextVegetable(double beat, int type, Color onionColor, Color potatoColor)
{ {
@ -514,8 +574,7 @@ namespace HeavenStudio.Games
{ {
foreach (var turn in passedTurns) foreach (var turn in passedTurns)
{ {
SetPassTurnValues(turn); PassTurnStandalone(turn);
PassTurn(turn);
} }
passedTurns.Clear(); passedTurns.Clear();
} }
@ -530,28 +589,25 @@ namespace HeavenStudio.Games
} }
} }
private void LateUpdate() public override void OnGameSwitch(double beat)
{ {
// Set tweezer angle. if (Conductor.instance.isPlaying && !Conductor.instance.isPaused)
var tweezerAngle = -180f; {
if (queuedIntervals.Count > 0)
var tweezerTime = Conductor.instance.songPositionInBeats; {
var unclampedAngle = -58f + 116 * Mathp.Normalize(tweezerTime, (float)passTurnBeat + 1f, (float)passTurnEndBeat - 1f); foreach (var interval in queuedIntervals)
tweezerAngle = Mathf.Clamp(unclampedAngle, -180f, 180f); {
SetIntervalStart(interval.beat, beat, interval.interval, interval.autoPassTurn);
Tweezers.transform.eulerAngles = new Vector3(0, 0, tweezerAngle); }
queuedIntervals.Clear();
// Set tweezer to follow vegetable. }
var currentTweezerPos = Tweezers.transform.localPosition; }
var vegetablePos = Vegetable.transform.localPosition;
var vegetableHolderPos = VegetableHolder.transform.localPosition;
Tweezers.transform.localPosition = new Vector3(vegetableHolderPos.x, vegetablePos.y + 1f, currentTweezerPos.z);
} }
private void ResetVegetable() private void ResetVegetable()
{ {
// If the tweezers happen to be holding a hair, drop it immediately so it can be destroyed below. // If the tweezers happen to be holding a hair, drop it immediately so it can be destroyed below.
Tweezers.DropHeldHair(); currentTweezers?.DropHeldHair();
foreach (Transform t in HairsHolder.transform) foreach (Transform t in HairsHolder.transform)
{ {
@ -564,8 +620,6 @@ namespace HeavenStudio.Games
} }
VegetableAnimator.Play("Idle", 0, 0); VegetableAnimator.Play("Idle", 0, 0);
eyeSize = 0;
} }
private void StopTransitionIfActive() private void StopTransitionIfActive()

View file

@ -4,6 +4,7 @@ using UnityEngine;
using System; using System;
using HeavenStudio.Util; using HeavenStudio.Util;
using Starpelly;
namespace HeavenStudio.Games.Scripts_RhythmTweezers namespace HeavenStudio.Games.Scripts_RhythmTweezers
{ {
@ -17,6 +18,10 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
private bool holdingHair; private bool holdingHair;
public SpriteRenderer heldHairSprite; public SpriteRenderer heldHairSprite;
public Transform tweezerSpriteTrans; public Transform tweezerSpriteTrans;
private double passTurnBeat = -1;
private double passTurnEndBeat = -1;
[NonSerialized] public int hairsLeft;
private int eyeSize = 0;
private void Awake() private void Awake()
{ {
@ -26,6 +31,37 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
game = RhythmTweezers.instance; game = RhythmTweezers.instance;
} }
public void Init(double beat, double endBeat)
{
passTurnBeat = beat;
passTurnEndBeat = endBeat;
Update();
}
private void Update()
{
if (passTurnBeat != -1)
{
// Set tweezer angle.
float tweezerTime = Conductor.instance.GetPositionFromBeat(passTurnBeat, Math.Max(passTurnEndBeat - 1f - passTurnBeat, 1));
var unclampedAngle = -58f + (116 * tweezerTime);
var tweezerAngle = Mathf.Clamp(unclampedAngle, -180f, 180f);
transform.eulerAngles = new Vector3(0, 0, tweezerAngle);
// Set tweezer to follow vegetable.
var currentTweezerPos = transform.localPosition;
var vegetablePos = game.Vegetable.transform.localPosition;
var vegetableHolderPos = game.VegetableHolder.transform.localPosition;
transform.localPosition = new Vector3(vegetableHolderPos.x, vegetablePos.y + 1f, currentTweezerPos.z);
if (tweezerAngle == 180)
{
Destroy(gameObject);
}
}
}
private void LateUpdate() private void LateUpdate()
{ {
if (PlayerInput.Pressed(true)) if (PlayerInput.Pressed(true))
@ -51,13 +87,13 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
hair.hairSprite.SetActive(false); hair.hairSprite.SetActive(false);
hair.stubbleSprite.SetActive(true); hair.stubbleSprite.SetActive(true);
game.hairsLeft--; hairsLeft--;
game.eyeSize = Mathf.Clamp(game.eyeSize + 1, 0, 10); eyeSize = Mathf.Clamp(eyeSize + 1, 0, 10);
if (game.hairsLeft <= 0) if (hairsLeft <= 0)
vegetableAnim.Play("HopFinal", 0, 0); vegetableAnim.Play("HopFinal", 0, 0);
else else
vegetableAnim.Play("Hop" + game.eyeSize.ToString(), 0, 0); vegetableAnim.Play("Hop" + eyeSize.ToString(), 0, 0);
anim.Play("Tweezers_Pluck_Success", 0, 0); anim.Play("Tweezers_Pluck_Success", 0, 0);
} }
@ -91,13 +127,13 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
// Making transparent instead of disabling because animators are silly. // Making transparent instead of disabling because animators are silly.
hair.loop.GetComponent<SpriteRenderer>().color = Color.clear; hair.loop.GetComponent<SpriteRenderer>().color = Color.clear;
game.hairsLeft--; hairsLeft--;
game.eyeSize = Mathf.Clamp(game.eyeSize + 1, 0, 10); eyeSize = Mathf.Clamp(eyeSize + 1, 0, 10);
if (game.hairsLeft <= 0) if (hairsLeft <= 0)
vegetableAnim.Play("HopFinal", 0, 0); vegetableAnim.Play("HopFinal", 0, 0);
else else
vegetableAnim.Play("Hop" + game.eyeSize.ToString(), 0, 0); vegetableAnim.Play("Hop" + eyeSize.ToString(), 0, 0);
anim.Play("Tweezers_Pluck_Success", 0, 0); anim.Play("Tweezers_Pluck_Success", 0, 0);
} }

View file

@ -17,35 +17,18 @@ namespace HeavenStudio.Games.Loaders
{ {
new GameAction("intervalStart", "Start Interval") new GameAction("intervalStart", "Start Interval")
{ {
function = delegate { var e = eventCaller.currentEntity; Rockers.instance.StartInterval(e.beat, e.length); },
defaultLength = 8f, defaultLength = 8f,
resizable = true, resizable = true,
preFunction = delegate { Rockers.PreMoveCamera(eventCaller.currentEntity.beat, eventCaller.currentEntity["moveCamera"]); }, preFunction = delegate { var e = eventCaller.currentEntity; Rockers.PreInterval(e.beat, e.length, e["auto"], e["moveCamera"], e["movePass"]); },
parameters = new List<Param>() parameters = new List<Param>()
{ {
new Param("moveCamera", true, "Move Camera", "Should the camera move?") new Param("moveCamera", true, "Move Camera", "Should the camera move?"),
new Param("movePass", true, "Move Camera (Pass Turn)", "Should the camera move at the auto pass turn?"),
new Param("auto", true, "Auto Pass Turn")
}, },
inactiveFunction = delegate { var e = eventCaller.currentEntity; Rockers.InactiveInterval(e.beat, e.length); }
}, },
new GameAction("riff", "Riff") new GameAction("riff", "Riff")
{ {
function = delegate { var e = eventCaller.currentEntity; Rockers.instance.Riff(e.beat, e.length, new int[6]
{
e["1JJ"],
e["2JJ"],
e["3JJ"],
e["4JJ"],
e["5JJ"],
e["6JJ"],
}, e["gcJJ"], new int[6]
{
e["1S"],
e["2S"],
e["3S"],
e["4S"],
e["5S"],
e["6S"],
}, e["gcS"], e["sampleJJ"], e["pitchSampleJJ"], e["sampleS"], e["pitchSampleS"], !e["respond"]); },
defaultLength = 1f, defaultLength = 1f,
resizable = true, resizable = true,
parameters = new List<Param>() parameters = new List<Param>()
@ -70,19 +53,9 @@ namespace HeavenStudio.Games.Loaders
new Param("pitchSampleS", new EntityTypes.Integer(-24, 24, 0), "Sample Semtiones (Soshi)", "Pitch up the sample by X amount of semitones?"), new Param("pitchSampleS", new EntityTypes.Integer(-24, 24, 0), "Sample Semtiones (Soshi)", "Pitch up the sample by X amount of semitones?"),
new Param("gcS", false, "Glee Club Guitar (Soshi)", "Will Soshi use the same guitar as in the glee club lessons?") new Param("gcS", false, "Glee Club Guitar (Soshi)", "Will Soshi use the same guitar as in the glee club lessons?")
}, },
inactiveFunction = delegate { var e = eventCaller.currentEntity; Rockers.InactiveRiff(e.beat, e.length, new int[6]
{
e["1S"],
e["2S"],
e["3S"],
e["4S"],
e["5S"],
e["6S"],
}, e["gcS"], e["sampleS"], e["pitchSampleS"]); }
}, },
new GameAction("bend", "Bend") new GameAction("bend", "Bend")
{ {
function = delegate { var e = eventCaller.currentEntity; Rockers.instance.Bend(e.beat, e.length, e["1JJ"], e["1S"], !e["respond"]); },
defaultLength = 1f, defaultLength = 1f,
resizable = true, resizable = true,
parameters = new List<Param>() parameters = new List<Param>()
@ -91,7 +64,6 @@ namespace HeavenStudio.Games.Loaders
new Param("1JJ", new EntityTypes.Integer(-24, 24, 1), "Pitch Bend (JJ)", "How many semitones up is the current riff gonna be pitchbended?"), new Param("1JJ", new EntityTypes.Integer(-24, 24, 1), "Pitch Bend (JJ)", "How many semitones up is the current riff gonna be pitchbended?"),
new Param("1S", new EntityTypes.Integer(-24, 24, 1), "Pitch Bend (Soshi)", "How many semitones up is the current riff gonna be pitchbended?"), new Param("1S", new EntityTypes.Integer(-24, 24, 1), "Pitch Bend (Soshi)", "How many semitones up is the current riff gonna be pitchbended?"),
}, },
inactiveFunction = delegate { var e = eventCaller.currentEntity; Rockers.InactiveBend(e.beat, e.length, e["1S"]); }
}, },
new GameAction("prepare", "Prepare") new GameAction("prepare", "Prepare")
{ {
@ -320,9 +292,6 @@ namespace HeavenStudio.Games.Loaders
namespace HeavenStudio.Games namespace HeavenStudio.Games
{ {
using Scripts_Rockers; using Scripts_Rockers;
using Starpelly;
using System;
using UnityEngine.UIElements;
public class Rockers : Minigame public class Rockers : Minigame
{ {
@ -402,24 +371,30 @@ namespace HeavenStudio.Games
private double cameraMoveBeat = -1; private double cameraMoveBeat = -1;
private double endBeat = double.MaxValue; private double endBeat = double.MaxValue;
private static List<double> queuedCameraEvents = new(); private static List<double> queuedCameraEvents = new();
private static List<double> queuedPreInterval = new();
private List<RiqEntity> riffEvents = new List<RiqEntity>(); private List<RiqEntity> riffEvents = new List<RiqEntity>();
private static List<double> riffUsedBeats = new();
private List<RiqEntity> bendEvents = new List<RiqEntity>(); private List<RiqEntity> bendEvents = new List<RiqEntity>();
private static List<double> bendUsedBeats = new();
private List<double> prepareBeatsJJ = new(); private List<double> prepareBeatsJJ = new();
private struct QueuedInterval
{
public double beat;
public float length;
public bool moveCamera;
public bool moveCameraPass;
public bool autoPassTurn;
}
private static List<QueuedInterval> queuedIntervals = new();
private void Awake() private void Awake()
{ {
instance = this; instance = this;
if (crHandlerInstance == null) if (crHandlerInstance == null)
{ {
crHandlerInstance = new CallAndResponseHandler(8); crHandlerInstance = new CallAndResponseHandler();
} }
var tempEvents = EventCaller.GetAllInGameManagerList("rockers", new string[] { "prepare" }); var tempEvents = EventCaller.GetAllInGameManagerList("rockers", new string[] { "prepare" });
foreach (var tempEvent in tempEvents) foreach (var tempEvent in tempEvents)
@ -480,6 +455,21 @@ namespace HeavenStudio.Games
} }
} }
private static List<RiqEntity> GrabAllInputsBetween(double beat, double endBeat)
{
List<RiqEntity> hairEvents = EventCaller.GetAllInGameManagerList("rockers", new string[] { "riff", "bend" });
List<RiqEntity> tempEvents = new();
foreach (var entity in hairEvents)
{
if (entity.beat >= beat && entity.beat < endBeat)
{
tempEvents.Add(entity);
}
}
return tempEvents;
}
private List<RiqEntity> GrabAllTogetherEvents(double beat) private List<RiqEntity> GrabAllTogetherEvents(double beat)
{ {
var tempEvents = EventCaller.GetAllInGameManagerList("rockers", new string[] { "riffTogether", "riffTogetherEnd" }); var tempEvents = EventCaller.GetAllInGameManagerList("rockers", new string[] { "riffTogether", "riffTogetherEnd" });
@ -546,22 +536,32 @@ namespace HeavenStudio.Games
} }
} }
public override void OnPlay(double beat)
{
crHandlerInstance = null;
}
private void OnDestroy() private void OnDestroy()
{ {
if (!Conductor.instance.isPlaying)
{
crHandlerInstance = null;
if (riffUsedBeats.Count > 0) riffUsedBeats.Clear();
if (bendUsedBeats.Count > 0) bendUsedBeats.Clear();
}
if (queuedCameraEvents.Count > 0) queuedCameraEvents.Clear(); if (queuedCameraEvents.Count > 0) queuedCameraEvents.Clear();
if (queuedPreInterval.Count > 0) queuedPreInterval.Clear();
foreach (var evt in scheduledInputs) foreach (var evt in scheduledInputs)
{ {
evt.Disable(); evt.Disable();
} }
} }
public override void OnGameSwitch(double beat)
{
if (queuedIntervals.Count > 0)
{
foreach (var interval in queuedIntervals)
{
StartInterval(interval.beat, interval.length, beat, interval.autoPassTurn, interval.moveCameraPass);
}
queuedIntervals.Clear();
}
}
private void Update() private void Update()
{ {
var cond = Conductor.instance; var cond = Conductor.instance;
@ -593,20 +593,12 @@ namespace HeavenStudio.Games
} }
queuedCameraEvents.Clear(); queuedCameraEvents.Clear();
} }
if (queuedPreInterval.Count > 0)
{
foreach (var interval in queuedPreInterval)
{
PreInterval(interval);
}
queuedPreInterval.Clear();
}
if (passedTurns.Count > 0) if (passedTurns.Count > 0)
{ {
foreach (var turn in passedTurns) foreach (var turn in passedTurns)
{ {
PassTurn(turn.beat, turn.moveCamera); StandalonePassTurn(turn.beat, turn.moveCamera);
} }
passedTurns.Clear(); passedTurns.Clear();
} }
@ -621,12 +613,6 @@ namespace HeavenStudio.Games
GameCamera.additionalPosition = new Vector3(newX, 0, 0); GameCamera.additionalPosition = new Vector3(newX, 0, 0);
} }
} }
if (!Conductor.instance.isPlaying)
{
crHandlerInstance = null;
if (riffUsedBeats.Count > 0) riffUsedBeats.Clear();
if (bendUsedBeats.Count > 0) bendUsedBeats.Clear();
}
} }
public void DefaultLastOne(double beat, int[] JJSamples, int[] JJPitches, int[] SoshiSamples, int[] SoshiPitches, bool moveCamera) public void DefaultLastOne(double beat, int[] JJSamples, int[] JJPitches, int[] SoshiSamples, int[] SoshiPitches, bool moveCamera)
@ -827,15 +813,22 @@ namespace HeavenStudio.Games
BeatAction.New(instance.gameObject, actions); BeatAction.New(instance.gameObject, actions);
} }
public static void PreMoveCamera(double beat, bool moveCamera) public static void PreInterval(double beat, float length, bool autoPassTurn, bool moveCamera, bool movePass)
{ {
if (GameManager.instance.currentGame == "rockers") if (GameManager.instance.currentGame == "rockers")
{ {
if (moveCamera) instance.MoveCamera(beat - 1); if (moveCamera) instance.MoveCamera(beat - 1);
instance.PreInterval(beat - 1); instance.StartInterval(beat, length, beat, autoPassTurn, movePass);
} }
if (moveCamera) queuedCameraEvents.Add(beat - 1); if (moveCamera) queuedCameraEvents.Add(beat - 1);
queuedPreInterval.Add(beat - 1); queuedIntervals.Add(new QueuedInterval()
{
beat = beat,
length = length,
autoPassTurn = autoPassTurn,
moveCamera = moveCamera,
moveCameraPass = movePass
});
} }
private void MoveCamera(double beat) private void MoveCamera(double beat)
@ -846,91 +839,104 @@ namespace HeavenStudio.Games
} }
private void PreInterval(double beat) public void StartInterval(double beat, float length, double gameSwitchBeat, bool autoPassTurn, bool moveCamera)
{ {
CallAndResponseHandler newHandler = new();
crHandlerInstance = newHandler;
crHandlerInstance.StartInterval(beat, length);
List<RiqEntity> relevantInputs = GrabAllInputsBetween(beat, beat + length);
List<double> riffUsedBeats = new List<double>();
List<double> bendUsedBeats = new();
foreach (var input in relevantInputs)
{
if (input.datamodel == "rockers/riff")
{
RiqEntity foundEvent = riffEvents.Find(x => x.beat == input.beat);
if ((foundEvent == null || (riffUsedBeats.Count > 0 && riffUsedBeats.Contains((float)foundEvent.beat))) && riffEvents.Count > 1) continue;
riffUsedBeats.Add(input.beat);
if (input["respond"])
{
crHandlerInstance.AddEvent(input.beat, input.length, "riff", new List<CallAndResponseHandler.CallAndResponseEventParam>()
{
new CallAndResponseHandler.CallAndResponseEventParam("gleeClub", input["gcS"]),
new CallAndResponseHandler.CallAndResponseEventParam("1", input["1S"]),
new CallAndResponseHandler.CallAndResponseEventParam("2", input["2S"]),
new CallAndResponseHandler.CallAndResponseEventParam("3", input["3S"]),
new CallAndResponseHandler.CallAndResponseEventParam("4", input["4S"]),
new CallAndResponseHandler.CallAndResponseEventParam("5", input["5S"]),
new CallAndResponseHandler.CallAndResponseEventParam("6", input["6S"]),
new CallAndResponseHandler.CallAndResponseEventParam("sample", input["sampleS"]),
new CallAndResponseHandler.CallAndResponseEventParam("sampleTones", input["pitchSampleS"])
});
}
if (input.beat >= gameSwitchBeat)
{
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{
new BeatAction.Action(input.beat, delegate { Riff(input.beat, input.length, new int[]
{
input["1JJ"],
input["2JJ"],
input["3JJ"],
input["4JJ"],
input["5JJ"],
input["6JJ"],
}, input["gcJJ"], input["sampleJJ"], input["pitchSampleJJ"], !input["respond"]);
})
});
}
}
else
{
if (riffEvents.Count == 0) continue;
RiqEntity foundEvent = bendEvents.Find(x => x.beat == beat);
if ((foundEvent == null || (bendUsedBeats.Count > 0 && bendUsedBeats.Contains((float)foundEvent.beat))) && bendEvents.Count > 1) continue;
RiqEntity riffEventToCheck = riffEvents.Find(x => beat >= x.beat && beat < x.beat + x.length);
if (riffEventToCheck == null) continue;
bendUsedBeats.Add(beat);
if (input["respond"])
{
crHandlerInstance.AddEvent(input.beat, input.length, "bend", new List<CallAndResponseHandler.CallAndResponseEventParam>()
{
new CallAndResponseHandler.CallAndResponseEventParam("Pitch", input["1S"]),
});
}
if (input.beat >= gameSwitchBeat)
{
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{
new BeatAction.Action(input.beat, delegate
{
Bend(input.beat, input.length, input["1JJ"]);
})
});
}
}
}
BeatAction.New(instance.gameObject, new List<BeatAction.Action>() BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{ {
new BeatAction.Action(beat, delegate new BeatAction.Action(beat, delegate
{ {
if (GameManager.instance.autoplay) Soshi.UnHold();
if (JJ.together || Soshi.together) if (JJ.together || Soshi.together)
{ {
JJ.ReturnBack(); JJ.ReturnBack();
if (prepareBeatsJJ.Count > 0 && prepareBeatsJJ.Contains(beat)) JJ.Mute(false); if (prepareBeatsJJ.Count > 0 && prepareBeatsJJ.Contains(beat)) JJ.Mute(false);
Soshi.ReturnBack(); Soshi.ReturnBack();
} }
}) }),
}); });
if (autoPassTurn) PassTurn(beat + length, moveCamera, newHandler);
} }
public static void InactiveInterval(double beat, float length) public void Riff(double beat, float length, int[] pitches, bool gleeClubJJ, int sampleJJ, int sampleTonesJJ, bool noRespond)
{ {
if (crHandlerInstance == null)
{
crHandlerInstance = new CallAndResponseHandler(8);
}
crHandlerInstance.StartInterval(beat, length);
}
public void StartInterval(double beat, float length)
{
crHandlerInstance.StartInterval(beat, length);
if (GameManager.instance.autoplay) Soshi.UnHold();
}
public static void InactiveRiff(double beat, float length, int[] pitchesPlayer, bool gleeClubPlayer, int sampleSoshi, int sampleTonesSoshi)
{
if (crHandlerInstance == null)
{
crHandlerInstance = new CallAndResponseHandler(8);
}
List<RiqEntity> foundRiffEvents = GrabAllRiffEvents();
RiqEntity foundEvent = foundRiffEvents.Find(x => x.beat == beat);
if ((foundEvent == null || (riffUsedBeats.Count > 0 && riffUsedBeats.Contains(foundEvent.beat))) && foundRiffEvents.Count > 1) return;
riffUsedBeats.Add(beat);
crHandlerInstance.AddEvent(beat, length, "riff", new List<CallAndResponseHandler.CallAndResponseEventParam>()
{
new CallAndResponseHandler.CallAndResponseEventParam("gleeClub", gleeClubPlayer),
new CallAndResponseHandler.CallAndResponseEventParam("1", pitchesPlayer[0]),
new CallAndResponseHandler.CallAndResponseEventParam("2", pitchesPlayer[1]),
new CallAndResponseHandler.CallAndResponseEventParam("3", pitchesPlayer[2]),
new CallAndResponseHandler.CallAndResponseEventParam("4", pitchesPlayer[3]),
new CallAndResponseHandler.CallAndResponseEventParam("5", pitchesPlayer[4]),
new CallAndResponseHandler.CallAndResponseEventParam("6", pitchesPlayer[5]),
new CallAndResponseHandler.CallAndResponseEventParam("sample", sampleSoshi),
new CallAndResponseHandler.CallAndResponseEventParam("sampleTones", sampleTonesSoshi)
});
}
public static void InactiveBend(double beat, float length, int pitchSoshi)
{
if (crHandlerInstance == null)
{
crHandlerInstance = new CallAndResponseHandler(8);
}
var bendEventsToCheck = GrabAllBendEvents();
var riffEventsToCheck = GrabAllRiffEvents();
if (riffEventsToCheck.Count == 0) return;
RiqEntity foundEvent = bendEventsToCheck.Find(x => x.beat == beat);
if ((foundEvent == null || (bendUsedBeats.Count > 0 && bendUsedBeats.Contains((float)foundEvent.beat))) && bendEventsToCheck.Count > 1) return;
RiqEntity riffEventToCheck = riffEventsToCheck.Find(x => beat >= x.beat && beat < x.beat + x.length);
if (riffEventToCheck == null) return;
bendUsedBeats.Add(beat);
crHandlerInstance.AddEvent(beat, length, "bend", new List<CallAndResponseHandler.CallAndResponseEventParam>()
{
new CallAndResponseHandler.CallAndResponseEventParam("Pitch", pitchSoshi),
});
}
public void Riff(double beat, float length, int[] pitches, bool gleeClubJJ, int[] pitchesPlayer, bool gleeClubPlayer, int sampleJJ, int sampleTonesJJ, int sampleSoshi, int sampleTonesSoshi, bool noRespond)
{
RiqEntity foundEvent = riffEvents.Find(x => x.beat == beat);
if ((foundEvent == null || (riffUsedBeats.Count > 0 && riffUsedBeats.Contains((float)foundEvent.beat))) && riffEvents.Count > 1) return;
riffUsedBeats.Add(beat);
JJ.StrumStrings(gleeClubJJ, pitches, (PremadeSamples)sampleJJ, sampleTonesJJ, noRespond); JJ.StrumStrings(gleeClubJJ, pitches, (PremadeSamples)sampleJJ, sampleTonesJJ, noRespond);
BeatAction.New(instance.gameObject, new List<BeatAction.Action>() BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{ {
new BeatAction.Action(beat + length, delegate { JJ.Mute(); }) new BeatAction.Action(beat + length, delegate { JJ.Mute(); })
}); });
/*
if (noRespond) return; if (noRespond) return;
crHandlerInstance.AddEvent(beat, length, "riff", new List<CallAndResponseHandler.CallAndResponseEventParam>() crHandlerInstance.AddEvent(beat, length, "riff", new List<CallAndResponseHandler.CallAndResponseEventParam>()
{ {
@ -944,26 +950,16 @@ namespace HeavenStudio.Games
new CallAndResponseHandler.CallAndResponseEventParam("sample", sampleSoshi), new CallAndResponseHandler.CallAndResponseEventParam("sample", sampleSoshi),
new CallAndResponseHandler.CallAndResponseEventParam("sampleTones", sampleTonesSoshi) new CallAndResponseHandler.CallAndResponseEventParam("sampleTones", sampleTonesSoshi)
}); });
*/
} }
public void Bend(double beat, float length, int pitchJJ, int pitchSoshi, bool noRespond) public void Bend(double beat, float length, int pitchJJ)
{ {
if (riffEvents.Count == 0) return;
RiqEntity foundEvent = bendEvents.Find(x => x.beat == beat);
if ((foundEvent == null || (bendUsedBeats.Count > 0 && bendUsedBeats.Contains((float)foundEvent.beat))) && bendEvents.Count > 1) return;
RiqEntity riffEventToCheck = riffEvents.Find(x => beat >= x.beat && beat < x.beat + x.length);
if (riffEventToCheck == null) return;
bendUsedBeats.Add(beat);
JJ.BendUp(pitchJJ); JJ.BendUp(pitchJJ);
BeatAction.New(instance.gameObject, new List<BeatAction.Action>() BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{ {
new BeatAction.Action(beat + length, delegate { JJ.BendDown(); }) new BeatAction.Action(beat + length, delegate { JJ.BendDown(); })
}); });
if (noRespond) return;
crHandlerInstance.AddEvent(beat, length, "bend", new List<CallAndResponseHandler.CallAndResponseEventParam>()
{
new CallAndResponseHandler.CallAndResponseEventParam("Pitch", pitchSoshi),
});
} }
public void Mute(int whoMutes) public void Mute(int whoMutes)
@ -994,7 +990,7 @@ namespace HeavenStudio.Games
{ {
if (GameManager.instance.currentGame == "rockers") if (GameManager.instance.currentGame == "rockers")
{ {
instance.PassTurn(beat, moveCamera); instance.StandalonePassTurn(beat, moveCamera);
} }
else else
{ {
@ -1006,15 +1002,29 @@ namespace HeavenStudio.Games
} }
} }
private void PassTurn(double beat, bool moveCamera) private void StandalonePassTurn(double beat, bool moveCamera)
{
if (crHandlerInstance != null) PassTurn(beat, moveCamera, crHandlerInstance);
}
private void PassTurn(double beat, bool moveCamera, CallAndResponseHandler handler)
{ {
if (crHandlerInstance.queuedEvents.Count > 0) if (crHandlerInstance.queuedEvents.Count > 0)
{ {
BeatAction.New(instance.gameObject, new List<BeatAction.Action>() BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{ {
new BeatAction.Action(beat -1, delegate new BeatAction.Action(beat - 1, delegate
{ {
List<CallAndResponseHandler.CallAndResponseEvent> crEvents = crHandlerInstance.queuedEvents; if (moveCamera)
{
lastTargetCameraX = GameCamera.additionalPosition.x;
targetCameraX = Soshi.transform.localPosition.x;
cameraMoveBeat = beat - 1;
}
}),
new BeatAction.Action(beat -0.25, delegate
{
List<CallAndResponseHandler.CallAndResponseEvent> crEvents = handler.queuedEvents;
foreach (var crEvent in crEvents) foreach (var crEvent in crEvents)
{ {
@ -1032,41 +1042,13 @@ namespace HeavenStudio.Games
ScheduleInput(beat, crEvent.relativeBeat + crEvent.length, InputType.DIRECTION_UP, JustUnBend, UnBendMiss, Empty); ScheduleInput(beat, crEvent.relativeBeat + crEvent.length, InputType.DIRECTION_UP, JustUnBend, UnBendMiss, Empty);
} }
} }
crHandlerInstance.queuedEvents.Clear(); handler.queuedEvents.Clear();
}), }),
new BeatAction.Action(beat, delegate new BeatAction.Action(beat, delegate
{ {
JJ.UnHold(); JJ.UnHold();
if (crHandlerInstance.queuedEvents.Count > 0)
{
List<CallAndResponseHandler.CallAndResponseEvent> crEvents = crHandlerInstance.queuedEvents;
foreach (var crEvent in crEvents)
{
if (crEvent.tag == "riff")
{
RockersInput riffComp = Instantiate(rockerInputRef, transform);
riffComp.Init(crEvent["gleeClub"], new int[6] { crEvent["1"], crEvent["2"], crEvent["3"], crEvent["4"], crEvent["5"], crEvent["6"] }, beat, crEvent.relativeBeat,
(PremadeSamples)crEvent["sample"], crEvent["sampleTones"]);
ScheduleInput(beat, crEvent.relativeBeat + crEvent.length, InputType.STANDARD_DOWN, JustMute, MuteMiss, Empty);
}
else if (crEvent.tag == "bend")
{
RockerBendInput bendComp = Instantiate(rockerBendInputRef, transform);
bendComp.Init(crEvent["Pitch"], beat, crEvent.relativeBeat);
ScheduleInput(beat, crEvent.relativeBeat + crEvent.length, InputType.DIRECTION_UP, JustUnBend, UnBendMiss, Empty);
}
}
crHandlerInstance.queuedEvents.Clear();
}
}) })
}); });
if (moveCamera)
{
lastTargetCameraX = GameCamera.additionalPosition.x;
targetCameraX = Soshi.transform.localPosition.x;
cameraMoveBeat = beat - 1;
}
} }
} }

View file

@ -31,7 +31,8 @@ namespace HeavenStudio.Games.Scripts_WorkingDough
if (startBeat > double.MinValue) if (startBeat > double.MinValue)
{ {
Vector3 pos = GetPathPositionFromBeat(path, Math.Max(beat, startBeat), startBeat); Vector3 pos = GetPathPositionFromBeat(path, Math.Max(beat, startBeat), startBeat);
transform.position = pos; if (startBeat <= beat) transform.position = pos;
else transform.position = new Vector3(-80, -80);
if (beat >= startBeat + 2) Destroy(gameObject); if (beat >= startBeat + 2) Destroy(gameObject);
} }
} }

View file

@ -2,7 +2,6 @@ using HeavenStudio.Util;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using NaughtyBezierCurves;
namespace HeavenStudio.Games.Loaders namespace HeavenStudio.Games.Loaders
{ {
@ -15,26 +14,23 @@ namespace HeavenStudio.Games.Loaders
{ {
new GameAction("beat intervals", "Start Interval") new GameAction("beat intervals", "Start Interval")
{ {
preFunction = delegate { var e = eventCaller.currentEntity; WorkingDough.PreSetIntervalStart(e.beat, e.length); }, preFunction = delegate { var e = eventCaller.currentEntity; WorkingDough.PreSetIntervalStart(e.beat, e.length, e["auto"]); },
defaultLength = 8f, defaultLength = 8f,
resizable = true, resizable = true,
priority = 2, parameters = new List<Param>()
{
new Param("auto", true, "Auto Pass Turn", "Will the turn automatically be passed at the end of this event?")
}
}, },
new GameAction("small ball", "Small Ball") new GameAction("small ball", "Small Ball")
{ {
preFunction = delegate { var e = eventCaller.currentEntity; WorkingDough.PreSpawnBall(e.beat, false, false); },
defaultLength = 0.5f, defaultLength = 0.5f,
priority = 1, priority = 1,
inactiveFunction = delegate { var e = eventCaller.currentEntity; WorkingDough.OnSpawnBallInactive(e.beat, false, false); },
function = delegate { var e = eventCaller.currentEntity; WorkingDough.instance.OnSpawnBall(e.beat, false, false); }
}, },
new GameAction("big ball", "Big Ball") new GameAction("big ball", "Big Ball")
{ {
preFunction = delegate { var e = eventCaller.currentEntity; WorkingDough.PreSpawnBall(e.beat, true, e["hasGandw"]); },
defaultLength = 0.5f, defaultLength = 0.5f,
priority = 1, priority = 1,
inactiveFunction = delegate { var e = eventCaller.currentEntity; WorkingDough.OnSpawnBallInactive(e.beat, true, e["hasGandw"]); },
function = delegate { var e = eventCaller.currentEntity; WorkingDough.instance.OnSpawnBall(e.beat, true, e["hasGandw"]); },
parameters = new List<Param>() parameters = new List<Param>()
{ {
new Param("hasGandw", false, "Has Mr. Game & Watch") new Param("hasGandw", false, "Has Mr. Game & Watch")
@ -103,8 +99,12 @@ namespace HeavenStudio.Games.Loaders
}, },
new GameAction("disableBG", "Toggle Background") new GameAction("disableBG", "Toggle Background")
{ {
function = delegate { WorkingDough.instance.DisableBG(); }, function = delegate { WorkingDough.instance.DisableBG(eventCaller.currentEntity["ship"]); },
defaultLength = 0.5f defaultLength = 0.5f,
parameters = new List<Param>()
{
new Param("ship", false, "Spaceship Only", "Will only the spaceship be affected by this event?")
}
} }
}, },
new List<string>() {"rvl", "repeat"}, new List<string>() {"rvl", "repeat"},
@ -117,6 +117,7 @@ namespace HeavenStudio.Games.Loaders
namespace HeavenStudio.Games namespace HeavenStudio.Games
{ {
using Jukebox;
using Scripts_WorkingDough; using Scripts_WorkingDough;
public class WorkingDough : Minigame public class WorkingDough : Minigame
@ -154,6 +155,7 @@ namespace HeavenStudio.Games
[SerializeField] Animator gandwAnim; [SerializeField] Animator gandwAnim;
[SerializeField] private GameObject[] bgObjects; [SerializeField] private GameObject[] bgObjects;
[SerializeField] private GameObject shipObject;
private bool bgDisabled; private bool bgDisabled;
[Header("Variables")] [Header("Variables")]
@ -165,14 +167,7 @@ namespace HeavenStudio.Games
double gandMovingStartBeat; double gandMovingStartBeat;
public bool bigMode; public bool bigMode;
public bool bigModePlayer; public bool bigModePlayer;
static List<QueuedBall> queuedBalls = new List<QueuedBall>();
static List<double> passedTurns = new List<double>(); static List<double> passedTurns = new List<double>();
struct QueuedBall
{
public double beat;
public bool isBig;
public bool hasGandw;
}
public bool spaceshipRisen = false; public bool spaceshipRisen = false;
public bool spaceshipRising = false; public bool spaceshipRising = false;
bool liftingDoughDudes; bool liftingDoughDudes;
@ -215,10 +210,6 @@ namespace HeavenStudio.Games
void Awake() void Awake()
{ {
if (crHandlerInstance == null)
{
crHandlerInstance = new CallAndResponseHandler(8);
}
instance = this; instance = this;
} }
@ -228,73 +219,83 @@ namespace HeavenStudio.Games
doughDudesHolderAnim.Play("OnGround", 0, 0); doughDudesHolderAnim.Play("OnGround", 0, 0);
} }
public void DisableBG() private bool shipOnly;
public void DisableBG(bool ship)
{ {
shipOnly = ship;
bgDisabled = !bgDisabled; bgDisabled = !bgDisabled;
foreach (var bgObject in bgObjects) foreach (var bgObject in bgObjects)
{ {
bgObject.SetActive(!bgDisabled); bgObject.SetActive(!bgDisabled || shipOnly);
} }
shipObject.SetActive(!bgDisabled && !shipOnly);
} }
public void SetIntervalStart(double beat, float interval) private static List<RiqEntity> GetAllBallsInBetweenBeat(double beat, double endBeat)
{ {
if (!crHandlerInstance.IntervalIsActive()) List<RiqEntity> ballEvents = EventCaller.GetAllInGameManagerList("workingDough", new string[] { "small ball", "big ball" });
{ List<RiqEntity> tempEvents = new();
bigMode = false;
BeatAction.New(ballTransporterLeftNPC, new List<BeatAction.Action>()
{
new BeatAction.Action(beat - 1, delegate
{
if (!instance.ballTransporterLeftNPC.GetComponent<Animator>().IsPlayingAnimationName("BallTransporterLeftOpened"))
{
instance.ballTransporterLeftNPC.GetComponent<Animator>().Play("BallTransporterLeftOpen", 0, 0);
instance.ballTransporterRightNPC.GetComponent<Animator>().Play("BallTransporterRightOpen", 0, 0);
if (instance.gandwHasEntered && !bgDisabled) instance.gandwAnim.Play("GANDWLeverUp", 0, 0);
}
}),
//Open player transporters
/*
new BeatAction.Action(beat + interval - 1f, delegate {
ballTransporterRightPlayer.GetComponent<Animator>().Play("BallTransporterRightOpen", 0, 0);
}),
new BeatAction.Action(beat + interval - 1f, delegate {
ballTransporterRightPlayer.GetComponent<Animator>().Play("BallTransporterRightOpen", 0, 0);
}),*/
//Close npc transporters foreach (var entity in ballEvents)
new BeatAction.Action(beat + interval, delegate { {
if (bigMode) if (entity.beat >= beat && entity.beat < endBeat)
{ {
NPCBallTransporters.GetComponent<Animator>().Play("NPCExitBigMode", 0, 0); tempEvents.Add(entity);
bigMode = false; }
}
}),
/*
new BeatAction.Action(beat + interval + 1, delegate { if (!intervalStarted) ballTransporterLeftNPC.GetComponent<Animator>().Play("BallTransporterLeftClose", 0, 0); }),
new BeatAction.Action(beat + interval + 1, delegate { if (!intervalStarted) ballTransporterRightNPC.GetComponent<Animator>().Play("BallTransporterRightClose", 0, 0); }),
new BeatAction.Action(beat + interval + 1, delegate { if (gandwHasEntered) gandwAnim.Play("MrGameAndWatchLeverDown", 0, 0); }),
//Close player transporters
new BeatAction.Action(beat + interval * 2 + 1, delegate { ballTransporterLeftPlayer.GetComponent<Animator>().Play("BallTransporterLeftClose", 0, 0); }),
new BeatAction.Action(beat + interval * 2 + 1, delegate { ballTransporterRightPlayer.GetComponent<Animator>().Play("BallTransporterRightClose", 0, 0); }),
new BeatAction.Action(beat + interval * 2 + 1, delegate {
if (bigModePlayer)
{
PlayerBallTransporters.GetComponent<Animator>().Play("PlayerExitBigMode", 0, 0);
bigModePlayer = false;
}
}),
*/
});
} }
return tempEvents;
}
public void SetIntervalStart(double beat, double gameSwitchBeat, float interval = 8f, bool autoPassTurn = true)
{
CallAndResponseHandler newHandler = new();
crHandlerInstance = newHandler;
crHandlerInstance.StartInterval(beat, interval); crHandlerInstance.StartInterval(beat, interval);
List<RiqEntity> relevantBalls = GetAllBallsInBetweenBeat(beat, beat + interval);
bool hasBigBall = false;
foreach (var ball in relevantBalls)
{
bool isBig = ball.datamodel == "workingDough/big ball";
if (ball.beat >= gameSwitchBeat)
{
SpawnBall(ball.beat - 1, isBig, isBig && ball["hasGandw"]);
OnSpawnBall(ball.beat, isBig, isBig && ball["hasGandw"]);
}
else
{
OnSpawnBallInactive(ball.beat, isBig, isBig && ball["hasGandw"]);
}
if (isBig) hasBigBall = true;
}
if (autoPassTurn)
{
PassTurn(beat + interval, interval, newHandler);
}
BeatAction.New(ballTransporterLeftNPC, new List<BeatAction.Action>()
{
new BeatAction.Action(beat - 1, delegate
{
bigMode = hasBigBall;
if (bigMode)
{
NPCBallTransporters.GetComponent<Animator>().Play("NPCGoBigMode", 0, 0);
}
if (!instance.ballTransporterLeftNPC.GetComponent<Animator>().IsPlayingAnimationName("BallTransporterLeftOpened"))
{
instance.ballTransporterLeftNPC.GetComponent<Animator>().Play("BallTransporterLeftOpen", 0, 0);
instance.ballTransporterRightNPC.GetComponent<Animator>().Play("BallTransporterRightOpen", 0, 0);
if (instance.gandwHasEntered && !bgDisabled) instance.gandwAnim.Play("GANDWLeverUp", 0, 0);
}
}),
});
} }
public static void PrePassTurn(double beat) public static void PrePassTurn(double beat)
{ {
if (GameManager.instance.currentGame == "workingDough") if (GameManager.instance.currentGame == "workingDough")
{ {
instance.PassTurn(beat); instance.PassTurnStandalone(beat);
} }
else else
{ {
@ -302,45 +303,61 @@ namespace HeavenStudio.Games
} }
} }
private void PassTurn(double beat) private void PassTurnStandalone(double beat)
{ {
if (crHandlerInstance.queuedEvents.Count > 0) if (crHandlerInstance != null) PassTurn(beat, crHandlerInstance.intervalLength, crHandlerInstance);
}
private void PassTurn(double beat, double length, CallAndResponseHandler crHandler)
{
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{ {
ballTransporterRightPlayer.GetComponent<Animator>().Play("BallTransporterRightOpen", 0, 0); new BeatAction.Action(beat - 1, delegate
ballTransporterLeftPlayer.GetComponent<Animator>().Play("BallTransporterLeftOpen", 0, 0);
foreach (var ball in crHandlerInstance.queuedEvents)
{ {
SpawnPlayerBall(beat + ball.relativeBeat - 1, ball.tag == "big", ball["hasGandw"]); ballTransporterRightPlayer.GetComponent<Animator>().Play("BallTransporterRightOpen", 0, 0);
} ballTransporterLeftPlayer.GetComponent<Animator>().Play("BallTransporterLeftOpen", 0, 0);
crHandlerInstance.queuedEvents.Clear(); if (crHandler.queuedEvents.Count > 0)
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{
new BeatAction.Action(beat, delegate
{ {
if (crHandlerInstance.queuedEvents.Count > 0) bool hasBig = false;
foreach (var ball in crHandler.queuedEvents)
{ {
foreach (var ball in crHandlerInstance.queuedEvents) SpawnPlayerBall(beat + ball.relativeBeat - 1, ball.tag == "big", ball["hasGandw"]);
{ if (ball.tag == "big") hasBig = true;
SpawnPlayerBall(beat + ball.relativeBeat - 1, ball.tag == "big", ball["hasGandw"]);
}
crHandlerInstance.queuedEvents.Clear();
} }
}), crHandler.queuedEvents.Clear();
new BeatAction.Action(beat + 1, delegate { if (!crHandlerInstance.IntervalIsActive()) ballTransporterLeftNPC.GetComponent<Animator>().Play("BallTransporterLeftClose", 0, 0); }), bigModePlayer = hasBig;
new BeatAction.Action(beat + 1, delegate { if (!crHandlerInstance.IntervalIsActive()) ballTransporterRightNPC.GetComponent<Animator>().Play("BallTransporterRightClose", 0, 0); }),
new BeatAction.Action(beat + 1, delegate { if (gandwHasEntered && !bgDisabled) gandwAnim.Play("MrGameAndWatchLeverDown", 0, 0); }),
//Close player transporters
new BeatAction.Action(beat + crHandlerInstance.intervalLength + 1, delegate { ballTransporterLeftPlayer.GetComponent<Animator>().Play("BallTransporterLeftClose", 0, 0); }),
new BeatAction.Action(beat + crHandlerInstance.intervalLength + 1, delegate { ballTransporterRightPlayer.GetComponent<Animator>().Play("BallTransporterRightClose", 0, 0); }),
new BeatAction.Action(beat + crHandlerInstance.intervalLength + 1, delegate {
if (bigModePlayer) if (bigModePlayer)
{ {
PlayerBallTransporters.GetComponent<Animator>().Play("PlayerExitBigMode", 0, 0); PlayerBallTransporters.GetComponent<Animator>().Play("PlayerGoBigMode", 0, 0);
bigModePlayer = false;
} }
}), }
}); }),
} new BeatAction.Action(beat + 1, delegate
{
if (gandwHasEntered && !bgDisabled) gandwAnim.Play("MrGameAndWatchLeverDown", 0, 0);
if (crHandlerInstance == null || !crHandlerInstance.IntervalIsActive())
{
ballTransporterLeftNPC.GetComponent<Animator>().Play("BallTransporterLeftClose", 0, 0);
ballTransporterRightNPC.GetComponent<Animator>().Play("BallTransporterRightClose", 0, 0);
}
if (bigMode)
{
NPCBallTransporters.GetComponent<Animator>().Play("NPCExitBigMode", 0, 0);
bigMode = false;
}
}),
//Close player transporters
new BeatAction.Action(beat + length + 1, delegate
{
ballTransporterLeftPlayer.GetComponent<Animator>().Play("BallTransporterLeftClose", 0, 0);
ballTransporterRightPlayer.GetComponent<Animator>().Play("BallTransporterRightClose", 0, 0);
if (bigModePlayer)
{
PlayerBallTransporters.GetComponent<Animator>().Play("PlayerExitBigMode", 0, 0);
bigModePlayer = false;
}
}),
});
} }
public void SpawnBall(double beat, bool isBig, bool hasGandw) public void SpawnBall(double beat, bool isBig, bool hasGandw)
@ -351,19 +368,10 @@ namespace HeavenStudio.Games
var ballComponent = spawnedBall.GetComponent<NPCDoughBall>(); var ballComponent = spawnedBall.GetComponent<NPCDoughBall>();
spawnedBall.SetActive(true); spawnedBall.SetActive(true);
ballComponent.Init(beat, hasGandw); ballComponent.Init(beat, hasGandw);
if (isBig && !bigMode)
{
NPCBallTransporters.GetComponent<Animator>().Play("NPCGoBigMode", 0, 0);
bigMode = true;
}
arrowSRLeftNPC.sprite = redArrowSprite;
BeatAction.New(doughDudesNPC, new List<BeatAction.Action>() BeatAction.New(doughDudesNPC, new List<BeatAction.Action>()
{ {
//Jump and play sound //Jump and play sound
new BeatAction.Action(beat, delegate { arrowSRLeftNPC.sprite = redArrowSprite; }),
new BeatAction.Action(beat + 0.1f, delegate { arrowSRLeftNPC.sprite = whiteArrowSprite; }), new BeatAction.Action(beat + 0.1f, delegate { arrowSRLeftNPC.sprite = whiteArrowSprite; }),
new BeatAction.Action(beat + 1f, delegate { doughDudesNPC.GetComponent<Animator>().DoScaledAnimationAsync(isBig ? "BigDoughJump" :"SmallDoughJump", 0.5f); }), new BeatAction.Action(beat + 1f, delegate { doughDudesNPC.GetComponent<Animator>().DoScaledAnimationAsync(isBig ? "BigDoughJump" :"SmallDoughJump", 0.5f); }),
new BeatAction.Action(beat + 1f, delegate { npcImpact.SetActive(true); }), new BeatAction.Action(beat + 1f, delegate { npcImpact.SetActive(true); }),
@ -373,43 +381,11 @@ namespace HeavenStudio.Games
}); });
} }
public static void PreSpawnBall(double beat, bool isBig, bool hasGandw)
{
double spawnBeat = beat - 1f;
beat -= 1f;
if (GameManager.instance.currentGame == "workingDough")
{
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{
new BeatAction.Action(spawnBeat, delegate
{
if (!instance.ballTransporterLeftNPC.GetComponent<Animator>().IsPlayingAnimationName("BallTransporterLeftOpened") && !crHandlerInstance.IntervalIsActive() && !instance.bgDisabled)
{
instance.ballTransporterLeftNPC.GetComponent<Animator>().Play("BallTransporterLeftOpen", 0, 0);
instance.ballTransporterRightNPC.GetComponent<Animator>().Play("BallTransporterRightOpen", 0, 0);
if (instance.gandwHasEntered) instance.gandwAnim.Play("GANDWLeverUp", 0, 0);
}
}),
new BeatAction.Action(spawnBeat, delegate { if (instance != null) instance.SpawnBall(beat, isBig, hasGandw); }),
// new BeatAction.Action(spawnBeat + instance.beatInterval, delegate { instance.SpawnPlayerBall(beat + instance.beatInterval, isBig); }),
});
}
else
{
queuedBalls.Add(new QueuedBall()
{
beat = beat + 1f,
isBig = isBig,
hasGandw = hasGandw
});
}
}
public static void OnSpawnBallInactive(double beat, bool isBig, bool hasGandw) public static void OnSpawnBallInactive(double beat, bool isBig, bool hasGandw)
{ {
if (crHandlerInstance == null) if (crHandlerInstance == null)
{ {
crHandlerInstance = new CallAndResponseHandler(8); crHandlerInstance = new CallAndResponseHandler();
} }
crHandlerInstance.AddEvent(beat, 0, isBig ? "big" : "small", new List<CallAndResponseHandler.CallAndResponseEventParam>() crHandlerInstance.AddEvent(beat, 0, isBig ? "big" : "small", new List<CallAndResponseHandler.CallAndResponseEventParam>()
{ {
@ -423,17 +399,8 @@ namespace HeavenStudio.Games
{ {
new CallAndResponseHandler.CallAndResponseEventParam("hasGandw", hasGandw) new CallAndResponseHandler.CallAndResponseEventParam("hasGandw", hasGandw)
}); });
SoundByte.PlayOneShotGame(isBig ? "workingDough/hitBigOther" : "workingDough/hitSmallOther"); SoundByte.PlayOneShotGame(isBig ? "workingDough/hitBigOther" : "workingDough/hitSmallOther", beat);
SoundByte.PlayOneShotGame(isBig ? "workingDough/bigOther" : "workingDough/smallOther"); SoundByte.PlayOneShotGame(isBig ? "workingDough/bigOther" : "workingDough/smallOther", beat);
}
public static void InactiveInterval(double beat, float interval)
{
if (crHandlerInstance == null)
{
crHandlerInstance = new CallAndResponseHandler(8);
}
crHandlerInstance.StartInterval(beat, interval);
} }
public void SpawnPlayerBall(double beat, bool isBig, bool hasGandw) public void SpawnPlayerBall(double beat, bool isBig, bool hasGandw)
@ -445,12 +412,6 @@ namespace HeavenStudio.Games
spawnedBall.SetActive(true); spawnedBall.SetActive(true);
ballComponent.Init(beat, isBig, hasGandw); ballComponent.Init(beat, isBig, hasGandw);
if (isBig && !bigModePlayer)
{
PlayerBallTransporters.GetComponent<Animator>().Play("PlayerGoBigMode", 0, 0);
bigModePlayer = true;
}
BeatAction.New(doughDudesPlayer, new List<BeatAction.Action>() BeatAction.New(doughDudesPlayer, new List<BeatAction.Action>()
{ {
new BeatAction.Action(beat, delegate { arrowSRLeftPlayer.sprite = redArrowSprite; }), new BeatAction.Action(beat, delegate { arrowSRLeftPlayer.sprite = redArrowSprite; }),
@ -458,17 +419,30 @@ namespace HeavenStudio.Games
}); });
} }
public static void PreSetIntervalStart(double beat, float interval) private struct QueuedInterval
{
public double beat;
public float interval;
public bool auto;
}
private static List<QueuedInterval> queuedIntervals = new();
public static void PreSetIntervalStart(double beat, float interval, bool auto)
{ {
if (GameManager.instance.currentGame == "workingDough") if (GameManager.instance.currentGame == "workingDough")
{ {
// instance.ballTriggerSetInterval = false; // instance.ballTriggerSetInterval = false;
// beatInterval = interval; // beatInterval = interval;
instance.SetIntervalStart(beat, interval); instance.SetIntervalStart(beat, beat, interval, auto);
} }
else else
{ {
InactiveInterval(beat, interval); queuedIntervals.Add(new QueuedInterval
{
beat = beat,
interval = interval,
auto = auto
});
} }
} }
@ -478,7 +452,6 @@ namespace HeavenStudio.Games
{ {
crHandlerInstance = null; crHandlerInstance = null;
} }
if (queuedBalls.Count > 0) queuedBalls.Clear();
foreach (var evt in scheduledInputs) foreach (var evt in scheduledInputs)
{ {
evt.Disable(); evt.Disable();
@ -487,38 +460,26 @@ namespace HeavenStudio.Games
public override void OnGameSwitch(double beat) public override void OnGameSwitch(double beat)
{ {
if (queuedBalls.Count > 0) if (Conductor.instance.isPlaying && !Conductor.instance.isPaused)
{ {
foreach (var ball in queuedBalls) if (queuedIntervals.Count > 0)
{ {
if (ball.isBig) NPCBallTransporters.GetComponent<Animator>().Play("BigMode", 0, 0); foreach (var interval in queuedIntervals)
if (!crHandlerInstance.IntervalIsActive())
{ {
ballTransporterLeftNPC.GetComponent<Animator>().Play("BallTransporterLeftOpened", 0, 0); SetIntervalStart(interval.beat, beat, interval.interval, interval.auto);
ballTransporterRightNPC.GetComponent<Animator>().Play("BallTransporterRightOpened", 0, 0);
if (gandwHasEntered && !bgDisabled) gandwAnim.Play("GANDWLeverUp", 0, 0);
} }
if (ball.beat > beat - 1) queuedIntervals.Clear();
{
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
{
new BeatAction.Action(ball.beat - 1, delegate { SpawnBall(ball.beat - 1, ball.isBig, ball.hasGandw); })
});
}
} }
queuedBalls.Clear();
} }
} }
public override void OnPlay(double beat)
{
crHandlerInstance = null;
}
void Update() void Update()
{ {
Conductor cond = Conductor.instance;
if (!cond.isPlaying || cond.isPaused)
{
if (queuedBalls.Count > 0) queuedBalls.Clear();
}
if (spaceshipRising && !bgDisabled) spaceshipAnimator.DoScaledAnimation("RiseSpaceship", risingStartBeat, risingLength); if (spaceshipRising && !bgDisabled) spaceshipAnimator.DoScaledAnimation("RiseSpaceship", risingStartBeat, risingLength);
if (liftingDoughDudes && !bgDisabled) doughDudesHolderAnim.DoScaledAnimation(liftingAnimName, liftingStartBeat, liftingLength); if (liftingDoughDudes && !bgDisabled) doughDudesHolderAnim.DoScaledAnimation(liftingAnimName, liftingStartBeat, liftingLength);
if (gandwMoving && !bgDisabled) gandwAnim.DoScaledAnimation(gandwMovingAnimName, gandMovingStartBeat, gandMovingLength); if (gandwMoving && !bgDisabled) gandwAnim.DoScaledAnimation(gandwMovingAnimName, gandMovingStartBeat, gandMovingLength);
@ -526,7 +487,7 @@ namespace HeavenStudio.Games
{ {
foreach (var passTurn in passedTurns) foreach (var passTurn in passedTurns)
{ {
PassTurn(passTurn); PassTurnStandalone(passTurn);
} }
passedTurns.Clear(); passedTurns.Clear();
} }