cb3b21389e
* i love the blue bear * launch party beginning * fork lifter fixes * whiff strum guitar + snekky * rockers score miss fix * splashdown tweak * auto dispense and inactive dispense iteration 1 * fixed some auto dispense bugs * another small fix * auto dispense + miss stuff * fixed mr game and watch being slow boy * no log * monk fix * bg launch aprt * coint oss layer thing * tap troupe and double date fixes * fixing spaceball line * extended cheer reaers bg * upbeat constant * fixed uglyness * Gomenasai * fix lines 2 * tram and pauline new sprite --------- Co-authored-by: ev <85412919+evdial@users.noreply.github.com> Co-authored-by: minenice55 <star.elementa@gmail.com>
634 lines
29 KiB
C#
634 lines
29 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using HeavenStudio.Util;
|
|
|
|
namespace HeavenStudio.Games.Loaders
|
|
{
|
|
using static Minigames;
|
|
public static class NtrSoccerLoader
|
|
{
|
|
public static Minigame AddGame(EventCaller eventCaller) {
|
|
return new Minigame("spaceSoccer", "Space Soccer", "ff7d27", false, false, new List<GameAction>()
|
|
{
|
|
new GameAction("ball dispense", "Ball Dispense")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; SpaceSoccer.instance.Dispense(e.beat, !e["toggle"], false, e["down"], e["auto"], e["interval"]); },
|
|
defaultLength = 2f,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("toggle", false, "Disable Sound", "Disables the dispense sound"),
|
|
new Param("down", false, "Down Sound", "Will the Down sound be played?"),
|
|
new Param("auto", true, "Auto Redispense", "", new()
|
|
{
|
|
new((x, _) => (bool)x, new string[] { "interval" })
|
|
}),
|
|
new("interval", new EntityTypes.Integer(2, 20, 2), "Redispense Interval")
|
|
},
|
|
inactiveFunction = delegate
|
|
{
|
|
if (!eventCaller.currentEntity["toggle"]) { SpaceSoccer.DispenseSound(eventCaller.currentEntity.beat, eventCaller.currentEntity["down"]);}
|
|
}
|
|
},
|
|
new GameAction("high kick-toe!", "High Kick-Toe!")
|
|
{
|
|
defaultLength = 3f,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("swing", new EntityTypes.Float(0, 1, 0.5f), "Swing", "The amount of swing")
|
|
}
|
|
},
|
|
new GameAction("npc kickers enter or exit", "NPC Kickers Enter or Exit")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; SpaceSoccer.instance.NPCKickersEnterOrExit(e.beat, e.length, e["choice"], e["ease"], e["amount"], e["x"], e["y"], e["z"], e["override"], e["preset"]); },
|
|
defaultLength = 4f,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("preset", SpaceSoccer.EnterExitPresets.FiveKickers, "Preset", "Which preset should be used?", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, _) => (int)x == (int)SpaceSoccer.EnterExitPresets.Custom, new string[] { "amount", "x", "y", "z" })
|
|
}),
|
|
|
|
|
|
new Param("amount", new EntityTypes.Integer(2, 30, 5), "Amount", "Amount of Space Kickers."),
|
|
new Param("x", new EntityTypes.Float(-30, 30, 2f), "X Distance", "How much distance should there be between the space kickers on the x axis?"),
|
|
new Param("y", new EntityTypes.Float(-30, 30, -0.5f), "Y Distance", "How much distance should there be between the space kickers on the y axis?"),
|
|
new Param("z", new EntityTypes.Float(-30, 30, 1.25f), "Z Distance", "How much distance should there be between the space kickers on the z axis?"),
|
|
|
|
new Param("choice", SpaceSoccer.AnimationToPlay.Enter, "Enter Or Exit", "Whether the kickers should exit or enter."),
|
|
new Param("ease", EasingFunction.Ease.Linear, "Ease", "The Ease of the entering or exiting."),
|
|
new Param("override", true, "Override Easing", "Should this block override the easing of the space kickers' positions?")
|
|
},
|
|
resizable = true
|
|
},
|
|
new GameAction("easePos", "Ease NPC Space Kicker Distances")
|
|
{
|
|
function = delegate {var e = eventCaller.currentEntity; SpaceSoccer.instance.EaseSpaceKickersPositions(e.beat, e.length, e["ease"], e["x"], e["y"], e["z"]); },
|
|
defaultLength = 4f,
|
|
resizable = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("x", new EntityTypes.Float(-30, 30, 2f), "X Distance", "How much distance should there be between the space kickers on the x axis?"),
|
|
new Param("y", new EntityTypes.Float(-30, 30, -0.5f), "Y Distance", "How much distance should there be between the space kickers on the y axis?"),
|
|
new Param("z", new EntityTypes.Float(-30, 30, 1.25f), "Z Distance", "How much distance should there be between the space kickers on the z axis?"),
|
|
new Param("ease", EasingFunction.Ease.Linear, "Ease", "The Ease of the space kickers moving."),
|
|
}
|
|
},
|
|
new GameAction("pMove", "Move Player")
|
|
{
|
|
function = delegate {var e = eventCaller.currentEntity; SpaceSoccer.instance.MovePlayerKicker(e.beat, e.length, e["ease"], e["x"], e["y"], e["z"], e["sound"], e["preset"]); },
|
|
defaultLength = 4f,
|
|
resizable = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("preset", SpaceSoccer.PlayerPresets.LaunchStart, "Preset", "Which preset should be used?", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, _) => (int)x == (int)SpaceSoccer.PlayerPresets.Custom, new string[] { "x", "y", "z", "ease", "sound" })
|
|
}),
|
|
new Param("x", new EntityTypes.Float(-30, 30, 0f), "X Pos", "Which position should the player move to on the x axis?"),
|
|
new Param("y", new EntityTypes.Float(-30, 30, 0f), "Y Pos", "Which position should the player move to on the y axis?"),
|
|
new Param("z", new EntityTypes.Float(-30, 30, 0f), "Z Pos", "Which position should the player move to on the z axis?"),
|
|
new Param("ease", EasingFunction.Ease.Linear, "Ease", "The Ease of the space kickers moving."),
|
|
new Param("sound", SpaceSoccer.LaunchSoundToPlay.None, "Sound", "Which launch sound should be played at the start of this block?")
|
|
}
|
|
},
|
|
new GameAction("changeBG", "Change Background Color")
|
|
{
|
|
function = delegate {var e = eventCaller.currentEntity; SpaceSoccer.instance.BackgroundColor(e.beat, e.length, e["start"], e["end"], e["startDots"], e["endDots"], e["ease"]); },
|
|
defaultLength = 1f,
|
|
resizable = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("start", SpaceSoccer.defaultBGColor, "Start Color", "The start color for the fade or the color that will be switched to if -instant- is ticked on."),
|
|
new Param("end", SpaceSoccer.defaultBGColor, "End Color", "The end color for the fade."),
|
|
new Param("startDots", Color.white, "Start Color (Dots)", "The start color for the fade or the color that will be switched to if -instant- is ticked on."),
|
|
new Param("endDots", Color.white, "End Color (Dots)", "The end color for the fade."),
|
|
new Param("ease", Util.EasingFunction.Ease.Linear, "Ease")
|
|
}
|
|
},
|
|
new GameAction("scroll", "Scrolling Background")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; SpaceSoccer.instance.UpdateScrollSpeed(e["x"], e["y"]); },
|
|
defaultLength = 1f,
|
|
parameters = new List<Param>() {
|
|
new Param("x", new EntityTypes.Float(-10f, 10, 0.1f), "Horizontal", "How fast does the background move horizontally?"),
|
|
new Param("y", new EntityTypes.Float(-10, 10f, 0.3f), "Vertical", "How fast does the background move vertically?"),
|
|
}
|
|
},
|
|
new GameAction("stopBall", "Stop Ball")
|
|
{
|
|
function = delegate { SpaceSoccer.instance.StopBall(eventCaller.currentEntity["toggle"]); },
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("toggle", true, "Stop ball?", "Should the ball be stopped? If ticked off the kickers will regain their ability to use the ball.")
|
|
}
|
|
},
|
|
// This is still here for "backwards-compatibility" but is hidden in the editor (it does absolutely nothing however)
|
|
new GameAction("keep-up", "")
|
|
{
|
|
defaultLength = 4f,
|
|
resizable = true,
|
|
hidden = true
|
|
},
|
|
new GameAction("npc kickers instant enter or exit", "NPC Kickers Instant Enter or Exit")
|
|
{
|
|
function = delegate
|
|
{
|
|
var e = eventCaller.currentEntity;
|
|
int choice;
|
|
if (e["toggle"])
|
|
{
|
|
choice = (int)SpaceSoccer.AnimationToPlay.Exit;
|
|
}
|
|
else
|
|
{
|
|
choice = (int)SpaceSoccer.AnimationToPlay.Enter;
|
|
}
|
|
SpaceSoccer.instance.NPCKickersEnterOrExit(e.beat, e.length, choice, (int)EasingFunction.Ease.Instant, 5, 1.75f, 0.25f, 0.75f, true, (int)SpaceSoccer.EnterExitPresets.Custom);
|
|
},
|
|
defaultLength = 0.5f,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("toggle", false, "Should Exit?", "Whether the kickers should be exited or entered.")
|
|
},
|
|
hidden = true
|
|
},
|
|
},
|
|
new List<string>() { "ntr", "keep" },
|
|
"ntrsoccer", "en",
|
|
new List<string>() { "en" }
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace HeavenStudio.Games
|
|
{
|
|
using Scripts_SpaceSoccer;
|
|
using HeavenStudio.Common;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.UI;
|
|
using System;
|
|
|
|
public class SpaceSoccer : Minigame
|
|
{
|
|
public enum EnterExitPresets
|
|
{
|
|
FiveKickers,
|
|
DuoKickers,
|
|
Custom
|
|
}
|
|
public enum PlayerPresets
|
|
{
|
|
LaunchStart = 0,
|
|
LaunchEnd = 1,
|
|
Custom = 2
|
|
}
|
|
public enum LaunchSoundToPlay
|
|
{
|
|
None = 0,
|
|
LaunchStart = 1,
|
|
LaunchEnd = 2
|
|
}
|
|
public enum AnimationToPlay
|
|
{
|
|
Enter = 0,
|
|
Exit = 1
|
|
}
|
|
private static Color _defaultBGColor;
|
|
public static Color defaultBGColor
|
|
{
|
|
get
|
|
{
|
|
ColorUtility.TryParseHtmlString("#FF7D27", out _defaultBGColor);
|
|
return _defaultBGColor;
|
|
}
|
|
}
|
|
[Header("Components")]
|
|
[SerializeField] private GameObject kickerPrefab;
|
|
[SerializeField] private GameObject ballRef;
|
|
[SerializeField] private List<Kicker> kickers;
|
|
[SerializeField] private CanvasScroll backgroundSprite;
|
|
[SerializeField] private RawImage bgImage;
|
|
[SerializeField] private SpriteRenderer bg;
|
|
|
|
[Header("Properties")]
|
|
[SerializeField] SuperCurveObject.Path[] ballPaths;
|
|
public bool ballDispensed;
|
|
double lastDispensedBeat;
|
|
float xScrollMultiplier = 0.1f;
|
|
float yScrollMultiplier = 0.3f;
|
|
[SerializeField] private float xBaseSpeed = 1;
|
|
[SerializeField] private float yBaseSpeed = 1;
|
|
|
|
private List<double> _highKickToeBeats = new();
|
|
private List<double> _stopBeats = new();
|
|
|
|
[NonSerialized] public List<double> hitBeats = new();
|
|
|
|
#region Space Kicker Position Easing
|
|
float easeBeat;
|
|
float easeLength;
|
|
EasingFunction.Ease lastEase;
|
|
Vector3 lastPos = new Vector3();
|
|
Vector3 currentPos = new Vector3();
|
|
float easeBeatP;
|
|
float easeLengthP;
|
|
EasingFunction.Ease lastEaseP;
|
|
Vector3 lastPosP = new Vector3();
|
|
Vector3 currentPosP = new Vector3();
|
|
#endregion
|
|
|
|
public static SpaceSoccer instance { get; private set; }
|
|
|
|
private void Awake()
|
|
{
|
|
instance = this;
|
|
colorStart = defaultBGColor;
|
|
colorEnd = defaultBGColor;
|
|
var allHighKickToeEvents = EventCaller.GetAllInGameManagerList("spaceSoccer", new string[] { "high kick-toe!" });
|
|
foreach (var e in allHighKickToeEvents)
|
|
{
|
|
_highKickToeBeats.Add(e.beat);
|
|
}
|
|
}
|
|
|
|
new void OnDrawGizmos()
|
|
{
|
|
base.OnDrawGizmos();
|
|
foreach (SuperCurveObject.Path path in ballPaths)
|
|
{
|
|
if (path.preview)
|
|
{
|
|
ballRef.GetComponent<Ball>().DrawEditorGizmo(path);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
var cond = Conductor.instance;
|
|
BackgroundColorUpdate();
|
|
backgroundSprite.NormalizedX -= xBaseSpeed * xScrollMultiplier * Time.deltaTime;
|
|
backgroundSprite.NormalizedY += yBaseSpeed * yScrollMultiplier * Time.deltaTime;
|
|
|
|
float normalizedEaseBeat = cond.GetPositionFromBeat(easeBeat, easeLength);
|
|
if (normalizedEaseBeat <= 1 && normalizedEaseBeat > 0)
|
|
{
|
|
EasingFunction.Function func = EasingFunction.GetEasingFunction(lastEase);
|
|
float newPosX = func(lastPos.x, currentPos.x, normalizedEaseBeat);
|
|
float newPosY = func(lastPos.y, currentPos.y, normalizedEaseBeat);
|
|
float newPosZ = func(lastPos.z, currentPos.z, normalizedEaseBeat);
|
|
UpdateKickersPositions(newPosX, newPosY, newPosZ);
|
|
}
|
|
|
|
float normalizedPBeat = cond.GetPositionFromBeat(easeBeatP, easeLengthP);
|
|
if (normalizedPBeat <= 1 && normalizedPBeat > 0)
|
|
{
|
|
EasingFunction.Function func = EasingFunction.GetEasingFunction(lastEaseP);
|
|
float newPosX = func(lastPosP.x, currentPosP.x, normalizedPBeat);
|
|
float newPosY = func(lastPosP.y, currentPosP.y, normalizedPBeat);
|
|
float newPosZ = func(lastPosP.z, currentPosP.z, normalizedPBeat);
|
|
kickers[0].transform.parent.position = new Vector3(3.384f - newPosX, newPosY, newPosZ);
|
|
}
|
|
}
|
|
|
|
public override void OnBeatPulse(double beat)
|
|
{
|
|
if (!ballDispensed) return;
|
|
|
|
double offsetBeat = beat + (lastDispensedBeat % 1);
|
|
|
|
if (_stopBeats.Exists(x => offsetBeat >= x) || offsetBeat < lastDispensedBeat + 2) return;
|
|
|
|
if (_highKickToeBeats.Exists(x => offsetBeat >= x + 1 && offsetBeat < x + 3))
|
|
{
|
|
if (_highKickToeBeats.Exists(x => offsetBeat == x + 2) && !IsExpectingInputNow(InputAction_FlickRelease))
|
|
{
|
|
if (hitBeats.Exists(x => x == offsetBeat - 0.5)) return;
|
|
ScoreMiss();
|
|
Debug.Log("Miss toe");
|
|
}
|
|
}
|
|
else if (!IsExpectingInputNow(InputAction_BasicPress))
|
|
{
|
|
if (hitBeats.Exists(x => offsetBeat == x)) return;
|
|
ScoreMiss();
|
|
Debug.Log("Miss");
|
|
}
|
|
}
|
|
|
|
public void StopBall(bool stop)
|
|
{
|
|
foreach (var kicker in kickers)
|
|
{
|
|
kicker.StopBall(stop);
|
|
}
|
|
}
|
|
|
|
public void NPCKickersEnterOrExit(double beat, float length, int animToPut, int easeToPut, int amount, float xDistance, float yDistance, float zDistance, bool overrideEasing, int preset)
|
|
{
|
|
switch (preset)
|
|
{
|
|
case (int)EnterExitPresets.Custom:
|
|
UpdateSpaceKickers(amount, xDistance, yDistance, zDistance, overrideEasing);
|
|
break;
|
|
case (int)EnterExitPresets.DuoKickers:
|
|
UpdateSpaceKickers(2, 7, -6, 10, overrideEasing);
|
|
break;
|
|
case (int)EnterExitPresets.FiveKickers:
|
|
UpdateSpaceKickers(5, 2, -0.5f, 1.25f, overrideEasing);
|
|
break;
|
|
}
|
|
|
|
string animName = "Enter";
|
|
switch (animToPut)
|
|
{
|
|
case (int)AnimationToPlay.Enter:
|
|
animName = "Enter";
|
|
break;
|
|
case (int)AnimationToPlay.Exit:
|
|
animName = "Exit";
|
|
break;
|
|
}
|
|
foreach (var kicker in kickers)
|
|
{
|
|
if (kicker.player) continue;
|
|
kicker.SetAnimParams(beat, length, animName, easeToPut);
|
|
}
|
|
}
|
|
|
|
public override void OnGameSwitch(double beat)
|
|
{
|
|
foreach(var entity in GameManager.instance.Beatmap.Entities)
|
|
{
|
|
if(entity.beat > beat) //the list is sorted based on the beat of the entity, so this should work fine.
|
|
{
|
|
break;
|
|
}
|
|
if(entity.datamodel != "spaceSoccer/ball dispense" || entity.beat + entity.length <= beat) //check for dispenses that happen right before the switch
|
|
{
|
|
continue;
|
|
}
|
|
bool isOnGameSwitchBeat = entity.beat == beat;
|
|
Dispense(entity.beat, isOnGameSwitchBeat && !entity["toggle"], false, isOnGameSwitchBeat && entity["down"], entity["auto"], entity["interval"]);
|
|
break;
|
|
}
|
|
|
|
PersistColor(beat);
|
|
AddStopEvents(beat);
|
|
}
|
|
|
|
public SuperCurveObject.Path GetPath(string name)
|
|
{
|
|
foreach (SuperCurveObject.Path path in ballPaths)
|
|
{
|
|
if (path.name == name)
|
|
{
|
|
return path;
|
|
}
|
|
}
|
|
return default(SuperCurveObject.Path);
|
|
}
|
|
|
|
#region VisualInterpolation
|
|
|
|
public void UpdateScrollSpeed(float scrollSpeedX, float scrollSpeedY)
|
|
{
|
|
xScrollMultiplier = scrollSpeedX;
|
|
yScrollMultiplier = scrollSpeedY;
|
|
}
|
|
|
|
public void EaseSpaceKickersPositions(double beat, float length, int ease, float xDistance, float yDistance, float zDistance)
|
|
{
|
|
easeBeat = (float)beat;
|
|
easeLength = length;
|
|
lastEase = (EasingFunction.Ease)ease;
|
|
lastPos = currentPos;
|
|
currentPos = new Vector3(xDistance, yDistance, zDistance);
|
|
}
|
|
|
|
public void UpdateKickersPositions(float xDistance, float yDistance, float zDistance)
|
|
{
|
|
for (int i = 1; i < kickers.Count; i++)
|
|
{
|
|
kickers[i].transform.parent.position = new Vector3(3.384f - xDistance * i, -yDistance * i, zDistance * i);
|
|
CircularMotion circularMotion = kickers[i].GetComponent<CircularMotion>();
|
|
circularMotion.width = 0.85f - Mathf.Pow(zDistance * 10f, -1f);
|
|
circularMotion.height = 0.5f - Mathf.Pow(zDistance * 10f, -1f);
|
|
}
|
|
}
|
|
|
|
public void MovePlayerKicker(double beat, float length, int ease, float xPos, float yPos, float zPos, int soundToPlay, int preset)
|
|
{
|
|
switch (preset)
|
|
{
|
|
case (int)PlayerPresets.Custom:
|
|
break;
|
|
case (int)PlayerPresets.LaunchStart:
|
|
lastEaseP = EasingFunction.Ease.EaseInOutCubic;
|
|
xPos = -6;
|
|
yPos = 15;
|
|
zPos = 0;
|
|
soundToPlay = (int)LaunchSoundToPlay.LaunchStart;
|
|
break;
|
|
case (int)PlayerPresets.LaunchEnd:
|
|
lastEaseP = EasingFunction.Ease.EaseInOutQuint;
|
|
xPos = -4;
|
|
yPos = 15;
|
|
zPos = 0;
|
|
soundToPlay = (int)LaunchSoundToPlay.LaunchEnd;
|
|
break;
|
|
}
|
|
easeBeatP = (float)beat;
|
|
easeLengthP = length;
|
|
lastEaseP = (EasingFunction.Ease)ease;
|
|
lastPosP = currentPosP;
|
|
currentPosP = new Vector3(-xPos, yPos, -zPos);
|
|
switch (soundToPlay)
|
|
{
|
|
case (int)LaunchSoundToPlay.None:
|
|
break;
|
|
case (int)LaunchSoundToPlay.LaunchStart:
|
|
SoundByte.PlayOneShotGame("spaceSoccer/jet1");
|
|
break;
|
|
case (int)LaunchSoundToPlay.LaunchEnd:
|
|
SoundByte.PlayOneShotGame("spaceSoccer/jet2");
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void UpdateSpaceKickers(int amount, float xDistance = 1.75f, float yDistance = 0.25f, float zDistance = 0.75f, bool overrideEasing = true)
|
|
{
|
|
for (int i = kickers.Count - 1; i > 0; i--)
|
|
{
|
|
if (i >= amount)
|
|
{
|
|
Kicker kickerToDestroy = kickers[i];
|
|
kickers.Remove(kickerToDestroy);
|
|
Destroy(kickerToDestroy.transform.parent.gameObject);
|
|
}
|
|
}
|
|
if (overrideEasing)
|
|
{
|
|
UpdateKickersPositions(xDistance, yDistance, zDistance);
|
|
currentPos = new Vector3(xDistance, yDistance, zDistance);
|
|
}
|
|
|
|
for (int i = kickers.Count; i < amount; i++)
|
|
{
|
|
Transform kickerHolder = Instantiate(kickerPrefab, transform).transform;
|
|
kickerHolder.transform.position = new Vector3(kickerHolder.transform.position.x - xDistance * i, kickerHolder.transform.position.y - yDistance * i, kickerHolder.transform.position.z + zDistance * i);
|
|
Kicker spawnedKicker = kickerHolder.GetChild(0).GetComponent<Kicker>();
|
|
CircularMotion circularMotion = spawnedKicker.GetComponent<CircularMotion>();
|
|
circularMotion.width = 0.85f - Mathf.Pow(zDistance * 10f, -1f);
|
|
circularMotion.height = 0.5f - Mathf.Pow(zDistance * 10f, -1f);
|
|
circularMotion.timeOffset = kickers[0].GetComponent<CircularMotion>().timeCounter;
|
|
if (0 > zDistance)
|
|
{
|
|
spawnedKicker.GetComponent<SortingGroup>().sortingOrder = i;
|
|
}
|
|
else
|
|
{
|
|
spawnedKicker.GetComponent<SortingGroup>().sortingOrder = -i;
|
|
}
|
|
|
|
kickers.Add(spawnedKicker);
|
|
kickerHolder.gameObject.SetActive(true);
|
|
}
|
|
if (ballDispensed) Dispense(lastDispensedBeat, false, true, false, false);
|
|
}
|
|
|
|
#endregion
|
|
|
|
public void Dispense(double beat, bool playSound = true, bool ignorePlayer = false, bool playDown = false, bool autoDispense = true, int autoInterval = 2)
|
|
{
|
|
DispenseExec(beat, playSound, ignorePlayer, playDown);
|
|
|
|
if (!autoDispense) return;
|
|
|
|
DispenseRecursion(beat + 2, autoInterval);
|
|
}
|
|
|
|
private void DispenseRecursion(double beat, int interval)
|
|
{
|
|
double dispenseBeat = beat + interval;
|
|
if (_stopBeats.Exists(x => dispenseBeat + 2 >= x)) return;
|
|
BeatAction.New(this, new()
|
|
{
|
|
new(dispenseBeat, delegate
|
|
{
|
|
if (!_highKickToeBeats.Exists(x => dispenseBeat + 2 > x && dispenseBeat + 2 < x + 3)) DispenseExec(dispenseBeat);
|
|
DispenseRecursion(dispenseBeat + 2, interval);
|
|
})
|
|
});
|
|
}
|
|
|
|
private void DispenseExec(double beat, bool playSound = true, bool ignorePlayer = false, bool playDown = false)
|
|
{
|
|
if (!ballDispensed) lastDispensedBeat = beat;
|
|
ballDispensed = true;
|
|
for (int i = 0; i < kickers.Count; i++)
|
|
{
|
|
Kicker kicker = kickers[i];
|
|
kicker.player = i == 0;
|
|
if (kicker.ball != null || (ignorePlayer && kicker.player)) continue;
|
|
|
|
GameObject ball = Instantiate(ballRef, kicker.transform.GetChild(0));
|
|
ball.SetActive(true);
|
|
Ball ball_ = ball.GetComponent<Ball>();
|
|
ball_.Init(kicker, (float)beat);
|
|
if (kicker.player && playSound)
|
|
{
|
|
DispenseSound((float)beat, playDown);
|
|
}
|
|
kicker.DispenseBall((float)beat);
|
|
|
|
kicker.canKick = true;
|
|
}
|
|
}
|
|
|
|
public static void DispenseSound(double beat, bool playDown)
|
|
{
|
|
if (playDown) SoundByte.PlayOneShot("games/spaceSoccer/down", beat);
|
|
MultiSound.Play(new MultiSound.Sound[]
|
|
{
|
|
new MultiSound.Sound("spaceSoccer/dispenseNoise", beat),
|
|
new MultiSound.Sound("spaceSoccer/dispenseTumble1", beat),
|
|
new MultiSound.Sound("spaceSoccer/dispenseTumble2", beat + 0.25f),
|
|
new MultiSound.Sound("spaceSoccer/dispenseTumble2B",beat + 0.25f),
|
|
new MultiSound.Sound("spaceSoccer/dispenseTumble3", beat + 0.75f),
|
|
new MultiSound.Sound("spaceSoccer/dispenseTumble4", beat + 1f),
|
|
new MultiSound.Sound("spaceSoccer/dispenseTumble5", beat + 1.25f),
|
|
new MultiSound.Sound("spaceSoccer/dispenseTumble6", beat + 1.5f),
|
|
new MultiSound.Sound("spaceSoccer/dispenseTumble6B",beat + 1.75f),
|
|
}, forcePlay:true);
|
|
}
|
|
|
|
private void AddStopEvents(double beat)
|
|
{
|
|
var allStopEvents = EventCaller.GetAllInGameManagerList("spaceSoccer", new string[] { "stopBall" }).FindAll(x => x.beat >= beat);
|
|
foreach (var e in allStopEvents)
|
|
{
|
|
_stopBeats.Add(e.beat);
|
|
}
|
|
}
|
|
|
|
private double colorStartBeat = -1;
|
|
private float colorLength = 0f;
|
|
private Color colorStart; //obviously put to the default color of the game
|
|
private Color colorEnd;
|
|
private Color colorStartDot = Color.white; //obviously put to the default color of the game
|
|
private Color colorEndDot = Color.white;
|
|
private Util.EasingFunction.Ease colorEase; //putting Util in case this game is using jukebox
|
|
|
|
//call this in update
|
|
private void BackgroundColorUpdate()
|
|
{
|
|
float normalizedBeat = Mathf.Clamp01(Conductor.instance.GetPositionFromBeat(colorStartBeat, colorLength));
|
|
|
|
var func = Util.EasingFunction.GetEasingFunction(colorEase);
|
|
|
|
float newR = func(colorStart.r, colorEnd.r, normalizedBeat);
|
|
float newG = func(colorStart.g, colorEnd.g, normalizedBeat);
|
|
float newB = func(colorStart.b, colorEnd.b, normalizedBeat);
|
|
|
|
bg.color = new Color(newR, newG, newB);
|
|
|
|
float newRDot = func(colorStartDot.r, colorEndDot.r, normalizedBeat);
|
|
float newGDot = func(colorStartDot.g, colorEndDot.g, normalizedBeat);
|
|
float newBDot = func(colorStartDot.b, colorEndDot.b, normalizedBeat);
|
|
|
|
bgImage.color = new Color(newRDot, newGDot, newBDot);
|
|
}
|
|
|
|
public void BackgroundColor(double beat, float length, Color colorStartSet, Color colorEndSet, Color colorStartDotSet, Color colorEndDotSet, int ease)
|
|
{
|
|
colorStartBeat = beat;
|
|
colorLength = length;
|
|
colorStart = colorStartSet;
|
|
colorEnd = colorEndSet;
|
|
colorStartDot = colorStartDotSet;
|
|
colorEndDot = colorEndDotSet;
|
|
colorEase = (Util.EasingFunction.Ease)ease;
|
|
}
|
|
|
|
//call this in OnPlay(double beat) and OnGameSwitch(double beat)
|
|
private void PersistColor(double beat)
|
|
{
|
|
var allEventsBeforeBeat = EventCaller.GetAllInGameManagerList("spaceSoccer", new string[] { "changeBG" }).FindAll(x => x.beat < beat);
|
|
if (allEventsBeforeBeat.Count > 0)
|
|
{
|
|
allEventsBeforeBeat.Sort((x, y) => x.beat.CompareTo(y.beat)); //just in case
|
|
var lastEvent = allEventsBeforeBeat[^1];
|
|
BackgroundColor(lastEvent.beat, lastEvent.length, lastEvent["start"], lastEvent["end"], lastEvent["startDots"], lastEvent["endDots"], lastEvent["ease"]);
|
|
}
|
|
}
|
|
|
|
public override void OnPlay(double beat)
|
|
{
|
|
PersistColor(beat);
|
|
AddStopEvents(beat);
|
|
}
|
|
}
|
|
} |