mirror of
https://github.com/RHeavenStudioPlus/HeavenStudioPlus.git
synced 2024-11-29 21:13:07 +00:00
263855830f
* fix spelling and grammar errors in release 1 games * fix nightly game text
1495 lines
No EOL
66 KiB
C#
1495 lines
No EOL
66 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
using HeavenStudio.Util;
|
|
using HeavenStudio.InputSystem;
|
|
|
|
using Jukebox;
|
|
|
|
namespace HeavenStudio.Games.Loaders
|
|
{
|
|
using static Minigames;
|
|
public static class NtrFreezeFrameLoader
|
|
{
|
|
public static Minigame AddGame(EventCaller eventCaller)
|
|
{
|
|
return new Minigame("freezeFrame", "Freeze Frame", "8b93b4", false, false, new List<GameAction>()
|
|
{
|
|
new GameAction("bop", "Bop")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.SetBopping(e.beat, e.length, e["bop"], e["autoBop"], e["blink"], e["autoBlink"]); },
|
|
defaultLength = 1f,
|
|
resizable = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("bop", false, "Bop", "Set the type of photo to use."),
|
|
new Param("autoBop", true, "Bop (Auto)", "Set the type of photo to use."),
|
|
new Param("blink", false, "Crosshair Blink", "Set the type of photo to use."),
|
|
new Param("autoBlink", true, "Crosshair Blink (Auto)", "Set the type of photo to use."),
|
|
}
|
|
},
|
|
// cues
|
|
new GameAction("slowCar", "Slow Car")
|
|
{
|
|
function = delegate
|
|
{
|
|
var e = eventCaller.currentEntity;
|
|
FreezeFrame.SlowCarCue(e.beat, e["variant"], e["mute"], e["clear"]);
|
|
},
|
|
inactiveFunction = delegate
|
|
{
|
|
var e = eventCaller.currentEntity;
|
|
if (!(bool)e["mute"]) FreezeFrame.SlowCarSFX();
|
|
},
|
|
defaultLength = 3f,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("variant", FreezeFrame.PhotoType.Random, "Photo Variant", "Set the type of photo to use."),
|
|
new Param("mute", false, "Mute", "Mute the sound of the cue."),
|
|
new Param("clear", false, "Clear Previous Photos", "Dispose of all the photos taken before this one."),
|
|
new Param("autoShowPhotos", true, "Auto Show Photos", "Automagically show the photos after they're taken.", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, _) => (bool)x, new string[] { "gradeType", "audience" })
|
|
}),
|
|
new Param("gradeType", FreezeFrame.GradeType.Symbols, "Rating Type", "Choose whether to use the English or Japanese variant of the grading screen."),
|
|
new Param("audience", true, "Crowd Cheer", "Set whether or not the audience should cheer when the photos are shown."),
|
|
}
|
|
},
|
|
new GameAction("fastCar", "Fast Car")
|
|
{
|
|
function = delegate
|
|
{
|
|
var e = eventCaller.currentEntity;
|
|
FreezeFrame.FastCarCue(e.beat, e["variant"], e["mute"], e["clear"]);
|
|
},
|
|
inactiveFunction = delegate
|
|
{
|
|
var e = eventCaller.currentEntity;
|
|
if (!(bool)e["mute"]) FreezeFrame.FastCarSFX();
|
|
},
|
|
defaultLength = 3f,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("variant", FreezeFrame.PhotoType.Random, "Photo Variant", "Set the type of photo to use."),
|
|
new Param("mute", false, "Mute", "Mute the sound of the cue."),
|
|
new Param("clear", false, "Clear Previous Photos", "Dispose of all the photos taken before this one."),
|
|
new Param("autoShowPhotos", true, "Auto Show Photos", "Automagically show the photos after they're taken.", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, _) => (bool)x, new string[] { "gradeType", "audience" })
|
|
}),
|
|
new Param("gradeType", FreezeFrame.GradeType.Symbols, "Rating Type", "Choose whether to use the English or Japanese variant of the grading screen."),
|
|
new Param("audience", true, "Crowd Cheer", "Set whether or not the audience should cheer when the photos are shown."),
|
|
}
|
|
},
|
|
new GameAction("showPhotos", "Show Photos")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.ShowPhotos(e.beat, e.length, e["gradeType"], e["audience"], e["clearCache"]); },
|
|
defaultLength = 1,
|
|
resizable = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("gradeType", FreezeFrame.GradeType.Symbols, "Rating Type", "Choose whether to use the English or Japanese variant of the grading screen."),
|
|
new Param("audience", true, "Crowd Cheer", "Set whether or not the audience should cheer when the photos are shown."),
|
|
new Param("clearCache", true, "Clear Photos", "Clears the photo cache after the photos are shown."),
|
|
}
|
|
},
|
|
// distractions
|
|
new GameAction("spawnPerson", "Spawn Walker")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.SummonWalker(e); },
|
|
defaultLength = 4f,
|
|
resizable = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("personType", FreezeFrame.PersonType.Dude1, "Walker Type", "Choose the type of walker to spawn."),
|
|
new Param("direction", FreezeFrame.PersonDirection.Random, "Direction", "Choose the direction from which to spawn the walker."),
|
|
new Param("layer", new EntityTypes.Integer(-10, 10, 0), "Layer", "The layer on which this walker should spawn (higher numbers are shown in front)."),
|
|
}
|
|
},
|
|
new GameAction("spawnCrowd", "Show/Hide Crowd")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.ToggleCrowd(e.beat, e["crowd"], e["customCrowd"], e["crowdFarLeft"], e["crowdLeft"], e["crowdRight"], e["crowdFarRight"], e["billboard"]); },
|
|
defaultLength = 0.5f,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("crowd", true, "Show Crowd", "Choose whether to spawn or despawn the crowd."),
|
|
new Param("customCrowd", false, "Custom Crowd", "Select to customize the crowd.", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, _) => (bool)x, new string[] { "crowdFarLeft", "crowdLeft", "crowdRight", "crowdFarRight" })
|
|
}),
|
|
new Param("crowdFarLeft" , FreezeFrame.CustomCrowdType.PinkDancers, "Far Left" , "Select the graphic to display on the far left."),
|
|
new Param("crowdLeft" , FreezeFrame.CustomCrowdType.YellowDancers, "Center Left" , "Select the graphic to display on the near left."),
|
|
new Param("crowdRight" , FreezeFrame.CustomCrowdType.TealDancers, "Center Right", "Select the graphic to display on the near right."),
|
|
new Param("crowdFarRight", FreezeFrame.CustomCrowdType.PinkDancers, "Far Right" , "Select the graphic to display on the far right."),
|
|
new Param("billboard", false, "Show Billboard", "Choose whether to show or hide the billboards."),
|
|
}
|
|
},
|
|
new GameAction("introSign", "Intro Sign")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.DoIntroSign(e.beat, e.length, e["enter"], e["ease"]); },
|
|
defaultLength = 4f,
|
|
resizable = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("enter", true, "Enter", "Choose whether the sign should enter or exit."),
|
|
new Param("ease", Util.EasingFunction.Ease.Linear, "Ease", "Set the easing of the action."),
|
|
}
|
|
},
|
|
new GameAction("introLights", "Intro Lights")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.IntroLightsAnim(e.beat, e.length, e["lightsOn"]); FreezeFrame.IntroLightsSound(e.beat, e.length, e["lightsOn"]); },
|
|
inactiveFunction = delegate { var e = eventCaller.currentEntity; FreezeFrame.IntroLightsSound(e.beat, e.length, e["lightsOn"]); },
|
|
defaultLength = 1f,
|
|
resizable = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("lightsOn", true, "Turn Lights On", "Choose whether to turn the lights on or off."),
|
|
}
|
|
},
|
|
// settings
|
|
new GameAction("toggleOverlay", "Toggle Overlay")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.ToggleOverlay(e.beat, e["showOverlay"], e["showCameraMan"], e["followCamera"]); },
|
|
defaultLength = 0.5f,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("showOverlay", true, "Show Overlay", "Choose whether or not to show the camera overlay."),
|
|
new Param("showCameraMan", true, "Show T.J.", "Choose whether or not to show the box containing T.J. Snapper."),
|
|
new Param("followCamera", true, "Follow Camera", "Choose whether or not the overlay should follow the camera."),
|
|
}
|
|
},
|
|
new GameAction("neoMoveCameraMan", "Move T.J.")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.SetMoveCameraMan(e); },
|
|
defaultLength = 1f,
|
|
resizable = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("doMove", false, "Move", "Select this option if you want to move T.J.", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, _) => (bool)x, new string[] { "endMoveX", "endMoveY" } ),
|
|
new Param.CollapseParam((x, e) => (bool)x && (Util.EasingFunction.Ease)e["ease"] != Util.EasingFunction.Ease.Instant, new string[] { "startMoveX", "startMoveY" }),
|
|
new Param.CollapseParam((_, e) => (bool)e["doMove"] || (bool)e["doRotate"] || (bool)e["doScale"], new string[] { "ease" })
|
|
}),
|
|
new Param("startMoveX", new EntityTypes.Float(-20f, 20f, 0f), "Start X", "Set the X position from which to move."),
|
|
new Param("startMoveY", new EntityTypes.Float(-20f, 20f, 0f), "Start Y", "Set the Y position from which to move."),
|
|
new Param("endMoveX", new EntityTypes.Float(-20f, 20f, 0f), "End X", "Set the X position to move to."),
|
|
new Param("endMoveY", new EntityTypes.Float(-20f, 20f, 0f), "End Y", "Set the Y position to move to."),
|
|
new Param("doRotate", false, "Rotate", "Select this option if you want to rotate T.J.", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, _) => (bool)x, new string[] { "endRotDegrees" } ),
|
|
new Param.CollapseParam((x, e) => (bool)x && (Util.EasingFunction.Ease)e["ease"] != Util.EasingFunction.Ease.Instant, new string[] { "startRotDegrees" }),
|
|
new Param.CollapseParam((_, e) => (bool)e["doMove"] || (bool)e["doRotate"] || (bool)e["doScale"], new string[] { "ease" })
|
|
}),
|
|
new Param("startRotDegrees", new EntityTypes.Float(-360f, 360f, 0f), "Start Rotation", "Set the number of degrees at which to begin rotating."),
|
|
new Param("endRotDegrees", new EntityTypes.Float(-360f, 360f, 0f), "End Rotation", "Set the number of degrees at which to finish rotating."),
|
|
new Param("doScale", false, "Scale", "Select this option if you want to change T.J.'s scale.", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, _) => (bool)x, new string[] { "endScaleX", "endScaleY" } ),
|
|
new Param.CollapseParam((x, e) => (bool)x && (Util.EasingFunction.Ease)e["ease"] != Util.EasingFunction.Ease.Instant, new string[] { "startScaleX", "startScaleY" }),
|
|
new Param.CollapseParam((_, e) => (bool)e["doMove"] || (bool)e["doRotate"] || (bool)e["doScale"], new string[] { "ease" })
|
|
}),
|
|
new Param("startScaleX", new EntityTypes.Float(-5f, 5f, 1f), "Start Scale X", "Set the desired scale on the X axis at which to start."),
|
|
new Param("startScaleY", new EntityTypes.Float(-5f, 5f, 1f), "Start Scale Y", "Set the desired scale on the Y axis at which to start."),
|
|
new Param("endScaleX", new EntityTypes.Float(-5f, 5f, 1f), "End Scale X", "Set the desired scale on the X axis at which to end."),
|
|
new Param("endScaleY", new EntityTypes.Float(-5f, 5f, 1f), "End Scale Y", "Set the desired scale on the Y axis at which to end."),
|
|
new Param("ease", Util.EasingFunction.Ease.Linear, "Ease", "Set the easing for the action.", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, e) => (Util.EasingFunction.Ease)x != Util.EasingFunction.Ease.Instant && (bool)e["doMove"], new string[] { "startMoveX", "startMoveY" }),
|
|
new Param.CollapseParam((x, e) => (Util.EasingFunction.Ease)x != Util.EasingFunction.Ease.Instant && (bool)e["doRotate"], new string[] { "startRotDegrees" }),
|
|
new Param.CollapseParam((x, e) => (Util.EasingFunction.Ease)x != Util.EasingFunction.Ease.Instant && (bool)e["doScale"], new string[] { "startScaleX", "startScaleY" }),
|
|
})
|
|
}
|
|
},
|
|
|
|
// DEPRECATED ACTIONS
|
|
// DEPRECATED ACTIONS
|
|
// DEPRECATED ACTIONS
|
|
|
|
new GameAction("clearPhotos", "Clear Photo Cache (DEPRECATED)")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.ClearPhotos(); },
|
|
inactiveFunction = delegate { var e = eventCaller.currentEntity; FreezeFrame.ClearPhotos(); },
|
|
defaultLength = 0.5f,
|
|
parameters = new List<Param>()
|
|
{
|
|
},
|
|
hidden = true
|
|
},
|
|
new GameAction("moveCameraMan", "Move T.J. (DEPRECATED)")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.SetMoveCameraMan_OLD(e.beat, e.length, e["startPosX"], e["startPosY"], e["endPosX"], e["endPosY"], e["ease"]); },
|
|
defaultLength = 1f,
|
|
resizable = true,
|
|
hidden = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("startPosX", new EntityTypes.Float(-5.0f, 5.0f, 0.0f), "Start X Position", "X position at which to start."),
|
|
new Param("startPosY", new EntityTypes.Float(-5.0f, 5.0f, 0.0f), "Start Y Position", "Y position at which to start."),
|
|
new Param("endPosX" , new EntityTypes.Float(-5.0f, 5.0f, 0.0f), "End X Position" , "X position at which to end."),
|
|
new Param("endPosY" , new EntityTypes.Float(-5.0f, 5.0f, 0.0f), "End Y Position" , "Y position at which to end."),
|
|
new Param("ease", Util.EasingFunction.Ease.Linear, "Ease", "Set the easing of the action.", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, _) => (Util.EasingFunction.Ease)x != Util.EasingFunction.Ease.Instant, new string[] { "startPosX", "startPosY" })
|
|
}),
|
|
//new Param("flipX", false, "Flip", "Set whether or not to flip T.J. horizontally."),
|
|
}
|
|
},
|
|
new GameAction("rotateCameraMan", "Rotate T.J. (DEPRECATED)")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.SetRotateCameraMan_OLD(e.beat, e.length, e["startRot"], e["endRot"], e["ease"]); },
|
|
defaultLength = 1f,
|
|
resizable = true,
|
|
hidden = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("startRot", new EntityTypes.Float(-360.0f, 360.0f, 0.0f), "Start Rotation", "Rotation degrees at which to start."),
|
|
new Param("endRot" , new EntityTypes.Float(-360.0f, 360.0f, 0.0f), "End Rotation" , "Rotation degrees position at which to end."),
|
|
new Param("ease", Util.EasingFunction.Ease.Linear, "Ease", "Set the easing of the action.", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, _) => (Util.EasingFunction.Ease)x != Util.EasingFunction.Ease.Instant, new string[] { "startRot" })
|
|
}),
|
|
}
|
|
},
|
|
new GameAction("scaleCameraMan", "Scale T.J. (DEPRECATED)")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; FreezeFrame.SetScaleCameraMan_OLD(e.beat, e.length, e["startSizeX"], e["startSizeY"], e["endSizeX"], e["endSizeY"], e["ease"]); },
|
|
defaultLength = 1f,
|
|
resizable = true,
|
|
hidden = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("startSizeX", new EntityTypes.Float(-5.0f, 5.0f, 1.0f), "Start Scale X", "Horizontal scale at which to start."),
|
|
new Param("startSizeY", new EntityTypes.Float(-5.0f, 5.0f, 1.0f), "Start Scale Y", "Vertical scale at which to start."),
|
|
new Param("endSizeX", new EntityTypes.Float(-5.0f, 5.0f, 1.0f), "End Scale X" , "Horizontal scale at which to end."),
|
|
new Param("endSizeY", new EntityTypes.Float(-5.0f, 5.0f, 1.0f), "End Scale Y" , "Vertical scale at which to end."),
|
|
new Param("ease", Util.EasingFunction.Ease.Linear, "Ease", "Set the easing of the action.", new List<Param.CollapseParam>()
|
|
{
|
|
new Param.CollapseParam((x, _) => (Util.EasingFunction.Ease)x != Util.EasingFunction.Ease.Instant, new string[] { "startSizeX", "startSizeY" })
|
|
}),
|
|
}
|
|
},
|
|
},
|
|
new List<string>() { "ntr", "normal" },
|
|
"ntrcameraman", "en",
|
|
chronologicalSortKey: 13
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace HeavenStudio.Games
|
|
{
|
|
using HeavenStudio.Common;
|
|
using Scripts_FreezeFrame;
|
|
using UnityEngine.Rendering;
|
|
|
|
public class FreezeFrame : Minigame
|
|
{
|
|
/*
|
|
BIG LIST OF TODOS
|
|
- finish sounds
|
|
- make pitching and panning work
|
|
- wait for upscale
|
|
- make particles random sprites
|
|
*/
|
|
|
|
public static FreezeFrame Instance
|
|
{
|
|
get
|
|
{
|
|
if (GameManager.instance.minigame is FreezeFrame instance)
|
|
return instance;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
[SerializeField] Animator CameraMan;
|
|
[SerializeField] Photograph[] Photographs;
|
|
[SerializeField] Photograph Photograph1;
|
|
[SerializeField] Photograph Photograph2;
|
|
[SerializeField] Photograph Photograph3;
|
|
[SerializeField] Animator Results;
|
|
|
|
[SerializeField] Animator IntroSign;
|
|
|
|
[SerializeField] GameObject Overlay;
|
|
[SerializeField] GameObject Crosshair;
|
|
[SerializeField] Animator Shutter;
|
|
[SerializeField] GameObject DimRect;
|
|
|
|
[SerializeField] StickyCanvas StickyLayer;
|
|
|
|
[SerializeField] Transform FarCarSpawn;
|
|
[SerializeField] GameObject FarCarPrefab;
|
|
|
|
[SerializeField] Transform NearCarSpawn;
|
|
[SerializeField] GameObject NearCarPrefab;
|
|
|
|
[SerializeField] Transform WalkerSpawn;
|
|
[SerializeField] GameObject WalkerPrefab;
|
|
|
|
[SerializeField] Animator Crowd;
|
|
[SerializeField] SpriteRenderer CrowdFarLeft;
|
|
[SerializeField] SpriteRenderer CrowdLeft;
|
|
[SerializeField] SpriteRenderer CrowdRight;
|
|
[SerializeField] SpriteRenderer CrowdFarRight;
|
|
[SerializeField] Sprite[] CrowdSprites;
|
|
[SerializeField] GameObject Billboards;
|
|
|
|
public bool DoAutoBop { get; set; } = true;
|
|
public bool DoAutoCrosshairBlink { get; set; } = true;
|
|
public bool ShowOverlay { get; set; } = true;
|
|
public bool ShowCameraMan { get; set; } = true;
|
|
public bool OverlayFollowCamera { get; set; } = true;
|
|
public bool ShowCrowd { get; set; } = false;
|
|
public bool ShowBillboard { get; set; } = false;
|
|
|
|
public List<WalkerArgs> Walkers { get; set; } = new();
|
|
|
|
public bool SignIsMoving { get; set; } = false;
|
|
public SignMoveArgs CurrentSignArgs { get; set; }
|
|
|
|
public static Vector3 CameraManStartPos { get; private set; }
|
|
public bool CameraManMoving { get; set; } = false;
|
|
public CameraManMoveArgs CurrentCameraManMoveArgs;
|
|
public bool CameraManRotating { get; set; } = false;
|
|
public CameraManRotateArgs CurrentCameraManRotateArgs;
|
|
public bool CameraManScaling { get; set; } = false;
|
|
public CameraManScaleArgs CurrentCameraManScaleArgs;
|
|
|
|
public static List<PhotoArgs> PhotoList = new();
|
|
public Dictionary<PlayerActionEvent, PhotoArgs> EventArgs = new();
|
|
public bool IsShowingPhotos { get; set; } = false;
|
|
|
|
public static Dictionary<RiqEntity, PersonDirection> WalkerDirections = new();
|
|
|
|
// UNITY BUILTIN METHODS
|
|
void Start()
|
|
{
|
|
if (conductor != null && !conductor.isPlaying && !conductor.isPaused)
|
|
{
|
|
ClearPhotos();
|
|
}
|
|
CameraManStartPos = CameraMan.transform.localPosition;
|
|
}
|
|
void Update()
|
|
{
|
|
if (conductor != null && !conductor.isPlaying && !conductor.isPaused)
|
|
{
|
|
CameraMan.Play("Idle");
|
|
IsShowingPhotos = false;
|
|
}
|
|
|
|
if (PlayerInput.GetIsAction(InputAction_BasicPress) && !IsExpectingInputNow(InputAction_BasicPress) && !IsShowingPhotos)
|
|
{
|
|
CameraFlash();
|
|
//ScoreMiss();
|
|
}
|
|
|
|
// sign
|
|
if (SignIsMoving)
|
|
{
|
|
float normalizedBeat = conductor.GetPositionFromBeat(CurrentSignArgs.StartTime, CurrentSignArgs.Length);
|
|
Util.EasingFunction.Function func = Util.EasingFunction.GetEasingFunction(CurrentSignArgs.Ease);
|
|
float newPos = func(0f, 1f, normalizedBeat);
|
|
IntroSign.DoNormalizedAnimation(CurrentSignArgs.AnimName, newPos, animLayer: 0);
|
|
if (normalizedBeat >= 1f)
|
|
SignIsMoving = false;
|
|
}
|
|
|
|
// move TJ
|
|
if (CameraManMoving)
|
|
{
|
|
float normalizedBeat = conductor.GetPositionFromBeat(CurrentCameraManMoveArgs.StartBeat, CurrentCameraManMoveArgs.Length);
|
|
Util.EasingFunction.Function func = Util.EasingFunction.GetEasingFunction(CurrentCameraManMoveArgs.Ease);
|
|
float newPos = func(0f, 1f, normalizedBeat);
|
|
|
|
Vector3 diff = CurrentCameraManMoveArgs.EndPos - CurrentCameraManMoveArgs.StartPos;
|
|
Vector3 diffPos = newPos * diff;
|
|
CameraMan.transform.localPosition = CurrentCameraManMoveArgs.StartPos + diffPos;
|
|
|
|
if (normalizedBeat >= 1f)
|
|
{
|
|
CameraMan.transform.localPosition = CurrentCameraManMoveArgs.EndPos;
|
|
CameraManMoving = false;
|
|
}
|
|
}
|
|
if (CameraManRotating)
|
|
{
|
|
float normalizedBeat = conductor.GetPositionFromBeat(CurrentCameraManRotateArgs.StartBeat, CurrentCameraManRotateArgs.Length);
|
|
Util.EasingFunction.Function func = Util.EasingFunction.GetEasingFunction(CurrentCameraManRotateArgs.Ease);
|
|
float newPos = func(0f, 1f, normalizedBeat);
|
|
|
|
float diff = CurrentCameraManRotateArgs.EndRot - CurrentCameraManRotateArgs.StartRot;
|
|
float diffPos = newPos * diff;
|
|
CameraMan.transform.localEulerAngles = new Vector3(0, 0, CurrentCameraManRotateArgs.StartRot + diffPos);
|
|
|
|
if (normalizedBeat >= 1f)
|
|
{
|
|
CameraMan.transform.localEulerAngles = new Vector3(0, 0, CurrentCameraManRotateArgs.EndRot);
|
|
CameraManRotating = false;
|
|
}
|
|
}
|
|
if (CameraManScaling)
|
|
{
|
|
float normalizedBeat = conductor.GetPositionFromBeat(CurrentCameraManScaleArgs.StartBeat, CurrentCameraManScaleArgs.Length);
|
|
Util.EasingFunction.Function func = Util.EasingFunction.GetEasingFunction(CurrentCameraManScaleArgs.Ease);
|
|
float newPos = func(0f, 1f, normalizedBeat);
|
|
|
|
Vector3 diff = CurrentCameraManScaleArgs.EndScale - CurrentCameraManScaleArgs.StartScale;
|
|
Vector3 diffPos = newPos * diff;
|
|
CameraMan.transform.localScale = CurrentCameraManScaleArgs.StartScale + diffPos;
|
|
|
|
if (normalizedBeat >= 1f)
|
|
{
|
|
CameraMan.transform.localScale = CurrentCameraManScaleArgs.EndScale;
|
|
CameraManScaling = false;
|
|
}
|
|
}
|
|
|
|
// boppers
|
|
if (Walkers.Count > 0)
|
|
{
|
|
Walkers.RemoveAll(w => w.Walker == null || w.Walker.gameObject == null);
|
|
foreach (WalkerArgs args in Walkers)
|
|
{
|
|
float normalizedBeat = conductor.GetPositionFromBeat(args.StartTime, args.Length);
|
|
args.Walker.DoNormalizedAnimation(args.AnimName, normalizedBeat, animLayer: 1);
|
|
if (normalizedBeat >= 1f)
|
|
Destroy(args.Walker.gameObject);
|
|
}
|
|
}
|
|
|
|
// car animations (deprecated)
|
|
/*if (QueuedCars.Count > 0)
|
|
{
|
|
var beat = conductor.songPositionInBeats;
|
|
if (beat >= 0)
|
|
{
|
|
QueuedCars.RemoveAll(e => e.Beat < beat - 5); // could probably be smaller. 5 just to be safe
|
|
foreach (SpawnCarArgs args in QueuedCars.Where(e => e.Beat <= beat))
|
|
{
|
|
SpawnCar(args);
|
|
}
|
|
QueuedCars.RemoveAll(e => e.Beat <= beat);
|
|
}
|
|
}*/
|
|
|
|
if (!IsShowingPhotos)
|
|
Instance.Overlay.SetActive(ShowOverlay);
|
|
|
|
Billboards.SetActive(ShowBillboard);
|
|
Instance.CameraMan.gameObject.SetActive(ShowCameraMan);
|
|
StickyLayer.Sticky = OverlayFollowCamera;
|
|
}
|
|
private void OnDestroy()
|
|
{
|
|
foreach (var evt in scheduledInputs)
|
|
{
|
|
evt.Disable();
|
|
}
|
|
//if (PhotoList.Count > 0) PhotoList.Clear();
|
|
}
|
|
|
|
// MINIGAME METHODS
|
|
public override void OnBeatPulse(double beat)
|
|
{
|
|
if (BeatIsInBopRegion(beat))
|
|
{
|
|
if (DoAutoBop && !IsShowingPhotos)
|
|
Bop();
|
|
|
|
if (DoAutoCrosshairBlink)
|
|
CrosshairBlink();
|
|
}
|
|
}
|
|
public override void OnPlay(double beat)
|
|
{
|
|
if (PhotoList.Count > 0) PhotoList.Clear();
|
|
OnGameSwitch(beat);
|
|
}
|
|
public override void OnGameSwitch(double beat)
|
|
{
|
|
Instance.Overlay.SetActive(ShowOverlay);
|
|
Instance.CameraMan.gameObject.SetActive(ShowCameraMan);
|
|
Instance.StickyLayer.Sticky = OverlayFollowCamera;
|
|
|
|
// calculation
|
|
CarbageCollection();
|
|
CalculateAutoShowPhotos();
|
|
CalculateCarSpawns();
|
|
PreRandomizeWalkers();
|
|
|
|
// setting local variables
|
|
RiqEntity e = GetLastEntityOfType(beat, "bop");
|
|
if (e is not null)
|
|
{
|
|
DoAutoBop = e["autoBop"];
|
|
DoAutoCrosshairBlink = e["autoBlink"];
|
|
}
|
|
e = GetLastEntityOfType(beat, "toggleOverlay");
|
|
if (e is not null)
|
|
{
|
|
ShowOverlay = e["showOverlay"];
|
|
ShowCameraMan = e["showCameraMan"];
|
|
OverlayFollowCamera = e["followCamera"];
|
|
}
|
|
e = GetLastEntityOfType(beat, "spawnCrowd");
|
|
if (e is not null)
|
|
{
|
|
ToggleCrowd(e.beat, e["crowd"], e["customCrowd"], e["crowdFarLeft"], e["crowdLeft"], e["crowdRight"], e["crowdFarRight"], e["billboard"]);
|
|
}
|
|
|
|
// walkers
|
|
List<RiqEntity> eList = GetCurrentlyActiveEntities(beat, "spawnPerson");
|
|
if (eList.Count > 0)
|
|
{
|
|
foreach (RiqEntity entity in eList)
|
|
{
|
|
SummonWalker(entity);
|
|
}
|
|
}
|
|
|
|
// bop entities
|
|
eList = GetCurrentlyActiveEntities(beat, "bop");
|
|
if (eList.Count > 0)
|
|
{
|
|
foreach (RiqEntity entity in eList)
|
|
{
|
|
SetBopping(entity.beat, entity.length, entity["bop"], entity["autoBop"], entity["blink"], entity["autoBlink"], beat);
|
|
}
|
|
}
|
|
|
|
// Intro
|
|
e = GetLastEntityOfType(beat, "introSign");
|
|
if (e is not null)
|
|
{
|
|
DoIntroSign(e.beat, e.length, e["enter"], e["ease"]);
|
|
}
|
|
e = GetLastEntityOfType(beat, "introLights");
|
|
if (e is not null)
|
|
{
|
|
IntroLightsAnim(e.beat, e.length, e["lightsOn"]);
|
|
}
|
|
|
|
// Camera Man Movement
|
|
foreach (RiqEntity entity in EventCaller.GetAllInGameManagerList("freezeFrame", new string[] { "neoMoveCameraMan", "moveCameraMan", "rotateCameraMan", "scaleCameraMan" }).OrderBy(en => en.beat).Where(en => en.beat <= beat))
|
|
{
|
|
switch (entity.datamodel)
|
|
{
|
|
case "freezeFrame/moveCameraMan":
|
|
SetMoveCameraMan_OLD(entity.beat, entity.length, entity["startPosX"], entity["startPosY"], entity["endPosX"], entity["endPosY"], entity["ease"]);
|
|
break;
|
|
case "freezeFrame/rotateCameraMan":
|
|
FreezeFrame.SetRotateCameraMan_OLD(entity.beat, entity.length, entity["startRot"], entity["endRot"], entity["ease"]);
|
|
break;
|
|
case "freezeFrame/scaleCameraMan":
|
|
SetScaleCameraMan_OLD(entity.beat, entity.length, entity["startSizeX"], entity["startSizeY"], entity["endSizeX"], entity["endSizeY"], entity["ease"]);
|
|
break;
|
|
case "freezeFrame/neoMoveCameraMan":
|
|
default:
|
|
SetMoveCameraMan(entity);
|
|
break;
|
|
}
|
|
}
|
|
// Deprecated:
|
|
/*e = GetLastEntityOfType(beat, "moveCameraMan");
|
|
if (e is not null)
|
|
{
|
|
SetMoveCameraMan_OLD(e.beat, e.length, e["startPosX"], e["startPosY"], e["endPosX"], e["endPosY"], e["ease"]);
|
|
}
|
|
e = GetLastEntityOfType(beat, "rotateCameraMan");
|
|
if (e is not null)
|
|
{
|
|
SetRotateCameraMan_OLD(e.beat, e.length, e["startRot"], e["endRot"], e["ease"]);
|
|
}
|
|
e = GetLastEntityOfType(beat, "scaleCameraMan");
|
|
if (e is not null)
|
|
{
|
|
SetScaleCameraMan_OLD(e.beat, e.length, e["startSizeX"], e["startSizeY"], e["endSizeX"], e["endSizeY"], e["ease"]);
|
|
}*/
|
|
|
|
// cues
|
|
eList = GetCurrentlyActiveEntities(beat, new string[] { "slowCar", "fastCar" });
|
|
if (eList.Count > 0)
|
|
{
|
|
foreach (RiqEntity entity in eList)
|
|
{
|
|
if (beat > entity.beat + 2 || beat <= entity.beat)
|
|
continue;
|
|
|
|
if (entity.datamodel == "freezeFrame/slowCar")
|
|
{
|
|
SlowCarCue(entity.beat, entity["variant"], true, entity["clear"]);
|
|
}
|
|
if (entity.datamodel == "freezeFrame/fastCar")
|
|
{
|
|
FastCarCue(entity.beat, entity["variant"], true, entity["clear"]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// CUE FUNCTIONS
|
|
public static void SetBopping(double beat, float length, bool bop, bool autoBop, bool blink, bool autoBlink, double currentBeat = -1)
|
|
{
|
|
if (Instance == null) return;
|
|
|
|
Instance.DoAutoBop = autoBop;
|
|
Instance.DoAutoCrosshairBlink = autoBlink;
|
|
|
|
if (bop || blink)
|
|
{
|
|
List<BeatAction.Action> actions = new List<BeatAction.Action>();
|
|
for (int i = 0; i < length; i++) {
|
|
if (beat + i < currentBeat)
|
|
continue;
|
|
if (bop)
|
|
actions.Add(new(beat + i, delegate { Instance.Bop(); }));
|
|
if (blink)
|
|
actions.Add(new(beat + i, delegate { Instance.CrosshairBlink(); }));
|
|
}
|
|
BeatAction.New(Instance, actions);
|
|
}
|
|
}
|
|
public static void SlowCarCue(double beat, int photoType, bool mute = false, bool clear = false)
|
|
{
|
|
if (!mute) SlowCarSFX();
|
|
|
|
if (Instance == null) return;
|
|
|
|
Instance.EventArgs.Add(
|
|
Instance.ScheduleInput(beat, 2f, InputAction_BasicPress, Instance.PhotoSuccess, Instance.PhotoMiss, Instance.PhotoEmpty),
|
|
new PhotoArgs(CarType.SlowCar, (PhotoType)photoType, 0f, clear)
|
|
);
|
|
}
|
|
public static void SlowCarSFX()
|
|
{
|
|
SoundByte.PlayOneShotGame("freezeFrame/slowCarFar", forcePlay: true);
|
|
}
|
|
public static void FastCarCue(double beat, int photoType, bool mute = false, bool clear = false)
|
|
{
|
|
if (!mute) FastCarSFX();
|
|
|
|
if (Instance == null) return;
|
|
|
|
Instance.EventArgs.Add(
|
|
Instance.ScheduleInput(beat, 2f, InputAction_BasicPress, Instance.PhotoSuccess, Instance.PhotoMiss, Instance.PhotoEmpty),
|
|
new PhotoArgs(CarType.FastCar, (PhotoType)photoType, 0f, clear)
|
|
);
|
|
SoundByte.PlayOneShotGame("freezeFrame/fastCarNear", beat + 2);
|
|
}
|
|
public static void FastCarSFX()
|
|
{
|
|
SoundByte.PlayOneShotGame("freezeFrame/fastCarFar", forcePlay: true);
|
|
}
|
|
public static void ShowPhotos(double beat, float length, int gradeTypeI, bool audience, bool clearCache)
|
|
{
|
|
if (Instance == null) return;
|
|
|
|
GradeType gradeType = (GradeType)gradeTypeI;
|
|
|
|
if (PhotoList.Count <= 0)
|
|
return;
|
|
|
|
SoundByte.PlayOneShotGame("freezeFrame/pictureShow");
|
|
|
|
// 2 = Hi
|
|
// 1 = OK
|
|
// 0 = Ng
|
|
int goodScore = 2;
|
|
foreach (PhotoArgs photo in PhotoList)
|
|
{
|
|
if (photo.State <= -2)
|
|
{
|
|
goodScore = 0;
|
|
break;
|
|
}
|
|
if (goodScore == 2 && photo.State != 0)
|
|
goodScore = 1;
|
|
}
|
|
|
|
if (gradeType == GradeType.Symbols)
|
|
{
|
|
switch (goodScore)
|
|
{
|
|
case 0:
|
|
Instance.Results.DoScaledAnimationAsync("Batsu", 0.5f);
|
|
break;
|
|
|
|
case 1:
|
|
Instance.Results.DoScaledAnimationAsync("Sankaku", 0.5f);
|
|
break;
|
|
|
|
case 2:
|
|
default:
|
|
Instance.Results.DoScaledAnimationAsync("Maru", 0.5f);
|
|
break;
|
|
}
|
|
}
|
|
if (gradeType == GradeType.Thumbs)
|
|
{
|
|
switch (goodScore)
|
|
{
|
|
case 0:
|
|
Instance.Results.DoScaledAnimationAsync("ThumbsDown", 0.5f);
|
|
break;
|
|
|
|
case 1:
|
|
Instance.Results.DoScaledAnimationAsync("ThumbsSide", 0.5f);
|
|
break;
|
|
|
|
case 2:
|
|
default:
|
|
Instance.Results.DoScaledAnimationAsync("ThumbsUp", 0.5f);
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < PhotoList.Count && i < Instance.Photographs.Length; i++)
|
|
{
|
|
Instance.Photographs[i].ShowPhoto(PhotoList[i]);
|
|
}
|
|
|
|
if (clearCache)
|
|
PhotoList.Clear();
|
|
|
|
Instance.Overlay.SetActive(false);
|
|
Instance.DimRect.SetActive(true);
|
|
Instance.IsShowingPhotos = true;
|
|
|
|
// reactions sounds
|
|
switch (goodScore)
|
|
{
|
|
case 2:
|
|
Instance.CameraMan.DoScaledAnimationAsync("Happy", 0.5f);
|
|
SoundByte.PlayOneShotGame("freezeFrame/result_Hi");
|
|
if (audience)
|
|
break;
|
|
break;
|
|
case 1:
|
|
Instance.CameraMan.DoScaledAnimationAsync("Oops", 0.5f);
|
|
SoundByte.PlayOneShotGame("freezeFrame/result_Ok");
|
|
if (audience)
|
|
SoundByte.PlayOneShot("applause");
|
|
break;
|
|
case 0:
|
|
Instance.CameraMan.DoScaledAnimationAsync("Cry", 0.5f);
|
|
SoundByte.PlayOneShotGame("freezeFrame/result_Ng");
|
|
if (audience)
|
|
break;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
BeatAction.New(Instance, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beat + length, delegate { Instance.HidePhotos(beat + length); })
|
|
});
|
|
}
|
|
public static void ClearPhotos()
|
|
{
|
|
PhotoList?.Clear();
|
|
}
|
|
public static void SummonWalker(RiqEntity e)
|
|
{
|
|
if (Instance == null) return;
|
|
|
|
double beat = e.beat;
|
|
double length = e.length;
|
|
PersonType walkerType = (PersonType)e["personType"];
|
|
PersonDirection direction = (PersonDirection)e["direction"];
|
|
int layer = e["layer"];
|
|
|
|
GameObject walker = Instantiate(Instance.WalkerPrefab, Instance.WalkerSpawn.transform);
|
|
Animator animator = walker.GetComponent<Animator>();
|
|
walker.GetComponent<SortingGroup>().sortingOrder = layer;
|
|
|
|
switch (walkerType)
|
|
{
|
|
case PersonType.Girlfriend:
|
|
animator.DoScaledAnimationAsync("Girlfriend", animLayer: 2);
|
|
break;
|
|
case PersonType.Dude2:
|
|
animator.DoScaledAnimationAsync("Dude2", animLayer: 2);
|
|
break;
|
|
case PersonType.Dude1:
|
|
default:
|
|
animator.DoScaledAnimationAsync("Dude1", animLayer: 2);
|
|
break;
|
|
}
|
|
|
|
if (direction == PersonDirection.Random)
|
|
{
|
|
if (WalkerDirections.ContainsKey(e))
|
|
direction = WalkerDirections[e];
|
|
else
|
|
direction = PersonDirection.Right;
|
|
}
|
|
|
|
if (direction == PersonDirection.Left)
|
|
Instance.Walkers.Add(new WalkerArgs(animator, beat, length, "EnterLeft"));
|
|
else
|
|
Instance.Walkers.Add(new WalkerArgs(animator, beat, length, "EnterRight"));
|
|
|
|
double nextBeat = Math.Ceiling(beat);
|
|
List<BeatAction.Action> actions = new();
|
|
for (double i = nextBeat; i < beat + length; i += 1)
|
|
{
|
|
actions.Add(new(i, delegate { animator.DoScaledAnimationAsync("Bop", timeScale: 0.5f, animLayer: 0); }));
|
|
}
|
|
BeatAction.New(Instance, actions);
|
|
}
|
|
public static void ToggleCrowd(double beat, bool showCrowd, bool customCrowd, int crowdFarLeft, int crowdLeft, int crowdRight, int crowdFarRight, bool billboard)
|
|
{
|
|
if (Instance == null) return;
|
|
|
|
Instance.ShowCrowd = showCrowd;
|
|
if (Instance.ShowCrowd)
|
|
Instance.Crowd.DoScaledAnimationAsync("Show", 0.5f);
|
|
else
|
|
Instance.Crowd.DoScaledAnimationAsync("Hide", 0.5f);
|
|
|
|
if (customCrowd)
|
|
{
|
|
Instance.CrowdFarLeft.sprite = Instance.GetCrowdSprite(crowdFarLeft);
|
|
Instance.CrowdLeft.sprite = Instance.GetCrowdSprite(crowdLeft);
|
|
Instance.CrowdRight.sprite = Instance.GetCrowdSprite(crowdRight);
|
|
Instance.CrowdFarRight.sprite = Instance.GetCrowdSprite(crowdFarRight);
|
|
}
|
|
else
|
|
{
|
|
Instance.CrowdFarLeft.sprite = Instance.GetCrowdSprite(2);
|
|
Instance.CrowdLeft.sprite = Instance.GetCrowdSprite(1);
|
|
Instance.CrowdRight.sprite = Instance.GetCrowdSprite(0);
|
|
Instance.CrowdFarRight.sprite = Instance.GetCrowdSprite(2);
|
|
}
|
|
|
|
Instance.ShowBillboard = billboard;
|
|
}
|
|
public static void DoIntroSign(double beat, double length, bool enter, int easeIndex)
|
|
{
|
|
Util.EasingFunction.Ease ease = (Util.EasingFunction.Ease)easeIndex;
|
|
Instance.SignIsMoving = true;
|
|
if (enter)
|
|
Instance.CurrentSignArgs = new("Enter", beat, length, ease);
|
|
else
|
|
Instance.CurrentSignArgs = new("Exit", beat, length, ease);
|
|
}
|
|
public static void IntroLightsAnim(double beat, double length, bool lightsOn)
|
|
{
|
|
if (!lightsOn)
|
|
{
|
|
Instance.IntroSign.DoScaledAnimationAsync("LightsOff", timeScale: 0.5f, animLayer: 1);
|
|
return;
|
|
}
|
|
|
|
Instance.IntroSign.DoScaledAnimationFromBeatAsync("Light01", startBeat: beat, timeScale: 0.5f, animLayer: 1);
|
|
BeatAction.New(Instance, new List<BeatAction.Action>
|
|
{
|
|
new(beat + length, delegate { Instance.IntroSign.DoScaledAnimationFromBeatAsync("Light02", startBeat: beat + length, timeScale: 0.5f, animLayer: 1); }),
|
|
new(beat + (length * 2), delegate { Instance.IntroSign.DoScaledAnimationFromBeatAsync("Light03", startBeat: beat + (length * 2), timeScale: 0.5f, animLayer: 1); }),
|
|
}
|
|
);
|
|
}
|
|
public static void IntroLightsSound(double beat, double length, bool lightsOn)
|
|
{
|
|
if (!lightsOn)
|
|
return;
|
|
|
|
MultiSound.Play(new MultiSound.Sound[] {
|
|
new MultiSound.Sound("freezeFrame/beginningSignal1", beat),
|
|
new MultiSound.Sound("freezeFrame/beginningSignal1", beat + length),
|
|
new MultiSound.Sound("freezeFrame/beginningSignal2", beat + (length * 2)),
|
|
}, forcePlay: true);
|
|
}
|
|
public static void ToggleOverlay(double beat, bool showOverlay, bool showCameraMan, bool followCamera)
|
|
{
|
|
Instance.ShowOverlay = showOverlay;
|
|
Instance.ShowCameraMan = showCameraMan;
|
|
Instance.OverlayFollowCamera = followCamera;
|
|
}
|
|
public static void SetMoveCameraMan(RiqEntity e)
|
|
{
|
|
if ((bool)e["doMove"])
|
|
{
|
|
SetMoveCameraMan_OLD(e.beat, e.length, e["startMoveX"], e["startMoveY"], e["endMoveX"], e["endMoveY"], e["ease"]);
|
|
}
|
|
if ((bool)e["doRotate"])
|
|
{
|
|
SetRotateCameraMan_OLD(e.beat, e.length, e["startRotDegrees"], e["endRotDegrees"], e["ease"]);
|
|
}
|
|
if ((bool)e["doScale"])
|
|
{
|
|
SetScaleCameraMan_OLD(e.beat, e.length, e["startScaleX"], e["startScaleY"], e["endScaleX"], e["endScaleY"], e["ease"]);
|
|
}
|
|
}
|
|
public static void SetMoveCameraMan_OLD(double beat, double length, float startX, float startY, float endX, float endY, int easeIndex)
|
|
{
|
|
Instance.CurrentCameraManMoveArgs = new(
|
|
beat,
|
|
length,
|
|
new Vector3(startX, startY, 0) + CameraManStartPos,
|
|
new Vector3(endX, endY, 0) + CameraManStartPos,
|
|
(Util.EasingFunction.Ease)easeIndex
|
|
);
|
|
Instance.CameraManMoving = true;
|
|
}
|
|
public static void SetRotateCameraMan_OLD(double beat, double length, float startRot, float endRot, int easeIndex)
|
|
{
|
|
Instance.CurrentCameraManRotateArgs = new(
|
|
beat,
|
|
length,
|
|
startRot,
|
|
endRot,
|
|
(Util.EasingFunction.Ease)easeIndex
|
|
);
|
|
Instance.CameraManRotating = true;
|
|
}
|
|
public static void SetScaleCameraMan_OLD(double beat, double length, float startX, float startY, float endX, float endY, int easeIndex)
|
|
{
|
|
Instance.CurrentCameraManScaleArgs = new(
|
|
beat,
|
|
length,
|
|
new Vector3(startX, startY, 1),
|
|
new Vector3(endX, endY, 1),
|
|
(Util.EasingFunction.Ease)easeIndex
|
|
);
|
|
Instance.CameraManScaling = true;
|
|
}
|
|
|
|
// PRE-FUNCTIONS
|
|
public void SpawnCar(double beat, bool near, string animName, float length)
|
|
{
|
|
if (near)
|
|
{
|
|
if (NearCarPrefab == null || NearCarSpawn == null)
|
|
{
|
|
Debug.LogError($"Failed to spawn car at beat {beat - 1}.");
|
|
return;
|
|
}
|
|
|
|
Instantiate(NearCarPrefab, NearCarSpawn).GetComponent<Car>().Setup(beat, animName, length);;
|
|
}
|
|
else
|
|
{
|
|
if (FarCarPrefab == null || FarCarSpawn == null)
|
|
{
|
|
Debug.LogError($"Failed to spawn car at beat {beat - 1}.");
|
|
return;
|
|
}
|
|
|
|
Instantiate(FarCarPrefab, FarCarSpawn).GetComponent<Car>().Setup(beat, animName, length);;
|
|
}
|
|
}
|
|
/*public void SpawnCar(SpawnCarArgs args)
|
|
{
|
|
if (args.Near)
|
|
{
|
|
if (NearCarSpawn == null)
|
|
{
|
|
UnityEngine.Debug.LogError($"Failed to spawn a car at beat {args.Beat}.");
|
|
return;
|
|
}
|
|
Animator car = Instantiate(NearCarPrefab, NearCarSpawn).GetComponent<Animator>();
|
|
car.DoScaledAnimationFromBeatAsync("Idle", startBeat: 0f, timeScale: 0.5f, animLayer: 0);
|
|
|
|
if (args.Fast)
|
|
car.DoScaledAnimationFromBeatAsync("FastCarGo", startBeat: args.Beat, timeScale: 2.666666666666667f, animLayer: 1);
|
|
else
|
|
car.DoScaledAnimationFromBeatAsync("SlowCarGo", startBeat: args.Beat, timeScale: 1.5f, animLayer: 1);
|
|
|
|
//BeatAction.New(Instance, new List<BeatAction.Action>() { new BeatAction.Action(args.Beat + 3, delegate { Destroy(car); }) });
|
|
}
|
|
else
|
|
{
|
|
if (FarCarSpawn == null)
|
|
{
|
|
UnityEngine.Debug.LogError($"Failed to spawn a car at beat {args.Beat}.");
|
|
return;
|
|
}
|
|
Animator car = Instantiate(FarCarPrefab, FarCarSpawn).GetComponent<Animator>();
|
|
car.DoScaledAnimationFromBeatAsync("Idle", startBeat: 0f, timeScale: 0.5f, animLayer: 0);
|
|
|
|
if (args.Fast)
|
|
car.DoScaledAnimationFromBeatAsync("FastCarGo", startBeat: args.Beat, timeScale: 0.5f, animLayer: 1);
|
|
else
|
|
car.DoScaledAnimationFromBeatAsync("SlowCarGo", startBeat: args.Beat, timeScale: 0.16666666666666666666666666666667f, animLayer: 1);
|
|
|
|
//BeatAction.New(Instance, new List<BeatAction.Action>() { new BeatAction.Action(args.Beat + 8, delegate { Destroy(car); }) });
|
|
}
|
|
}*/
|
|
/*public void SpawnSlowCarNear(double beat)
|
|
{
|
|
if (NearCarSpawn == null) return;
|
|
Animator nearCar = Instantiate(NearCarPrefab, NearCarSpawn).GetComponent<Animator>();
|
|
nearCar.DoScaledAnimationFromBeatAsync("Idle", startBeat: 0f, timeScale: 0.5f, animLayer: 0);
|
|
|
|
double startBeat = beat + 2 - 0.16666666666666666666666666666667;
|
|
BeatAction.New(Instance, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(startBeat, delegate { nearCar.DoScaledAnimationFromBeatAsync("SlowCarGo", startBeat: startBeat, timeScale: 1.5f, animLayer: 1); }),
|
|
new BeatAction.Action(beat + 3, delegate { Destroy(nearCar); } )
|
|
});
|
|
}
|
|
public void SpawnSlowCarFar(double beat)
|
|
{
|
|
//if (beat < 0) return;
|
|
if (FarCarSpawn == null) return;
|
|
Animator farCar = Instantiate(FarCarPrefab, FarCarSpawn).GetComponent<Animator>();
|
|
farCar.DoScaledAnimationFromBeatAsync("Idle", startBeat: 0f, timeScale: 0.5f, animLayer: 0);
|
|
farCar.DoScaledAnimationFromBeatAsync("SlowCarGo", startBeat: beat, timeScale: 0.16666666666666666666666666666667f, animLayer: 1);
|
|
|
|
BeatAction.New(Instance, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beat + 7, delegate { Destroy(farCar); } )
|
|
});
|
|
}
|
|
public void SpawnFastCar(double beat)
|
|
{
|
|
if (FarCarSpawn != null)
|
|
{
|
|
UnityEngine.Debug.Log("farcar");
|
|
Animator farCar = Instantiate(FarCarPrefab, FarCarSpawn).GetComponent<Animator>();
|
|
farCar.DoScaledAnimationFromBeatAsync("Idle", startBeat: 0f, timeScale: 0.5f, animLayer: 0);
|
|
|
|
BeatAction.New(Instance, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beat - 0.5, delegate { if (beat >= 0.5) farCar.DoScaledAnimationFromBeatAsync("FastCarGo", startBeat: beat - 0.5, timeScale: 0.5f, animLayer: 1); }),
|
|
new BeatAction.Action(beat + 3, delegate { Destroy(farCar); } )
|
|
});
|
|
}
|
|
if (NearCarSpawn != null)
|
|
{
|
|
UnityEngine.Debug.Log("fartcar");
|
|
Animator nearCar = Instantiate(NearCarPrefab, NearCarSpawn).GetComponent<Animator>();
|
|
nearCar.DoScaledAnimationFromBeatAsync("Idle", startBeat: 0f, timeScale: 0.5f, animLayer: 0);
|
|
|
|
BeatAction.New(Instance, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beat + 2 - 0.09375, delegate { nearCar.DoScaledAnimationFromBeatAsync("FastCarGo", startBeat: beat - 0.09375, timeScale: 2.666666666666667f, animLayer: 1); }),
|
|
new BeatAction.Action(beat + 3, delegate { Destroy(nearCar); } )
|
|
});
|
|
}
|
|
}*/
|
|
|
|
// INPUT RESULTS
|
|
public void PhotoSuccess(PlayerActionEvent caller, float state)
|
|
{
|
|
PhotoArgs args;
|
|
bool hasArgs = EventArgs.TryGetValue(caller, out args);
|
|
EventArgs.Remove(caller);
|
|
|
|
// passing the args for the photos
|
|
if (hasArgs)
|
|
{
|
|
if (state >= 1f)
|
|
{
|
|
args.State = 1;
|
|
}
|
|
else if (state <= -1f)
|
|
{
|
|
args.State = -1;
|
|
}
|
|
else
|
|
{
|
|
args.State = 0;
|
|
}
|
|
|
|
PushPhoto(args);
|
|
}
|
|
CameraFlash();
|
|
}
|
|
public void PhotoMiss(PlayerActionEvent caller)
|
|
{
|
|
PhotoArgs args;
|
|
bool hasArgs = EventArgs.TryGetValue(caller, out args);
|
|
EventArgs.Remove(caller);
|
|
|
|
if (hasArgs)
|
|
{
|
|
args.State = -2;
|
|
PushPhoto(args);
|
|
}
|
|
}
|
|
public void PhotoEmpty(PlayerActionEvent caller)
|
|
{
|
|
|
|
}
|
|
|
|
// GENERAL METHODS
|
|
public void Bop()
|
|
{
|
|
CameraMan.DoScaledAnimationAsync("Bop", 0.5f);
|
|
}
|
|
public void CrosshairBlink()
|
|
{
|
|
Crosshair.SetActive(!Crosshair.activeSelf);
|
|
}
|
|
public void CameraFlash()
|
|
{
|
|
Shutter.DoScaledAnimationAsync("Shut", 0.5f);
|
|
CameraMan.DoScaledAnimationAsync("Flash", 0.5f);
|
|
SoundByte.PlayOneShotGame("freezeFrame/shutter"/*, pitch: (float)new System.Random().NextDouble() + 0.5f*/);
|
|
}
|
|
public void PushPhoto(PhotoArgs args)
|
|
{
|
|
if (args.ClearPhotos)
|
|
ClearPhotos();
|
|
|
|
if (args.PhotoType == PhotoType.Random)
|
|
{
|
|
if (UnityEngine.Random.Range(0, 8) >= 7)
|
|
{
|
|
switch (UnityEngine.Random.Range(0, 3))
|
|
{
|
|
case 0:
|
|
args.PhotoType = PhotoType.Ninja;
|
|
break;
|
|
case 1:
|
|
args.PhotoType = PhotoType.Ghost;
|
|
break;
|
|
case 2:
|
|
args.PhotoType = PhotoType.Rats;
|
|
break;
|
|
default:
|
|
args.PhotoType = PhotoType.Default;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
args.PhotoType = PhotoType.Default;
|
|
}
|
|
|
|
PhotoList.Add(args);
|
|
}
|
|
public void HidePhotos(double beat)
|
|
{
|
|
Overlay.SetActive(ShowOverlay);
|
|
DimRect.SetActive(false);
|
|
foreach (Photograph photo in Photographs)
|
|
photo.HideAll();
|
|
Results.DoScaledAnimationAsync("None", 0.5f);
|
|
IsShowingPhotos = false;
|
|
if (beat % 1 == 0 && DoAutoBop)
|
|
CameraMan.DoScaledAnimationAsync("Bop", 0.5f);
|
|
else
|
|
CameraMan.DoScaledAnimationAsync("Idle", 0.5f);
|
|
}
|
|
public Sprite GetCrowdSprite(int i)
|
|
{
|
|
if (CrowdSprites.Length <= 0)
|
|
{
|
|
Debug.LogError("Error from Freeze Frame: CrowdSprites was empty.");
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
// just looping back thru the array jic there's an invalid index
|
|
return CrowdSprites[i % CrowdSprites.Length];
|
|
}
|
|
}
|
|
public void CalculateAutoShowPhotos()
|
|
{
|
|
List<RiqEntity> allCars = EventCaller.GetAllInGameManagerList("freezeFrame", new string[] { "slowCar", "fastCar" });
|
|
|
|
List<BeatAction.Action> actions = new();
|
|
List<double> beats = new(); // so you don't double up
|
|
|
|
foreach (RiqEntity entity in allCars.Where(car => (bool)car["autoShowPhotos"]))
|
|
{
|
|
double showBeat = 3f;
|
|
if (allCars.Any(car => car.beat == entity.beat - 1f))
|
|
showBeat = 3.5f;
|
|
if (entity.datamodel == "freezeFrame/fastCar")
|
|
showBeat = 4f;
|
|
if (allCars.Any(car => car.beat == entity.beat - 2f))
|
|
showBeat = 4.5f;
|
|
showBeat = entity.beat + showBeat;
|
|
|
|
if (!allCars.Any(car => car.beat > entity.beat && car.beat <= showBeat))
|
|
{
|
|
if (!beats.Any(b => showBeat >= b && showBeat < b + 2))
|
|
{
|
|
beats.Add(showBeat);
|
|
actions.Add(new BeatAction.Action(showBeat, delegate { ShowPhotos(showBeat, 2, (int)entity["gradeType"], (bool)entity["audience"], false); }));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (actions.Count > 0)
|
|
{
|
|
BeatAction.New(Instance, actions);
|
|
}
|
|
}
|
|
public void CalculateCarSpawns()
|
|
{
|
|
List<RiqEntity> fastCars = EventCaller.GetAllInGameManagerList("freezeFrame", new string[] { "fastCar" });
|
|
foreach (RiqEntity e in fastCars)
|
|
{
|
|
BeatAction.New(this, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(e.beat - 0.5, delegate { SpawnCar(e.beat - 0.5, false, "FastCarGo", 1); }),
|
|
new BeatAction.Action(e.beat + 2 - 0.09375, delegate { SpawnCar(e.beat + 2 - 0.09375, true, "FastCarGo", 3f / 16f); }),
|
|
});
|
|
}
|
|
|
|
List<RiqEntity> slowCars = EventCaller.GetAllInGameManagerList("freezeFrame", new string[] { "slowCar" });
|
|
foreach (RiqEntity e in slowCars)
|
|
{
|
|
BeatAction.New(this, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(e.beat + 2 - 0.16666666666666666666666666666667, delegate { SpawnCar(e.beat + 2 - 0.16666666666666666666666666666667, true, "SlowCarGo", 1f / 3f); })
|
|
});
|
|
}
|
|
|
|
List<List<double>> clusters = new();
|
|
|
|
while (slowCars.Count > 0)
|
|
{
|
|
double minBeat = slowCars[0].beat;
|
|
double maxBeat = minBeat + 2;
|
|
|
|
clusters.Add(slowCars.Where(car => car.beat >= minBeat && car.beat < maxBeat).Select(car => car.beat).ToList());
|
|
slowCars.RemoveAll(car => car.beat >= minBeat && car.beat < maxBeat);
|
|
}
|
|
|
|
foreach (List<double> cluster in clusters)
|
|
{
|
|
double midBeat = cluster.Min() + ((cluster.Max() - cluster.Min()) / 2);
|
|
|
|
foreach (double beat in cluster)
|
|
{
|
|
double diff = midBeat - beat;
|
|
double modifiedBeat = midBeat + (diff / 4);
|
|
|
|
BeatAction.New(this, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(modifiedBeat - 4, delegate { SpawnCar(modifiedBeat - 4, false, "SlowCarGo", 3f); })
|
|
});
|
|
}
|
|
}
|
|
}
|
|
public void PreRandomizeWalkers()
|
|
{
|
|
IEnumerable<RiqEntity> walkers = EventCaller.GetAllInGameManagerList("freezeFrame", new string[] { "spawnPerson" }).Where(e => (PersonDirection)e["direction"] == PersonDirection.Random);
|
|
foreach (RiqEntity e in walkers)
|
|
{
|
|
if (!WalkerDirections.ContainsKey(e))
|
|
{
|
|
float rand = UnityEngine.Random.Range(0.0f, 1.0f);
|
|
if (rand >= 0.5)
|
|
{
|
|
WalkerDirections.Add(e, PersonDirection.Left);
|
|
}
|
|
else
|
|
{
|
|
WalkerDirections.Add(e, PersonDirection.Right);
|
|
}
|
|
}
|
|
}
|
|
List<RiqEntity> keysToRemove = new();
|
|
foreach (RiqEntity key in WalkerDirections.Keys)
|
|
{
|
|
if (!walkers.Contains(key))
|
|
keysToRemove.Add(key);
|
|
}
|
|
foreach (RiqEntity key in keysToRemove)
|
|
{
|
|
WalkerDirections.Remove(key);
|
|
}
|
|
}
|
|
public void CarbageCollection()
|
|
{
|
|
foreach (Transform child in FarCarSpawn)
|
|
{
|
|
Destroy(child.gameObject);
|
|
}
|
|
foreach (Transform child in NearCarSpawn)
|
|
{
|
|
Destroy(child.gameObject);
|
|
}
|
|
foreach (Transform child in WalkerSpawn)
|
|
{
|
|
Destroy(child.gameObject);
|
|
}
|
|
}
|
|
public RiqEntity GetLastEntityOfType(double beat, string datamodel)
|
|
{
|
|
foreach (RiqEntity e in EventCaller.GetAllInGameManagerList("freezeFrame", new string[] { datamodel }).OrderBy(e => -e.beat))
|
|
{
|
|
if (e.beat < beat)
|
|
return e;
|
|
}
|
|
return null;
|
|
}
|
|
public List<RiqEntity> GetCurrentlyActiveEntities(double beat, string datamodel)
|
|
{
|
|
return GetCurrentlyActiveEntities(beat, new string[] { datamodel });
|
|
}
|
|
public List<RiqEntity> GetCurrentlyActiveEntities(double beat, string[] datamodel)
|
|
{
|
|
List<RiqEntity> result = new();
|
|
foreach (RiqEntity e in EventCaller.GetAllInGameManagerList("freezeFrame", datamodel))
|
|
{
|
|
if (beat >= e.beat && beat <= e.beat + e.length)
|
|
result.Add(e);
|
|
if (e.beat > beat)
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// ENUMS
|
|
public enum CarType : int
|
|
{
|
|
SlowCar = 0,
|
|
FastCar = 1
|
|
}
|
|
public enum PhotoType : int
|
|
{
|
|
Random = 0,
|
|
Default = 1,
|
|
Ninja = 2,
|
|
Ghost = 3,
|
|
Rats = 4,
|
|
PeaceSign = 5,
|
|
GirlfriendRight = 6,
|
|
GirlfriendLeft = 7,
|
|
Dude1Right = 8,
|
|
Dude1Left = 9,
|
|
Dude2Right = 10,
|
|
Dude2Left = 11,
|
|
}
|
|
public enum PersonType : int
|
|
{
|
|
Dude1 = 0,
|
|
Dude2 = 1,
|
|
Girlfriend = 2
|
|
}
|
|
public enum PersonDirection : int
|
|
{
|
|
Random = 0,
|
|
Right = 1,
|
|
Left = 2
|
|
}
|
|
public enum GradeType : int
|
|
{
|
|
Symbols = 0,
|
|
Thumbs = 1,
|
|
None = 2
|
|
}
|
|
public enum CustomCrowdType : int
|
|
{
|
|
TealDancers = 0,
|
|
YellowDancers = 1,
|
|
PinkDancers = 2,
|
|
CyanDancers = 3,
|
|
}
|
|
|
|
// STRUCTS
|
|
public struct PhotoArgs
|
|
{
|
|
public CarType Car;
|
|
public PhotoType PhotoType;
|
|
public float State;
|
|
public bool ClearPhotos;
|
|
|
|
public PhotoArgs(CarType car, PhotoType photoType, float state, bool clear)
|
|
{
|
|
Car = car;
|
|
PhotoType = photoType;
|
|
State = state;
|
|
ClearPhotos = clear;
|
|
}
|
|
}
|
|
public struct WalkerArgs
|
|
{
|
|
public Animator Walker;
|
|
public double StartTime;
|
|
public double Length;
|
|
public string AnimName;
|
|
|
|
public WalkerArgs(Animator walker, double startTime, double length, string animName)
|
|
{
|
|
Walker = walker;
|
|
StartTime = startTime;
|
|
Length = length;
|
|
AnimName = animName;
|
|
}
|
|
}
|
|
public struct SignMoveArgs
|
|
{
|
|
public string AnimName;
|
|
public double StartTime;
|
|
public double Length;
|
|
public Util.EasingFunction.Ease Ease;
|
|
|
|
public SignMoveArgs(string animName, double startTime, double length, Util.EasingFunction.Ease ease)
|
|
{
|
|
AnimName = animName;
|
|
StartTime = startTime;
|
|
Length = length;
|
|
Ease = ease;
|
|
}
|
|
}
|
|
public struct CameraManMoveArgs
|
|
{
|
|
public double StartBeat;
|
|
public double Length;
|
|
public Vector3 StartPos;
|
|
public Vector3 EndPos;
|
|
public Util.EasingFunction.Ease Ease;
|
|
|
|
public CameraManMoveArgs(double startBeat, double length, Vector3 startPos, Vector3 endPos, Util.EasingFunction.Ease ease)
|
|
{
|
|
StartBeat = startBeat;
|
|
Length = length;
|
|
StartPos = startPos;
|
|
EndPos = endPos;
|
|
Ease = ease;
|
|
}
|
|
}
|
|
public struct CameraManRotateArgs
|
|
{
|
|
public double StartBeat;
|
|
public double Length;
|
|
public float StartRot;
|
|
public float EndRot;
|
|
public Util.EasingFunction.Ease Ease;
|
|
|
|
public CameraManRotateArgs(double startBeat, double length, float startRot, float endRot, Util.EasingFunction.Ease ease)
|
|
{
|
|
StartBeat = startBeat;
|
|
Length = length;
|
|
StartRot = startRot;
|
|
EndRot = endRot;
|
|
Ease = ease;
|
|
}
|
|
}
|
|
public struct CameraManScaleArgs
|
|
{
|
|
public double StartBeat;
|
|
public double Length;
|
|
public Vector3 StartScale;
|
|
public Vector3 EndScale;
|
|
public Util.EasingFunction.Ease Ease;
|
|
|
|
public CameraManScaleArgs(double startBeat, double length, Vector3 startScale, Vector3 endScale, Util.EasingFunction.Ease ease)
|
|
{
|
|
StartBeat = startBeat;
|
|
Length = length;
|
|
StartScale = startScale;
|
|
EndScale = endScale;
|
|
Ease = ease;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// This minigame ported by Yin. ☆ |