diff --git a/Assets/Scripts/Games/TossBoys/TossBoys.cs b/Assets/Scripts/Games/TossBoys/TossBoys.cs
index b583bd972..b6a134b6f 100644
--- a/Assets/Scripts/Games/TossBoys/TossBoys.cs
+++ b/Assets/Scripts/Games/TossBoys/TossBoys.cs
@@ -16,13 +16,23 @@ namespace HeavenStudio.Games.Loaders
{
new GameAction("dispense", "Dispense")
{
- function = delegate { var e = eventCaller.currentEntity; TossBoys.instance.Dispense(e.beat, e.length, e["who"], e["call"]); },
+ function = delegate { var e = eventCaller.currentEntity; TossBoys.instance.Dispense(e.beat, e.length, e["who"], e["auto"], e["interval"], e["ignore"], e["callAuto"], true, e["call"]); },
+ inactiveFunction = delegate { var e = eventCaller.currentEntity; TossBoys.DispenseSound(e.beat, e["who"], e["call"]); },
defaultLength = 2f,
resizable = true,
parameters = new List()
{
new Param("who", TossBoys.KidChoice.Akachan, "Receiver", "Who will receive the ball?"),
- new Param("call", false, "Name Call", "Should the other kids than the receiver call their name?")
+ new Param("call", false, "Name Call", "Should the other kids than the receiver call their name?"),
+
+ //auto dispense stuff
+ new Param("auto", true, "Auto Redispense", "", new()
+ {
+ new((x, _) => (bool)x, new string[] { "interval", "ignore", "callAuto" })
+ }),
+ new Param("interval", new EntityTypes.Integer(1, 20, 2), "Redispense Interval", "Based on passes and not beats"),
+ new Param("ignore", true, "Ignore Special Passes"),
+ new Param("callAuto", false, "Name Call On Redispense")
}
},
new GameAction("pass", "Normal Toss")
@@ -235,6 +245,7 @@ namespace HeavenStudio.Games
colorStart = defaultBGColor;
colorEnd = defaultBGColor;
SetupBopRegion("tossBoys", "bop", "auto");
+ SetPassBallEvents();
}
new void OnDrawGizmos()
@@ -339,6 +350,17 @@ namespace HeavenStudio.Games
public override void OnGameSwitch(double beat)
{
PersistColor(beat);
+ HandleDispenses(beat);
+ }
+
+ private void HandleDispenses(double beat)
+ {
+ var allRelevantDispenses = EventCaller.GetAllInGameManagerList("tossBoys", new string[] { "dispense" }).FindAll(x => x.beat < beat && x.beat + x.length >= beat);
+ if (allRelevantDispenses.Count == 0) return;
+
+ var e = allRelevantDispenses[^1];
+
+ Dispense(e.beat, e.length, e["who"], e["auto"], e["interval"], e["ignore"], e["callAuto"], false, e["call"]);
}
#region Bop
@@ -363,13 +385,108 @@ namespace HeavenStudio.Games
}
#endregion
- public void Dispense(double beat, float length, int who, bool call)
+ public static void DispenseSound(double beat, int who, bool call)
+ {
+ SoundByte.PlayOneShotGame("tossBoys/ballStart" + GetColorBasedOnTossKid((WhichTossKid)who, true), beat, forcePlay: true);
+ if (!call) return;
+ double callBeat = beat;
+ switch (who)
+ {
+ case (int)WhichTossKid.Akachan:
+ MultiSound.Play(new MultiSound.Sound[]
+ {
+ new MultiSound.Sound("tossBoys/blueRedHigh1", callBeat),
+ new MultiSound.Sound("tossBoys/yellowRedHigh1", callBeat),
+ new MultiSound.Sound("tossBoys/blueRedHigh2", callBeat + 0.25f),
+ new MultiSound.Sound("tossBoys/yellowRedHigh2", callBeat + 0.25f),
+ new MultiSound.Sound("tossBoys/blueRedHigh3", callBeat + 0.5f),
+ new MultiSound.Sound("tossBoys/yellowRedHigh3", callBeat + 0.5f),
+ }, forcePlay: true);
+ break;
+ case (int)WhichTossKid.Aokun:
+ MultiSound.Play(new MultiSound.Sound[]
+ {
+ new MultiSound.Sound("tossBoys/redBlueHigh1", callBeat),
+ new MultiSound.Sound("tossBoys/yellowBlueHigh1", callBeat),
+ new MultiSound.Sound("tossBoys/redBlueHigh2", callBeat + 0.5f),
+ new MultiSound.Sound("tossBoys/yellowBlueHigh2", callBeat + 0.5f),
+ }, forcePlay: true);
+ break;
+ case (int)WhichTossKid.Kiiyan:
+ MultiSound.Play(new MultiSound.Sound[]
+ {
+ new MultiSound.Sound("tossBoys/redYellowHigh1", callBeat),
+ new MultiSound.Sound("tossBoys/blueYellowHigh1", callBeat),
+ new MultiSound.Sound("tossBoys/redYellowHigh2", callBeat + 0.5f),
+ new MultiSound.Sound("tossBoys/blueYellowHigh2", callBeat + 0.5f),
+ }, forcePlay: true);
+ break;
+ default:
+ break;
+ }
+ }
+
+ public void Dispense(double beat, float length, int who, bool auto, int autoInterval, bool ignoreSpecial, bool callAuto, bool playSound, bool call)
+ {
+ if (playSound) DispenseSound(beat, who, call);
+ DispenseExec(beat, length, who, false, "");
+ if (auto && passBallDict.TryGetValue(beat + length, out var e))
+ {
+ DispenseRecursion(beat + length, -1, autoInterval, ignoreSpecial, callAuto, e["who"], (int)WhichTossKid.None, false, e.length, IsSpecialEvent(e.datamodel), false, e.datamodel);
+ }
+ }
+
+ public void DispenseRecursion(double beat, int index, int interval, bool ignore, bool call, int curReceiver, int previousReceiver, bool isBlur, float currentLength, bool isSpecial, bool shouldForce, string eventDatamodel)
+ {
+ if (index % interval == 0 && !isBlur && !(ignore && isSpecial))
+ {
+ double dispenseBeat = beat - 2;
+ BeatAction.New(this, new()
+ {
+ new(dispenseBeat, delegate
+ {
+ if (currentBall != null) return;
+ DispenseSound(dispenseBeat, curReceiver, call);
+ DispenseExec(dispenseBeat, 2, curReceiver, shouldForce, eventDatamodel);
+ })
+ });
+ }
+ if (!isBlur && !(ignore && isSpecial)) index++;
+
+ var tempLastReceiver = previousReceiver;
+ var lastLength = isBlur ? 1 : currentLength;
+ previousReceiver = curReceiver;
+ var nextIsSpecial = isSpecial;
+
+ var blurSet = isBlur;
+ var nextForce = false;
+ if (passBallDict.TryGetValue(beat + lastLength, out var e))
+ {
+ curReceiver = e["who"];
+ blurSet = e.datamodel == "tossBoys/blur";
+ currentLength = e.length;
+ nextIsSpecial = IsSpecialEvent(e.datamodel);
+ eventDatamodel = e.datamodel;
+ if (e.datamodel == "tossBoys/pop") return;
+ }
+ else
+ {
+ curReceiver = tempLastReceiver;
+ nextForce = true;
+ }
+ // let's not do a stack overflow, alright?
+ BeatAction.New(this, new()
+ {
+ new(beat + lastLength - 2, delegate { DispenseRecursion(beat + lastLength, index, interval, ignore, call, curReceiver, previousReceiver, blurSet, currentLength, nextIsSpecial, nextForce, eventDatamodel); })
+ });
+ }
+
+ public void DispenseExec(double beat, float length, int who, bool forcePass, string eventDatamodel)
{
if (currentBall != null) return;
- SetPassBallEvents();
SetReceiver(who);
GetCurrentReceiver().ShowArrow(beat, length - 1);
- SoundByte.PlayOneShotGame("tossBoys/ballStart" + GetColorBasedOnTossKid(currentReceiver, true));
+
hatchAnim.Play("HatchOpen", 0, 0);
currentBall = Instantiate(ballPrefab, transform);
currentBall.gameObject.SetActive(true);
@@ -388,50 +505,10 @@ namespace HeavenStudio.Games
break;
}
- if (call)
- {
- double callBeat = beat;
- switch (who)
- {
- case (int)WhichTossKid.Akachan:
- MultiSound.Play(new MultiSound.Sound[]
- {
- new MultiSound.Sound("tossBoys/blueRedHigh1", callBeat),
- new MultiSound.Sound("tossBoys/yellowRedHigh1", callBeat),
- new MultiSound.Sound("tossBoys/blueRedHigh2", callBeat + 0.25f),
- new MultiSound.Sound("tossBoys/yellowRedHigh2", callBeat + 0.25f),
- new MultiSound.Sound("tossBoys/blueRedHigh3", callBeat + 0.5f),
- new MultiSound.Sound("tossBoys/yellowRedHigh3", callBeat + 0.5f),
- });
- break;
- case (int)WhichTossKid.Aokun:
- MultiSound.Play(new MultiSound.Sound[]
- {
- new MultiSound.Sound("tossBoys/redBlueHigh1", callBeat),
- new MultiSound.Sound("tossBoys/yellowBlueHigh1", callBeat),
- new MultiSound.Sound("tossBoys/redBlueHigh2", callBeat + 0.5f),
- new MultiSound.Sound("tossBoys/yellowBlueHigh2", callBeat + 0.5f),
- });
- break;
- case (int)WhichTossKid.Kiiyan:
- MultiSound.Play(new MultiSound.Sound[]
- {
- new MultiSound.Sound("tossBoys/redYellowHigh1", callBeat),
- new MultiSound.Sound("tossBoys/blueYellowHigh1", callBeat),
- new MultiSound.Sound("tossBoys/redYellowHigh2", callBeat + 0.5f),
- new MultiSound.Sound("tossBoys/blueYellowHigh2", callBeat + 0.5f),
- });
- break;
- default:
- break;
- }
- }
-
-
if (passBallDict.ContainsKey(beat + length))
{
ScheduleInput(beat, length, GetInputTypeBasedOnCurrentReceiver(), JustHitBall, Miss, Empty);
- if (passBallDict[beat + length].datamodel == "tossBoys/dual" || passBallDict[beat + length].datamodel == "tossBoys/lightning" || passBallDict[beat + length].datamodel == "tossBoys/blur")
+ if (IsSpecialEvent(passBallDict[beat + length].datamodel))
{
BeatAction.New(instance, new List()
{
@@ -448,6 +525,26 @@ namespace HeavenStudio.Games
});
}
}
+ else if (forcePass)
+ {
+ ScheduleInput(beat, length, GetInputTypeBasedOnCurrentReceiver(), JustHitBall, Miss, Empty);
+ if (IsSpecialEvent(eventDatamodel))
+ {
+ BeatAction.New(instance, new List()
+ {
+ new BeatAction.Action(beat + length - 1, delegate { DoSpecialBasedOnReceiver(beat + length - 1); })
+ });
+ }
+ else if (eventDatamodel == "tossBoys/pop")
+ {
+ currentBall.willBePopped = true;
+ if (PlayerInput.CurrentControlStyle != InputController.ControlStyles.Touch)
+ BeatAction.New(instance, new List()
+ {
+ new BeatAction.Action(beat + length - 1, delegate { GetCurrentReceiver().PopBallPrepare(); })
+ });
+ }
+ }
else
{
BeatAction.New(instance, new List()
@@ -461,17 +558,14 @@ namespace HeavenStudio.Games
{
passBallDict.Clear();
var passBallEvents = EventCaller.GetAllInGameManagerList("tossBoys", new string[] { "pass", "dual", "pop", "high", "lightning", "blur" });
- for (int i = 0; i < passBallEvents.Count; i++)
+ for (int i = 0; i < passBallEvents.Count; i++)
{
- if (passBallEvents[i].beat >= Conductor.instance.songPositionInBeatsAsDouble)
- {
- if (passBallDict.ContainsKey(passBallEvents[i].beat)) continue;
- passBallDict.Add(passBallEvents[i].beat, passBallEvents[i]);
- }
+ if (passBallDict.ContainsKey(passBallEvents[i].beat)) continue;
+ passBallDict.Add(passBallEvents[i].beat, passBallEvents[i]);
}
}
- void DeterminePass(double beat, bool barely)
+ private void DeterminePassValues(double beat)
{
var tempLastReceiver = lastReceiver;
lastReceiver = currentReceiver;
@@ -483,14 +577,13 @@ namespace HeavenStudio.Games
}
else
{
- /*
- RiqEntity spawnedEntity = new RiqEntity();
- spawnedEntity.DynamicData.Add("who", (int)tempLastReceiver);
- spawnedEntity.datamodel = currentPassType;
- passBallDict.Add(beat, spawnedEntity);
- */
currentReceiver = tempLastReceiver;
}
+ }
+
+ void DeterminePass(double beat, bool barely)
+ {
+ DeterminePassValues(beat);
switch (currentPassType)
{
case "tossBoys/pass":
@@ -508,14 +601,7 @@ namespace HeavenStudio.Games
default:
break;
}
- if (barely)
- {
- currentBall.anim.DoScaledAnimationAsync("WiggleBall", 0.5f);
- }
- else
- {
- currentBall.anim.DoScaledAnimationAsync("Hit", 0.5f);
- }
+ currentBall.anim.DoScaledAnimationAsync(barely ? "WiggleBall" : "Hit", 0.5f);
if (passBallDict.ContainsKey(beat + currentEventLength) && passBallDict[beat + currentEventLength].datamodel == "tossBoys/pop")
{
currentBall.willBePopped = true;
@@ -1048,6 +1134,7 @@ namespace HeavenStudio.Games
Destroy(currentBall.gameObject);
currentBall = null;
SoundByte.PlayOneShotGame("tossBoys/misshit");
+ if (caller != null) DeterminePassValues(caller.startBeat + caller.timer);
}
void Empty(PlayerActionEvent caller) { }
@@ -1110,7 +1197,7 @@ namespace HeavenStudio.Games
}
}
- string GetColorBasedOnTossKid(WhichTossKid tossKid, bool capital)
+ public static string GetColorBasedOnTossKid(WhichTossKid tossKid, bool capital)
{
switch (tossKid)
{
@@ -1162,6 +1249,24 @@ namespace HeavenStudio.Games
return null;
}
}
+
+ private bool IsSpecialEvent(string e)
+ {
+ bool b = false;
+
+ switch (e)
+ {
+ case "tossBoys/dual":
+ case "tossBoys/lightning":
+ case "tossBoys/blur":
+ b = true; break;
+ default:
+ return b;
+ }
+
+ return b;
+ }
+
#endregion
}
}