Autoplay Toggle, Fake Input Block (r1.1) (#976)

* vfx event optimization + scheduled autoplay stuff

FOR RELEASE 1.1
making another commit for r2

* toggle inputs/autoplay + stretchy

the days of useless stretchy toggle inputs are over.
also dog ninja fix and lockstep Stop Stepping block

* change order

* flash beat 0 fix, toggles are ignored in strechys

* km optimizations, air rally fixes

* smore km stuff
This commit is contained in:
AstrlJelly 2024-06-14 18:05:49 -04:00 committed by minenice55
parent 2f2161530a
commit 1c88ed844f
43 changed files with 791 additions and 385 deletions

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 7b5043598e8ba3e4cab4db512a80b0a3
guid: e3dd2ca1cdaa6884fa5b376b215d075d
AudioImporter:
externalObjects: {}
serializedVersion: 6
@ -18,5 +18,5 @@ AudioImporter:
ambisonic: 0
3D: 1
userData:
assetBundleName: rvlbadminton/locale
assetBundleVariant: en
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 24ea4abf57f853f48aa534d1a59941a0
guid: 27656503f44ea0e45a64d07217d99205
AudioImporter:
externalObjects: {}
serializedVersion: 6
@ -18,5 +18,5 @@ AudioImporter:
ambisonic: 0
3D: 1
userData:
assetBundleName: rvlbadminton/locale
assetBundleVariant: en
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 9d8a49a7004b1d4449aaf210c57e1b22
guid: 138cdf345de819c44abecb813a18ec4e
AudioImporter:
externalObjects: {}
serializedVersion: 6
@ -18,5 +18,5 @@ AudioImporter:
ambisonic: 0
3D: 1
userData:
assetBundleName: rvlbadminton/locale
assetBundleVariant: en
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: d59bc63e331a573429c19dd42fbfae7c
guid: cc6bbb564b5bed548962bea683196415
AudioImporter:
externalObjects: {}
serializedVersion: 6
@ -18,5 +18,5 @@ AudioImporter:
ambisonic: 0
3D: 1
userData:
assetBundleName: rvlbadminton/locale
assetBundleVariant: en
assetBundleName:
assetBundleVariant:

View File

@ -101,23 +101,6 @@ namespace HeavenStudio
}
}
// public void CallPreEvent(RiqEntity entity)
// {
// string[] details = entity.datamodel.Split('/');
// Minigames.Minigame game = minigames[details[0]];
// try
// {
// currentEntity = entity;
// Minigames.GameAction action = game.actions.Find(c => c.actionName == details[1]);
// action.preFunction.Invoke();
// }
// catch (Exception ex)
// {
// Debug.LogWarning("Event not found! May be spelled wrong or it is not implemented.\n" + ex);
// }
// }
public static List<RiqEntity> GetAllInGameManagerList(string gameName)
{
return instance.gameManager.Beatmap.Entities.FindAll(c => c.datamodel.Split('/')[0] == gameName);

View File

@ -156,23 +156,29 @@ namespace HeavenStudio
positionLast = defaultPosition;
rotEulerLast = defaultRotEluer;
// this entire thing is a mess redo it later
//pos
positionEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "move camera" });
// legacy event
positionEvents.AddRange(EventCaller.GetAllInGameManagerList("gameManager", new string[] { "move camera" }));
//rot
rotationEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "rotate camera" });
positionEvents.AddRange(EventCaller.GetAllInGameManagerList("gameManager", new string[] { "rotate camera" }));
//screen shake time baybee
shakeEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "screen shake" });
//color/colour time baybee
colorEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "camera background color" });
positionEvents.Clear();
rotationEvents.Clear();
shakeEvents.Clear();
colorEvents.Clear();
foreach (var entity in GameManager.instance.Beatmap.Entities)
{
switch (entity.datamodel)
{
case "vfx/move camera" or "gameManager/move camera":
positionEvents.Add(entity);
break;
case "vfx/rotate camera" or "gameManager/rotate camera":
rotationEvents.Add(entity);
break;
case "vfx/screen shake":
shakeEvents.Add(entity);
break;
case "vfx/camera background color":
colorEvents.Add(entity);
break;
default: break;
}
}
UpdateCameraTranslate();
UpdateCameraRotate();

View File

@ -36,6 +36,7 @@ namespace HeavenStudio
[NonSerialized] public GameObject GamesHolder;
[NonSerialized] public Games.Global.Flash fade;
[NonSerialized] public Games.Global.Filter filter;
[NonSerialized] public Games.Global.BlockChecker blockChecker;
[Header("Games")]
Coroutine currentGameSwitchIE;
@ -60,7 +61,9 @@ namespace HeavenStudio
public int MarkerCategory { get; private set; }
public bool playMode { get; private set; }
public bool autoplay { get; private set; }
public bool Autoplay => userAutoplay || scheduledAutoplay;
public bool userAutoplay { get; private set; }
public bool scheduledAutoplay { get; private set; }
public bool canInput { get; private set; }
public bool GameHasSplitColours
@ -75,10 +78,9 @@ namespace HeavenStudio
bool AudioLoadDone;
bool ChartLoadError;
//bool exiting; Unused value - Marc
List<double> eventBeats, preSequenceBeats, tempoBeats, volumeBeats, sectionBeats;
List<RiqEntity> allGameSwitches;
public List<RiqEntity> allGameSwitches;
public event Action<double> onBeatChanged;
public event Action<RiqEntity, RiqEntity> onSectionChange;
@ -130,7 +132,6 @@ namespace HeavenStudio
private void Awake()
{
instance = this;
//exiting = false; Unused value - Marc
}
public void Init(bool preLoaded = false)
@ -141,9 +142,12 @@ namespace HeavenStudio
currentPreSwitch = 0;
currentPreSequence = 0;
GameObject filter = new GameObject("filter");
GameObject filter = new GameObject("Filter");
this.filter = filter.AddComponent<Games.Global.Filter>();
GameObject blockChecker = new GameObject("BlockChecker");
this.blockChecker = blockChecker.AddComponent<Games.Global.BlockChecker>();
eventCaller = this.gameObject.AddComponent<EventCaller>();
eventCaller.GamesHolder = GamesHolder.transform;
eventCaller.Init(this);
@ -661,9 +665,14 @@ namespace HeavenStudio
canInput = inputs;
}
public void ToggleScheduledAutoplay(bool auto)
{
scheduledAutoplay = auto;
}
public void ToggleAutoplay(bool auto)
{
autoplay = auto;
userAutoplay = auto;
}
public void TogglePlayMode(bool mode)
@ -817,7 +826,6 @@ namespace HeavenStudio
}
else if (playMode)
{
//exiting = true; Unused value - Marc
judgementInfo.star = skillStarCollected;
judgementInfo.perfect = GoForAPerfect.instance.perfect;
judgementInfo.noMiss = noMiss;
@ -1240,27 +1248,25 @@ namespace HeavenStudio
}
if (gameInfo.fxOnly)
{
var gameInfos = Beatmap.Entities
.Select(x => x.datamodel.Split(0))
.Select(x => GetGameInfo(x))
.Where(x => x != null)
.Where(x => !x.fxOnly)
.Where(x => x.LoadableName is not "noGame" or "" or null);
if (gameInfos.Count() > 0)
// IEnumerable<Minigames.Minigame> gameInfos = Beatmap.Entities
// .Select(x => GetGameInfo(x.datamodel.Split(0)))
// .Where(x => x != null && !x.fxOnly && x.LoadableName is not "noGame" or "" or null);
foreach (var entity in Beatmap.Entities)
{
gameInfo = gameInfos.FirstOrDefault();
if (gameInfo == null) return Resources.Load<GameObject>($"Games/noGame");
}
else
{
return Resources.Load<GameObject>($"Games/noGame");
var gInfo = GetGameInfo(entity.datamodel.Split(0));
if (gInfo != null && !gInfo.fxOnly && gInfo.LoadableName is not "noGame" or "" or null) {
gameInfo = gInfo;
break;
}
}
if (gameInfo == null) return Resources.Load<GameObject>($"Games/noGame");
}
GameObject prefab;
if (gameInfo.UsesAssetBundle)
{
//game is packed in an assetbundle, load from that instead
// game is packed in an assetbundle, load from that instead
if (gameInfo.AssetsLoaded && gameInfo.LoadedPrefab != null) return gameInfo.LoadedPrefab;
// couldn't load cached prefab, try loading from resources (usually indev games with mispacked assetbundles)
Debug.LogWarning($"Failed to load prefab for game {name} from assetbundle, trying Resources...");

View File

@ -23,7 +23,9 @@ namespace HeavenStudio.Games.Loaders
},
new GameAction("ba bum bum bum", "Ba Bum Bum Bum")
{
preFunction = delegate { AirRally.PreStartBaBumBumBum(e.currentEntity.beat, e.currentEntity["toggle"], e.currentEntity["toggle2"]); },
preFunction = delegate {
AirRally.PreStartBaBumBumBum(e.currentEntity.beat, e.currentEntity["toggle"], e.currentEntity["toggle2"]);
},
defaultLength = 6f,
parameters = new List<Param>()
{
@ -34,7 +36,11 @@ namespace HeavenStudio.Games.Loaders
},
new GameAction("set distance", "Set Distance")
{
function = delegate { AirRally.instance.SetDistance(e.currentEntity.beat, e.currentEntity["type"], e.currentEntity["ease"]); },
function = delegate {
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.SetDistance(e.currentEntity.beat, e.currentEntity["type"], e.currentEntity["ease"]);
}
},
parameters = new List<Param>()
{
new Param("type", AirRally.DistanceSound.Close, "Type", "Set Forthington's distance."),
@ -46,7 +52,9 @@ namespace HeavenStudio.Games.Loaders
{
function = delegate
{
AirRally.instance.SetEnter(e.currentEntity.beat, e.currentEntity.length, e.currentEntity["ease"], true);
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.SetEnter(e.currentEntity.beat, e.currentEntity.length, e.currentEntity["ease"], true);
}
},
resizable = true,
defaultLength = 2f,
@ -59,7 +67,9 @@ namespace HeavenStudio.Games.Loaders
{
function = delegate
{
AirRally.instance.Forward(e.currentEntity["reset"]);
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.Forward(e.currentEntity["reset"]);
}
},
parameters = new List<Param>()
{
@ -76,25 +86,31 @@ namespace HeavenStudio.Games.Loaders
},
function = delegate
{
AirRally.instance.ForthCountIn4Do(e.currentEntity.beat, e.currentEntity.length);
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.ForthCountIn4Do(e.currentEntity.beat, e.currentEntity.length);
}
}
},
new GameAction("8beat", "8 Beat Count-In")
{
defaultLength = 8f,
resizable = true,
preFunction = delegate
{
preFunction = delegate {
AirRally.ForthCountIn8(e.currentEntity.beat, e.currentEntity.length);
},
function = delegate
{
AirRally.instance.ForthCountIn8Do(e.currentEntity.beat, e.currentEntity.length);
}
function = delegate {
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.ForthCountIn8Do(e.currentEntity.beat, e.currentEntity.length);
}
},
defaultLength = 8f,
resizable = true,
},
new GameAction("forthington voice lines", "Count")
{
function = delegate { AirRally.instance.ForthVoiceDo(e.currentEntity.beat); },
function = delegate {
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.ForthVoiceDo(e.currentEntity.beat);
}
},
preFunction = delegate { AirRally.ForthVoice(e.currentEntity.beat, e.currentEntity["type"]); },
parameters = new List<Param>()
{
@ -103,10 +119,11 @@ namespace HeavenStudio.Games.Loaders
},
new GameAction("spawnBird", "Spawn Birds")
{
function = delegate
{
AirRally.instance.SpawnBirds(e.currentEntity["type"], e.currentEntity["xSpeed"], e.currentEntity["zSpeed"],
e.currentEntity["startZ"], e.currentEntity["invert"]);
function = delegate {
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.SpawnBirds(e.currentEntity["type"], e.currentEntity["xSpeed"], e.currentEntity["zSpeed"],
e.currentEntity["startZ"], e.currentEntity["invert"]);
}
},
parameters = new List<Param>()
{
@ -119,9 +136,10 @@ namespace HeavenStudio.Games.Loaders
},
new GameAction("rainbow", "Spawn Rainbow")
{
function = delegate
{
AirRally.instance.SpawnRainbow(e.currentEntity.beat, e.currentEntity["speed"], e.currentEntity["start"]);
function = delegate {
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.SpawnRainbow(e.currentEntity.beat, e.currentEntity["speed"], e.currentEntity["start"]);
}
},
parameters = new List<Param>()
{
@ -133,9 +151,11 @@ namespace HeavenStudio.Games.Loaders
{
function = delegate
{
AirRally.instance.SetDayNightCycle(e.currentEntity.beat, e.currentEntity.length,
(AirRally.DayNightCycle)e.currentEntity["start"], (AirRally.DayNightCycle)e.currentEntity["end"],
(EasingFunction.Ease)e.currentEntity["ease"]);
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.SetDayNightCycle(e.currentEntity.beat, e.currentEntity.length,
(AirRally.DayNightCycle)e.currentEntity["start"], (AirRally.DayNightCycle)e.currentEntity["end"],
(EasingFunction.Ease)e.currentEntity["ease"]);
}
},
resizable = true,
parameters = new List<Param>()
@ -149,8 +169,10 @@ namespace HeavenStudio.Games.Loaders
{
function = delegate
{
AirRally.instance.SetCloudRates(e.currentEntity.beat, e.currentEntity.length, e.currentEntity["main"], e.currentEntity["side"], e.currentEntity["top"],
e.currentEntity["speed"], e.currentEntity["endSpeed"], e.currentEntity["ease"]);
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.SetCloudRates(e.currentEntity.beat, e.currentEntity.length, e.currentEntity["main"], e.currentEntity["side"], e.currentEntity["top"],
e.currentEntity["speed"], e.currentEntity["endSpeed"], e.currentEntity["ease"]);
}
},
resizable = true,
parameters = new List<Param>()
@ -165,10 +187,11 @@ namespace HeavenStudio.Games.Loaders
},
new GameAction("snowflake", "Snowflake Density")
{
function = delegate
{
AirRally.instance.SetSnowflakeRates(e.currentEntity.beat, e.currentEntity.length, e.currentEntity["cps"],
e.currentEntity["speed"], e.currentEntity["endSpeed"], e.currentEntity["ease"]);
function = delegate {
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.SetSnowflakeRates(e.currentEntity.beat, e.currentEntity.length, e.currentEntity["cps"],
e.currentEntity["speed"], e.currentEntity["endSpeed"], e.currentEntity["ease"]);
}
},
resizable = true,
parameters = new List<Param>()
@ -183,8 +206,10 @@ namespace HeavenStudio.Games.Loaders
{
function = delegate
{
AirRally.instance.SetTreeRates(e.currentEntity["enable"], e.currentEntity.beat, e.currentEntity.length, e.currentEntity["main"], e.currentEntity["side"],
e.currentEntity["speed"], e.currentEntity["endSpeed"], e.currentEntity["ease"]);
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.SetTreeRates(e.currentEntity["enable"], e.currentEntity.beat, e.currentEntity.length, e.currentEntity["main"], e.currentEntity["side"],
e.currentEntity["speed"], e.currentEntity["endSpeed"], e.currentEntity["ease"]);
}
},
resizable = true,
parameters = new List<Param>()
@ -204,8 +229,10 @@ namespace HeavenStudio.Games.Loaders
{
function = delegate
{
AirRally.instance.SetIslandSpeed(e.currentEntity.beat, e.currentEntity.length, e.currentEntity["speed"],
e.currentEntity["endSpeed"], e.currentEntity["ease"]);
if (e.gameManager.TryGetMinigame(out AirRally instance)) {
instance.SetIslandSpeed(e.currentEntity.beat, e.currentEntity.length, e.currentEntity["speed"],
e.currentEntity["endSpeed"], e.currentEntity["ease"]);
}
},
resizable = true,
parameters = new List<Param>()
@ -303,10 +330,10 @@ namespace HeavenStudio.Games
private static readonly float[] baBumBumBumFarAltOffsets = new float[4]
{
0.001f, // ba
0.012f, // bum1
0.012f, // bum2
0.012f, // bum3
0.001f, // ba
0.012f, // bum1
0.012f, // bum2
0.012f, // bum3
};
public enum BirdType
@ -316,8 +343,6 @@ namespace HeavenStudio.Games
Bluebirds
}
public static AirRally instance { get; set; }
[Header("Component")]
[SerializeField] Animator Baxter;
[SerializeField] Animator Forthington;
@ -371,7 +396,6 @@ namespace HeavenStudio.Games
private void Awake()
{
instance = this;
forthTrans = Forthington.transform;
baxterTrans = Baxter.transform;
// lags the game WAY too much when seeking
@ -384,7 +408,7 @@ namespace HeavenStudio.Games
// Update is called once per frame
void Update()
{
if (PlayerInput.CurrentControlStyle == InputController.ControlStyles.Touch && !GameManager.instance.autoplay)
if (PlayerInput.CurrentControlStyle == InputController.ControlStyles.Touch && !GameManager.instance.Autoplay)
{
if (PlayerInput.GetIsAction(InputAction_BasicPress))
{
@ -817,9 +841,10 @@ namespace HeavenStudio.Games
public static void ForthCountIn4(double beat, float length)
{
float realLength = length / 4;
Debug.Log("airRally/en/countIn1" + GetDistanceStringAtBeat(beat, true));
MultiSound.Play(new List<MultiSound.Sound>
{
new MultiSound.Sound("airRally/en/countIn1" + GetDistanceStringAtBeat(beat, true), beat, 1, 1, false, countInOffsets[0]),
new MultiSound.Sound("airRally/en/countIn1" + GetDistanceStringAtBeat(beat, true), beat, 1, 1, false, countInOffsets[0]),
new MultiSound.Sound("airRally/en/countIn2" + GetDistanceStringAtBeat(beat + (1 * realLength), true), beat + (1 * realLength), 1, 1, false, countInOffsets[1]),
new MultiSound.Sound("airRally/en/countIn3" + GetDistanceStringAtBeat(beat + (2 * realLength), true), beat + (2 * realLength), 1, 1, false, countInOffsets[2]),
new MultiSound.Sound("airRally/en/countIn4" + GetDistanceStringAtBeat(beat + (3 * realLength), true), beat + (3 * realLength), 1, 1, false, countInOffsets[3]),
@ -828,12 +853,12 @@ namespace HeavenStudio.Games
public void ForthCountIn4Do(double beat, float length)
{
BeatAction.New(instance, instance.ForthCountIn4Action(beat, length));
BeatAction.New(this, ForthCountIn4Action(beat, length));
}
public void ForthCountIn8Do(double beat, float length)
{
BeatAction.New(instance, instance.ForthCountIn8Action(beat, length));
BeatAction.New(this, ForthCountIn8Action(beat, length));
}
private List<BeatAction.Action> ForthCountIn4Action(double beat, float length)
@ -842,22 +867,10 @@ namespace HeavenStudio.Games
return new List<BeatAction.Action>()
{
new BeatAction.Action(beat, delegate
{
instance.Forthington.DoScaledAnimationAsync("TalkShort", 0.5f);
}),
new BeatAction.Action(beat + (1 * realLength), delegate
{
instance.Forthington.DoScaledAnimationAsync("TalkShort", 0.5f);
}),
new BeatAction.Action(beat + (2 * realLength), delegate
{
instance.Forthington.DoScaledAnimationAsync("TalkShort", 0.5f);
}),
new BeatAction.Action(beat + (3 * realLength), delegate
{
instance.Forthington.DoScaledAnimationAsync("TalkShort", 0.5f);
}),
new BeatAction.Action(beat, delegate { Forthington.DoScaledAnimationAsync("TalkShort", 0.5f); }),
new BeatAction.Action(beat + (1 * realLength), delegate { Forthington.DoScaledAnimationAsync("TalkShort", 0.5f); }),
new BeatAction.Action(beat + (2 * realLength), delegate { Forthington.DoScaledAnimationAsync("TalkShort", 0.5f); }),
new BeatAction.Action(beat + (3 * realLength), delegate { Forthington.DoScaledAnimationAsync("TalkShort", 0.5f); }),
};
}
@ -867,30 +880,12 @@ namespace HeavenStudio.Games
return new List<BeatAction.Action>()
{
new BeatAction.Action(beat, delegate
{
instance.Forthington.DoScaledAnimationAsync("TalkShort", 0.5f);
}),
new BeatAction.Action(beat + (2 * realLength), delegate
{
instance.Forthington.DoScaledAnimationAsync("TalkShort", 0.5f);
}),
new BeatAction.Action(beat + (4 * realLength), delegate
{
instance.Forthington.DoScaledAnimationAsync("TalkShort", 0.5f);
}),
new BeatAction.Action(beat + (5 * realLength), delegate
{
instance.Forthington.DoScaledAnimationAsync("TalkShort", 0.5f);
}),
new BeatAction.Action(beat + (6 * realLength), delegate
{
instance.Forthington.DoScaledAnimationAsync("TalkShort", 0.5f);
}),
new BeatAction.Action(beat + (7 * realLength), delegate
{
instance.Forthington.DoScaledAnimationAsync("TalkShort", 0.5f);
}),
new BeatAction.Action(beat, delegate { Forthington.DoScaledAnimationAsync("TalkShort", 0.5f); }),
new BeatAction.Action(beat + (2 * realLength), delegate { Forthington.DoScaledAnimationAsync("TalkShort", 0.5f); }),
new BeatAction.Action(beat + (4 * realLength), delegate { Forthington.DoScaledAnimationAsync("TalkShort", 0.5f); }),
new BeatAction.Action(beat + (5 * realLength), delegate { Forthington.DoScaledAnimationAsync("TalkShort", 0.5f); }),
new BeatAction.Action(beat + (6 * realLength), delegate { Forthington.DoScaledAnimationAsync("TalkShort", 0.5f); }),
new BeatAction.Action(beat + (7 * realLength), delegate { Forthington.DoScaledAnimationAsync("TalkShort", 0.5f); }),
};
}
@ -918,9 +913,9 @@ namespace HeavenStudio.Games
public void ForthVoiceDo(double beat)
{
BeatAction.New(instance, new List<BeatAction.Action>()
BeatAction.New(this, new List<BeatAction.Action>()
{
instance.ForthVoiceAction(beat)
ForthVoiceAction(beat)
});
}
@ -960,42 +955,29 @@ namespace HeavenStudio.Games
private static string GetDistanceStringAtBeat(double beat, bool emptyClose = false, bool farFarther = false)
{
// var distanceAtBeat = DistanceAtBeat(beat);
return DistanceAtBeat(beat).ToString();
// if (farFarther)
// {
// return DistanceAtBeat(beat) switch
// {
// DistanceSound.Close => "Close",
// DistanceSound.Far => "Far",
// DistanceSound.Farther => "Far",
// DistanceSound.Farthest => "Farthest",
// _ => throw new System.NotImplementedException()
// };
// }
// else if (emptyClose)
// {
// return DistanceAtBeat(beat) switch
// {
// DistanceSound.Close => "",
// DistanceSound.Far => "Far",
// DistanceSound.Farther => "Farther",
// DistanceSound.Farthest => "Farthest",
// _ => throw new System.NotImplementedException()
// };
// }
// else
// {
// return DistanceAtBeat(beat) switch
// {
// DistanceSound.Close => "Close",
// DistanceSound.Far => "Far",
// DistanceSound.Farther => "Farther",
// DistanceSound.Farthest => "Farthest",
// _ => throw new System.NotImplementedException()
// };
// }
// return DistanceAtBeat(beat).ToString();
if (farFarther)
{
return DistanceAtBeat(beat) switch
{
DistanceSound.Close => "Close",
DistanceSound.Far => "Far",
DistanceSound.Farther => "Far",
DistanceSound.Farthest => "Farthest",
_ => throw new System.NotImplementedException()
};
}
else
{
return DistanceAtBeat(beat) switch
{
DistanceSound.Close => "Close",
DistanceSound.Far => "Far",
DistanceSound.Farther => "Farther",
DistanceSound.Farthest => "Farthest",
_ => throw new System.NotImplementedException()
};
}
}
private static bool TryGetLastDistanceEvent(double beat, out RiqEntity distanceEvent)
@ -1059,7 +1041,7 @@ namespace HeavenStudio.Games
tempCounts.Sort((x, y) => x.beat.CompareTo(y.beat));
BeatAction.New(instance, tempCounts);
BeatAction.New(this, tempCounts);
}
public override void OnPlay(double beat)
@ -1158,11 +1140,11 @@ namespace HeavenStudio.Games
public static void PreStartRally(double beat)
{
if (IsCatchBeat(beat)) return;
if (GameManager.instance.currentGame == "airRally")
{
if (GameManager.instance.TryGetMinigame(out AirRally instance)) {
instance.StartRally(beat);
} else {
wantStartRally = beat;
}
else wantStartRally = beat;
}
private bool recursingRally;
@ -1177,7 +1159,7 @@ namespace HeavenStudio.Games
public static void PreStartBaBumBumBum(double beat, bool count, bool alt)
{
if (IsCatchBeat(beat)) return;
if (GameManager.instance.currentGame == "airRally")
if (GameManager.instance.TryGetMinigame(out AirRally instance))
{
instance.StartBaBumBumBum(beat, count, alt);
}
@ -1225,7 +1207,7 @@ namespace HeavenStudio.Games
new BeatAction.Action(beat, delegate
{
string distanceString = GetDistanceStringAtBeat(beat);
if (PlayerInput.CurrentControlStyle != InputController.ControlStyles.Touch || GameManager.instance.autoplay)
if (PlayerInput.CurrentControlStyle != InputController.ControlStyles.Touch || GameManager.instance.Autoplay)
{
Baxter.DoScaledAnimationAsync((distanceString == "Close") ? "CloseReady" : "FarReady", 0.5f);
}
@ -1345,7 +1327,7 @@ namespace HeavenStudio.Games
}),
new BeatAction.Action(beat + 2f, delegate
{
if (PlayerInput.CurrentControlStyle != InputController.ControlStyles.Touch || GameManager.instance.autoplay)
if (PlayerInput.CurrentControlStyle != InputController.ControlStyles.Touch || GameManager.instance.Autoplay)
{
Baxter.DoScaledAnimationAsync(GetDistanceStringAtBeat(beat + 2f, false, true) + "Ready", 0.5f);
}
@ -1390,7 +1372,7 @@ namespace HeavenStudio.Games
if (IsCatchBeat(caller.startBeat + caller.timer + 1))
{
BeatAction.New(instance, new List<BeatAction.Action>()
BeatAction.New(this, new List<BeatAction.Action>()
{
new BeatAction.Action(caller.startBeat + caller.timer + 1, delegate
{
@ -1427,7 +1409,7 @@ namespace HeavenStudio.Games
if (IsCatchBeat(caller.startBeat + caller.timer + 2))
{
BeatAction.New(instance, new List<BeatAction.Action>()
BeatAction.New(this, new List<BeatAction.Action>()
{
new BeatAction.Action(caller.startBeat + caller.timer + 2, delegate
{

View File

@ -26,11 +26,9 @@ namespace HeavenStudio.Games.Scripts_AirRally
[NonSerialized] public bool isReturning;
[NonSerialized] public bool isTossed = false;
[NonSerialized] public AirRally.DistanceSound currentDist = AirRally.DistanceSound.Close;
AirRally game;
private void Awake()
{
game = AirRally.instance;
rb = GetComponent<Rigidbody2D>();
}

View File

@ -78,7 +78,7 @@ namespace HeavenStudio.Games.Scripts_CropStomp
private void StompJust(PlayerActionEvent caller, float state)
{
if (GameManager.instance.autoplay)
if (GameManager.instance.Autoplay)
{
StompVeggie(true);
return;
@ -103,7 +103,7 @@ namespace HeavenStudio.Games.Scripts_CropStomp
game.bodyAnim.DoScaledAnimationAsync("Pick", 0.5f);
game.isFlicking = true;
if (!pickEligible) return;
if (GameManager.instance.autoplay)
if (GameManager.instance.Autoplay)
{
PickVeggie(true);
return;

View File

@ -225,7 +225,7 @@ namespace HeavenStudio.Games
shouldBeHolding = false;
ScoreMiss();
}
else if (!GameManager.instance.autoplay && shouldBeHolding && !PlayerInput.GetIsAction(InputAction_BasicPressing) && !IsExpectingInputNow(InputAction_FlickRelease))
else if (!GameManager.instance.Autoplay && shouldBeHolding && !PlayerInput.GetIsAction(InputAction_BasicPressing) && !IsExpectingInputNow(InputAction_FlickRelease))
{
student.UnHold();
shouldBeHolding = false;

View File

@ -26,23 +26,8 @@ namespace HeavenStudio.Games.Loaders
}
return null;
}
// // Beatmap.Entities isn't available in a riqentity updater...
// RiqEntity BirdUpdater(string datamodel, RiqEntity e)
// {
// if (datamodel == "dogNinja/CutEverything" && e.version == 0)
// {
// RiqEntity nextBird = eventCaller.gameManager.Beatmap.Entities.Find(c => c.datamodel is "dogNinja/CutEverything" && c.beat > e.beat);
// if (nextBird != null) nextBird.datamodel = "dogNinja/DELETE THIS";
// e.length = nextBird != null ? (float)(nextBird.beat - e.beat) : 4;
// e.version = 1;
// return e;
// }
// return null;
// }
RiqBeatmap.OnUpdateEntity += ObjectUpdater;
// RiqBeatmap.OnUpdateEntity += BirdUpdater;
return new Minigame("dogNinja", "Dog Ninja", "554899", false, false, new List<GameAction>()
{
@ -90,6 +75,7 @@ namespace HeavenStudio.Games.Loaders
new Param("shouldPrepare", true, "Prepare", "Toggle if Dog Ninja should automatically prepare for this cue."),
new Param("muteThrow", false, "Mute", "Toggle if the cue should be muted. This only applies when the cue is started from another game."),
},
defaultVersion = 1,
},
new GameAction("CutEverything", "Mister Eagle's Sign")
{
@ -242,13 +228,13 @@ namespace HeavenStudio.Games
}
// controls stuff
if (PlayerInput.GetIsAction(InputAction_TouchPress) && !GameManager.instance.autoplay)
if (PlayerInput.GetIsAction(InputAction_TouchPress) && !GameManager.instance.Autoplay)
{
// queuePrepare = true;
DogAnim.DoScaledAnimationAsync("Prepare", 0.5f);
preparing = true;
}
if (PlayerInput.GetIsAction(InputAction_TouchRelease) && (!IsExpectingInputNow(InputAction_Press)) && (!GameManager.instance.autoplay))
if (PlayerInput.GetIsAction(InputAction_TouchRelease) && (!IsExpectingInputNow(InputAction_Press)) && (!GameManager.instance.Autoplay))
{
StopPrepare();
DogAnim.DoScaledAnimationAsync("Unprepare", 0.5f);
@ -315,7 +301,7 @@ namespace HeavenStudio.Games
{
if (prepare) {
BeatAction.New(this, new() {
new(beat, () => queuePrepare = PlayerInput.CurrentControlStyle != InputController.ControlStyles.Touch || GameManager.instance.autoplay)
new(beat, () => queuePrepare = PlayerInput.CurrentControlStyle != InputController.ControlStyles.Touch || GameManager.instance.Autoplay)
});
}
for (int i = 0; i < (direction == 2 ? 2 : 1); i++)

View File

@ -933,7 +933,7 @@ namespace HeavenStudio.Games
{
if (who == 3)
{
if (gameManager.autoplay)
if (gameManager.Autoplay)
{
Player.ClapStart(true, false, 0.1f);
}

View File

@ -54,19 +54,19 @@ namespace HeavenStudio.Games.Scripts_FanClub
public void ClapJust(PlayerActionEvent caller, float state)
{
bool auto = GameManager.instance.autoplay;
bool auto = GameManager.instance.Autoplay;
ClapStart(state < 1f && state > -1f, false, auto ? 0.1f : 0f);
}
public void ChargeClapJust(PlayerActionEvent caller, float state)
{
bool auto = GameManager.instance.autoplay;
bool auto = GameManager.instance.Autoplay;
ClapStart(state < 1f && state > -1f, true, auto ? 1f : 0f);
}
public void LongClapJust(PlayerActionEvent caller, float state)
{
bool auto = GameManager.instance.autoplay;
bool auto = GameManager.instance.Autoplay;
ClapStart(state < 1f && state > -1f, false, auto ? 1f : 0f);
}

View File

@ -47,7 +47,7 @@ namespace HeavenStudio.Games.Scripts_GleeClub
{
disappeared = disappear;
sr.color = new Color(1, 1, 1, 1);
if (player && !PlayerInput.GetIsAction(GleeClub.InputAction_BasicPressing) && !GameManager.instance.autoplay)
if (player && !PlayerInput.GetIsAction(GleeClub.InputAction_BasicPressing) && !GameManager.instance.Autoplay)
{
StartSinging();
game.leftChorusKid.MissPose();

View File

@ -168,7 +168,7 @@ namespace HeavenStudio.Games
void Start()
{
if (!PlayerInput.GetIsAction(InputAction_BasicPressing) && Conductor.instance.isPlaying && !GameManager.instance.autoplay)
if (!PlayerInput.GetIsAction(InputAction_BasicPressing) && Conductor.instance.isPlaying && !GameManager.instance.Autoplay)
{
playerChorusKid.StartSinging();
leftChorusKid.MissPose();
@ -276,7 +276,7 @@ namespace HeavenStudio.Games
playerChorusKid.currentPitch = SoundByte.GetPitchFromSemiTones(semiTonesPlayer, true);
leftChorusKid.StartSinging(true);
middleChorusKid.StartSinging(true);
if (!PlayerInput.GetIsAction(InputAction_BasicPressing) || GameManager.instance.autoplay) playerChorusKid.StartSinging(true);
if (!PlayerInput.GetIsAction(InputAction_BasicPressing) || GameManager.instance.Autoplay) playerChorusKid.StartSinging(true);
else missed = true;
}

View File

@ -0,0 +1,86 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using HeavenStudio.Util;
using System.Linq;
using Jukebox;
namespace HeavenStudio.Games.Global
{
public class BlockChecker : MonoBehaviour
{
// abstracted from normal riqentities
// lets you treat stretchy blocks and static blocks the same way, making behavior more consistent
private readonly struct BasicEvent
{
public readonly double beat;
public readonly bool enable;
public BasicEvent(double beat, bool enable)
{
this.beat = beat;
this.enable = enable;
}
}
private List<BasicEvent> allStretchyToggleInputEvents = new List<BasicEvent>();
private List<BasicEvent> allStretchyAutoplayEvents = new List<BasicEvent>();
private void Awake()
{
GameManager.instance.onBeatChanged += OnBeatChanged;
}
public void OnBeatChanged(double beat)
{
allStretchyToggleInputEvents.Clear();
allStretchyAutoplayEvents.Clear();
double toggleInputEndBeat = double.MinValue;
double autoplayEndBeat = double.MinValue;
foreach (RiqEntity e in GameManager.instance.Beatmap.Entities)
{
switch (e.datamodel)
{
case "gameManager/toggle inputs":
if (e.beat >= toggleInputEndBeat) {
allStretchyToggleInputEvents.Add(new(e.beat, e["toggle"]));
}
break;
case "gameManager/toggle inputs stretchy":
toggleInputEndBeat = e.beat + e.length;
allStretchyToggleInputEvents.Add(new(e.beat, false));
allStretchyToggleInputEvents.Add(new(toggleInputEndBeat, true));
break;
case "gameManager/toggle autoplay":
if (e.beat >= autoplayEndBeat) {
allStretchyAutoplayEvents.Add(new(e.beat, e["toggle"]));
}
break;
case "gameManager/toggle autoplay stretchy":
autoplayEndBeat = e.beat + e.length;
allStretchyAutoplayEvents.Add(new(e.beat, true));
allStretchyAutoplayEvents.Add(new(e.beat + e.length, false));
break;
default: break;
}
}
}
private void Update()
{
double songPos = Conductor.instance.songPositionInBeatsAsDouble;
if (allStretchyToggleInputEvents.Count > 0) {
int lastEventIndex = allStretchyToggleInputEvents.FindLastIndex(e => e.beat < songPos);
// if index is invalid, toggle inputs on. else get the last event's enable bool
bool toggleInputs = lastEventIndex < 0 || allStretchyToggleInputEvents[lastEventIndex].enable;
GameManager.instance.ToggleInputs(toggleInputs);
}
if (allStretchyAutoplayEvents.Count > 0) {
int lastEventIndex = allStretchyAutoplayEvents.FindLastIndex(e => e.beat < songPos);
bool autoplay = lastEventIndex >= 0 && allStretchyAutoplayEvents[lastEventIndex].enable;
GameManager.instance.ToggleScheduledAutoplay(autoplay);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c3d236f69217641448fbb6133136ad56
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -103,7 +103,6 @@ namespace HeavenStudio.Games.Global
private void OnBeatChanged(double beat)
{
allFilterEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "filter" });
allFilterEvents.Sort((x, y) => x.beat.CompareTo(y.beat));
foreach (var a in amplifies)
{
a.LutTexture = null;

View File

@ -39,10 +39,9 @@ namespace HeavenStudio.Games.Global
public void OnBeatChanged(double beat)
{
allFadeEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "flash" });
// backwards-compatibility baybee
allFadeEvents.AddRange(EventCaller.GetAllInGameManagerList("gameManager", new string[] { "flash" }));
allFadeEvents.Sort((x, y) => x.beat.CompareTo(y.beat));
// fixes a bug where deleted flashes on beat 0 will persist until placing a new one
SetFade(0, 0, new Color(), new Color(), Util.EasingFunction.Ease.Instant);
FindFadeFromBeat(beat);
}
@ -55,7 +54,7 @@ namespace HeavenStudio.Games.Global
if (allFadeEvents.Count > 0)
{
RiqEntity startEntity = default(RiqEntity);
RiqEntity startEntity = default;
for (int i = 0; i < allFadeEvents.Count; i++)
{

View File

@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -91,10 +92,35 @@ namespace HeavenStudio.Games.Global
OpenCaptionsEnabler.SetActive(false);
ClosedCaptionsEnabler.SetActive(false);
textboxEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "display textbox" });
openCaptionsEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "display open captions" });
idolEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "display song artist" });
closedCaptionsEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "display closed captions" });
// System.Diagnostics.Stopwatch sw = new();
// sw.Restart();
textboxEvents.Clear();
openCaptionsEvents.Clear();
idolEvents.Clear();
closedCaptionsEvents.Clear();
foreach (var entity in GameManager.instance.Beatmap.Entities)
{
switch (entity.datamodel)
{
case "vfx/display textbox":
textboxEvents.Add(entity);
break;
case "vfx/display open captions":
openCaptionsEvents.Add(entity);
break;
case "vfx/display song artist":
idolEvents.Add(entity);
break;
case "vfx/display closed captions":
closedCaptionsEvents.Add(entity);
break;
default: break;
}
}
// sw.Stop();
// Debug.Log("ONCE took " + sw.Elapsed.TotalMilliseconds + " ms.");
UpdateTextboxDisplay();
UpdateOpenCaptionsDisplay();

View File

@ -220,16 +220,19 @@ namespace HeavenStudio.Games.Loaders
{
function = delegate {
var e = eventCaller.currentEntity;
KarateMan.instance.DoWord(e.beat, e.length, e["whichWarning"], e["pitchVoice"], e["forcePitch"], e["customLength"]);
KarateMan.instance.DoWord(e.beat, e.length, e["whichWarning"], e["pitchVoice"], e["forcePitch"], e["customLength"], !e["mute"]);
},
defaultLength = 1f,
resizable = true,
parameters = new List<Param>()
{
new Param("whichWarning", KarateMan.HitThree.HitThree, "Warning", "Choose the warning text to show and the sfx to play."),
new Param("mute", false, "Mute", "Toggle if the voice should play.", new List<Param.CollapseParam>() {
new((x, _) => !(bool)x, "pitchVoice", "forcePitch", "customLength", "cutOut")
}),
new Param("pitchVoice", false, "Pitch Voice", "Toggle if the voice should be pitched.", new List<Param.CollapseParam>()
{
new Param.CollapseParam((x, _) => (bool)x, new string[] { "forcePitch" }),
new Param.CollapseParam((x, _) => (bool)x, "forcePitch"),
}),
new Param("forcePitch", new EntityTypes.Float(0.5f, 2f, 1f), "Force Pitch", "Set the pitching of the voice, or keep it at 1 for automatic pitching."),
new Param("customLength", false, "Stretchable Length", "Toggle if the text should appear for the entire length of the event."),
@ -237,19 +240,19 @@ namespace HeavenStudio.Games.Loaders
},
inactiveFunction = delegate {
var e = eventCaller.currentEntity;
KarateMan.DoWordSound(e.beat, e.length, e["whichWarning"], e["pitchVoice"], e["forcePitch"], e["customLength"]);
if (!e["mute"]) KarateMan.DoWordSound(e.beat, e.length, e["whichWarning"], e["pitchVoice"], e["forcePitch"], e["customLength"]);
}
},
new GameAction("special camera", "Special Camera")
{
function = delegate { var e = eventCaller.currentEntity; KarateMan.DoSpecialCamera(e.beat, e.length, e["toggle"]); },
inactiveFunction = delegate { var e = eventCaller.currentEntity; KarateMan.DoSpecialCamera(e.beat, e.length, e["toggle"]); },
defaultLength = 8f,
resizable = true,
parameters = new List<Param>()
{
new Param("toggle", true, "Return Camera", "Toggle if the camera should zoom back in."),
},
inactiveFunction = delegate { var e = eventCaller.currentEntity; KarateMan.DoSpecialCamera(e.beat, e.length, e["toggle"]); }
},
new GameAction("prepare", "Prepare")
{
@ -558,7 +561,7 @@ namespace HeavenStudio.Games
[Header("Backgrounds")]
private ColorEase[] colorEases = new ColorEase[3];
public int currentBgEffect = (int)BackgroundFXType.None;
public BackgroundFXType currentBgEffect = BackgroundFXType.None;
public SpriteRenderer BGPlane;
public GameObject BGEffect;
@ -665,7 +668,7 @@ namespace HeavenStudio.Games
public static PlayerInput.InputAction InputAction_TouchUp =
new("KarateAltUp", new int[] { IAEmptyCat, IAReleaseCat, IAEmptyCat },
IA_PadAltUp, IA_EmptyTouchUp, IA_BatonAltUp);
public List<RiqEntity> specialEntities, hitVoiceEntities = new();
public List<RiqEntity> specialEntities, hitVoiceEntities;
public static KarateMan instance;
@ -691,44 +694,66 @@ namespace HeavenStudio.Games
Update();
}
public override void OnPlay(double beat) => OnGameSwitch(beat);
public override void OnGameSwitch(double beat)
{
EntityPreCheck(beat);
public override void OnStop(double beat) => EntityPreCheck(beat, false);
public override void OnPlay(double beat) => EntityPreCheck(beat, true);
public override void OnGameSwitch(double beat) => EntityPreCheck(beat, true);
var entities = gameManager.Beatmap.Entities.FindAll(e => (e.datamodel is "karateman/hit" or "karateman/bulb" or "karateman/kick" or "karateman/combo") && e.beat < beat && e.beat + 1 > beat);
// queued objects
foreach (var e in entities)
{
switch (e.datamodel) {
case "karateman/hit": CreateItem(e.beat, e["type"], e["type2"]); break;
case "karateman/bulb": CreateBulbSpecial(e.beat, e["type"], e["colorA"], e["type2"], e["sfx"], e["hitSfx"]); break;
case "karateman/kick": Kick(e.beat, e["toggle"], e["shouldGlow"], e["type"], e["pitchVoice"], e["forcePitch"], e["cutOut"], e["disableVoice"], e["woodColor"], e["hoopColor"]); break;
case "karateman/combo": Combo(e.beat, e["type"], e["pitchVoice"], e["forcePitch"], e["cutOut"], e["disableVoice"]); break;
default: Debug.LogError($"Karate Man has failed to cue an object with datamodel {e.datamodel} at beat {e.beat}"); break;
}
}
}
public override void OnStop(double beat) => EntityPreCheck(beat);
void EntityPreCheck(double beat)
private void EntityPreCheck(double beat, bool checkCues)
{
if (gameManager == null) return;
List<RiqEntity> prevEntities = gameManager.Beatmap.Entities.FindAll(c => c.datamodel.Split(0) == "karateman");
RiqEntity voice = prevEntities.FindLast(c => c.beat < beat && c.datamodel == "karateman/warnings");
if (wordClearTime > beat && wordStartTime < beat && voice != null)
specialEntities = new();
hitVoiceEntities = new();
RiqEntity bg = null, obj = null, voice = null, bop = null, flow = null;
foreach (var e in gameManager.Beatmap.Entities)
{
if (e.beat >= beat) {
if (e.datamodel is "karateman/kick" or "karateman/combo") {
specialEntities.Add(e);
}
if (e.datamodel is "karateman/warnings" && e["whichWarning"] <= (int)HitThree.HitFour) {
hitVoiceEntities.Add(e);
}
}
// if (e.beat <= beat) {
if (e.beat < beat) {
if (checkCues && e.beat + 1 > beat) {
switch (e.datamodel) {
case "karateman/hit": CreateItem(e.beat, e["type"], e["type2"]); break;
case "karateman/bulb": CreateBulbSpecial(e.beat, e["type"], e["colorA"], e["type2"], e["sfx"], e["hitSfx"]); break;
case "karateman/kick": Kick(e.beat, e["toggle"], e["shouldGlow"], e["type"], e["pitchVoice"], e["forcePitch"], e["cutOut"], e["disableVoice"], e["woodColor"], e["hoopColor"]); break;
case "karateman/combo": Combo(e.beat, e["type"], e["pitchVoice"], e["forcePitch"], e["cutOut"], e["disableVoice"]); break;
default: /* Debug.LogError($"Karate Man has failed to cue an object with datamodel {e.datamodel} at beat {e.beat}"); */ break;
}
}
switch (e.datamodel)
{
case "karateman/background appearance":
bg = e;
break;
case "karateman/set object colors":
obj = e;
break;
case "karateman/warnings":
voice = e;
break;
case "karateman/bop":
bop = e;
break;
case "karateman/set gameplay modifiers":
flow = e;
break;
default: break;
}
}
}
ToggleBop(0, 0, false, bop?["toggle"] ?? true);
if (wordClearTime > beat && wordStartTime < beat && voice != null) {
DoWord(voice.beat, voice.length, voice["whichWarning"], false, 1, voice["customLength"], false);
}
// init colors
RiqEntity bg = prevEntities.FindLast(c => c.beat <= beat && c.datamodel == "karateman/background appearance");
RiqEntity obj = prevEntities.FindLast(c => c.beat <= beat && c.datamodel == "karateman/set object colors");
if (bg != null)
{
if (bg != null) {
BackgroundColor(
bg.beat, bg.length, bg["fxType"],
bg["presetBg"], bg["startColor"], bg["endColor"], bg["ease"],
@ -737,30 +762,16 @@ namespace HeavenStudio.Games
);
}
if (obj != null)
{
if (obj != null) {
UpdateMaterialColour(obj["colorA"], obj["colorB"], obj["colorC"], obj["colorD"], obj["star"]);
}
else
{
} else {
UpdateMaterialColour(Color.white, new Color(0.81f, 0.81f, 0.81f), Color.white, Color.white, (int)StarColorOption.ItemColor);
}
// init modifier(s)
RiqEntity bop = prevEntities.FindLast(c => c.beat < beat && c.datamodel == "karateman/bop");
RiqEntity flow = prevEntities.FindLast(c => c.beat < beat && c.datamodel == "karateman/set gameplay modifiers");
ToggleBop(0, 0, false, bop?["toggle"] ?? true);
if (flow != null)
{
if (flow != null) {
int fxType = bg == null || flow.beat > bg.beat ? flow["fxType"] : bg["fxType"];
SetGameplayMods(beat, fxType, flow["type"], flow["combo"]);
}
// get all entities to later check against eachother to cut out voices
specialEntities = prevEntities.FindAll(c => c.beat >= beat && (c.datamodel is "karateman/kick" or "karateman/combo"));
hitVoiceEntities = prevEntities.FindAll(c => c.beat > beat && (c.datamodel is "karateman/warnings" && c["whichWarning"] <= (int)HitThree.HitFour));
}
@ -768,17 +779,17 @@ namespace HeavenStudio.Games
{
var songPos = conductor.songPositionInBeatsAsDouble;
// if (conductor != null && !conductor.isPlaying)
// {
// EntityPreCheck(songPos);
// }
if (conductor != null && !conductor.isPlaying)
{
EntityPreCheck(songPos, false);
}
switch (currentBgEffect)
{
case (int)BackgroundFXType.Sunburst:
case BackgroundFXType.Sunburst:
bgEffectAnimator.DoNormalizedAnimation("Sunburst", (float)(songPos * 0.5) % 1f);
break;
case (int)BackgroundFXType.Rings:
case BackgroundFXType.Rings:
bgEffectAnimator.DoNormalizedAnimation("Rings", (float)(songPos * 0.5) % 1f);
break;
default:
@ -793,9 +804,7 @@ namespace HeavenStudio.Games
if (songPos >= startCamSpecial && songPos <= wantsReturn)
{
float camX = 0f;
float camY = 0f;
float camZ = 0f;
float camX, camY, camZ;
if (songPos <= startCamSpecial + cameraReturnLength)
{
float prog = conductor.GetPositionFromBeat(startCamSpecial, cameraReturnLength);
@ -820,7 +829,10 @@ namespace HeavenStudio.Games
else
{
if (cameraAngle == CameraAngle.Special)
{
cameraAngle = CameraAngle.Normal;
}
cameraPosition = CameraPosition[0].position;
}
@ -831,7 +843,7 @@ namespace HeavenStudio.Games
private void OnDestroy()
{
foreach (var evt in scheduledInputs)
foreach (PlayerActionEvent evt in scheduledInputs)
{
evt.Disable();
}
@ -848,7 +860,7 @@ namespace HeavenStudio.Games
private static LightBulbType GetNextSpecial(double beat)
{
var entities = instance != null ? instance.specialEntities : null;
List<RiqEntity> entities = instance != null ? instance.specialEntities : null;
RiqEntity nextSpecial = entities != null ?
(entities.Count > 0 ? entities.Find(e => e.beat >= beat) : null) :
GameManager.instance.Beatmap.Entities.Find(c => c.beat >= beat && (c.datamodel is "karateman/combo" or "karateman/kick"));
@ -889,15 +901,15 @@ namespace HeavenStudio.Games
{
string number = ((HitThree)type).ToString()[3..];
number = char.ToLower(number[0]).ToString() + number[1..];
var sounds = new MultiSound.Sound[] {
new MultiSound.Sound($"karateman/{(type == (int)HitThree.HitThreeAlt ? "hitAlt" : "hit")}", beat + 0.5f, offset: 0.042f),
new MultiSound.Sound($"karateman/{number}", beat + 1f),
List<MultiSound.Sound> sounds = new List<MultiSound.Sound> {
new($"karateman/{(type == (int)HitThree.HitThreeAlt ? "hitAlt" : "hit")}", beat + 0.5f, offset: 0.042f),
new($"karateman/{number}", beat + 1f),
};
Array.ForEach(sounds, x => x.pitch = bpmPitch ? Conductor.instance.GetBpmAtBeat(x.beat) / PITCH_MOD : forcePitch);
sounds.ForEach(x => x.pitch = bpmPitch ? Conductor.instance.GetBpmAtBeat(x.beat) / PITCH_MOD : forcePitch);
MultiSound.Play(sounds, forcePlay: true);
}
var songPos = Conductor.instance.songPositionInBeatsAsDouble;
double songPos = Conductor.instance.songPositionInBeatsAsDouble;
if (songPos <= clear && songPos >= beat)
{
wordClearTime = customLength ? (beat + length) : clear;
@ -1083,7 +1095,7 @@ namespace HeavenStudio.Games
public void BackgroundColor(double beat, float length, int fxType, int presetBG, Color colorStart, Color colorEnd, int colorEaseSet, int shadowType, Color shadowStart, Color shadowEnd, int textureType, bool autoColor, Color filterStart, Color filterEnd)
{
currentBgEffect = fxType;
currentBgEffect = (BackgroundFXType)fxType;
bool preset = presetBG != (int)BackgroundType.Custom;
bool tinted = shadowType == (int)ShadowType.Tinted;
@ -1124,9 +1136,8 @@ namespace HeavenStudio.Games
{
NoriGO.SetActive(true);
Nori.SetNoriMode(beat, mode);
currentBgEffect = fxType;
currentBgEffect = (BackgroundFXType)fxType;
IsComboEnable = (ComboMode)combo;
// IsKickEnable = kick;
}
public enum StarColorOption
@ -1148,7 +1159,9 @@ namespace HeavenStudio.Games
{
if (type == (int)ParticleType.None)
{
foreach (var eff in Effects) eff.Stop();
foreach (ParticleSystem eff in Effects) {
eff.Stop();
}
return;
}
@ -1157,8 +1170,8 @@ namespace HeavenStudio.Games
particleSystem.gameObject.SetActive(true);
particleSystem.Play();
var emm = particleSystem.emission;
var main = particleSystem.main;
ParticleSystem.EmissionModule emm = particleSystem.emission;
ParticleSystem.MainModule main = particleSystem.main;
emm.rateOverTime = particleStrength * (type == (int)ParticleType.Rain ? 32f : 6f);
main.prewarm = instant;
@ -1177,9 +1190,11 @@ namespace HeavenStudio.Games
{
if (toggle)
{
var actions = new List<BeatAction.Action>();
for (int i = 0; i < length; i++) actions.Add(new(beat + i, delegate { Joe.Bop(); }));
BeatAction.New(instance, actions);
List<BeatAction.Action> actions = new List<BeatAction.Action>();
for (int i = 0; i < length; i++) {
actions.Add(new(beat + i, delegate { Joe.Bop(); }));
}
BeatAction.New(this, actions);
}
}

View File

@ -181,7 +181,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
}
}
if ((!GameManager.instance.autoplay)
if ((!GameManager.instance.Autoplay)
&& (PlayerInput.GetIsAction(KarateMan.InputAction_Flick) || PlayerInput.GetIsAction(KarateMan.InputAction_BasicRelease))
&& !PlayerInput.GetIsAction(KarateMan.InputAction_Pressing))
{

View File

@ -66,6 +66,15 @@ namespace HeavenStudio.Games.Loaders
new Param("visual", true, "Background Visual", "Toggle if the background will automatically flip depending on if it's on or off beat.")
}
},
new GameAction("stopStepping", "Stop Stepping")
{
preFunction = delegate {
var e = eventCaller.currentEntity;
Lockstep.instance.StopStepping();
},
defaultLength = 1f,
preFunctionLength = 0.5f,
},
new GameAction("hai", "Hai")
{
preFunction = delegate { Lockstep.HaiSound(eventCaller.currentEntity.beat); }
@ -223,6 +232,7 @@ namespace HeavenStudio.Games
public GameEvent bop = new GameEvent();
List<double> switches = new();
private List<RiqEntity> bachEvents = new();
private bool stopStepping;
public static Lockstep instance;
@ -615,6 +625,11 @@ namespace HeavenStudio.Games
if (actions.Count > 0) BeatAction.New(instance, actions);
}
public void StopStepping()
{
stopStepping = true;
}
private struct QueuedMarch
{
public double beat;
@ -712,6 +727,11 @@ namespace HeavenStudio.Games
private void MarchRecursive(double beat)
{
Debug.Log(stopStepping);
if (stopStepping) {
marchRecursing = false;
return;
}
marchRecursing = true;
if (NextStepIsSwitch(beat)) beat -= 0.5;
bool offBeat = beat % 1 != 0;

View File

@ -100,7 +100,7 @@ namespace HeavenStudio.Games
if (minigame != GameManager.instance.currentGame) return;
double normalizedTime = GetNormalizedTime();
if (gm.autoplay && gm.canInput)
if (gm.Autoplay && gm.canInput)
{
AutoplayInput(normalizedTime);
return;
@ -118,18 +118,9 @@ namespace HeavenStudio.Games
return;
}
if (!autoplayOnly && (IsHittable == null || IsHittable != null && IsHittable()) && IsCorrectInput(out double dt))
if (!autoplayOnly && (IsHittable == null || (IsHittable != null && IsHittable())))
{
normalizedTime -= dt;
if (IsExpectingInputNow(cond))
{
double stateProg = ((normalizedTime - Minigame.JustEarlyTime(cond.SongPitch, margin)) / (Minigame.JustLateTime(cond.SongPitch, margin) - Minigame.JustEarlyTime(cond.SongPitch, margin)) - 0.5f) * 2;
Hit(stateProg, normalizedTime, cond.SongPitch);
}
else
{
Blank();
}
TryInput(false, normalizedTime);
}
}
@ -178,7 +169,7 @@ namespace HeavenStudio.Games
private void AutoplayInput(double normalizedTime, bool autoPlay = false)
{
if (triggersAutoplay && (GameManager.instance.autoplay || autoPlay) && normalizedTime >= 1f - (Time.deltaTime * 0.5f))
if (triggersAutoplay && GameManager.instance.Autoplay && normalizedTime >= 1f - (Time.deltaTime * 0.5f))
{
AutoplayEvent();
if (!autoPlay)
@ -189,8 +180,8 @@ namespace HeavenStudio.Games
// TODO: move this to timeline code instead
private void TimelineAutoplay()
{
if (Editor.Editor.instance == null) return;
if (!GameManager.instance.canInput) return;
if (!GameManager.instance.userAutoplay) return;
if (Editor.Editor.instance == null || !GameManager.instance.canInput) return;
if (Editor.Track.Timeline.instance != null && !Editor.Editor.instance.fullscreen)
{
Editor.Track.Timeline.instance.AutoplayBTN.GetComponent<Animator>().Play("Ace", 0, 0);
@ -210,7 +201,7 @@ namespace HeavenStudio.Games
return normalizedBeat > Minigame.NgEarlyTime(cond.SongPitch, margin) && normalizedBeat < Minigame.NgLateTime(cond.SongPitch, margin);
}
double GetNormalizedTime()
private double GetNormalizedTime()
{
var cond = Conductor.instance;
double currTime = cond.songPositionAsDouble;
@ -235,11 +226,35 @@ namespace HeavenStudio.Games
else
{
double normalizedBeat = GetNormalizedTime();
double stateProg = ((normalizedBeat - Minigame.JustEarlyTime()) / (Minigame.JustLateTime() - Minigame.JustEarlyTime()) - 0.5f) * 2;
double stateProg = (((normalizedBeat - Minigame.JustEarlyTime()) / (Minigame.JustLateTime() - Minigame.JustEarlyTime())) - 0.5f) * 2;
Hit(stateProg, normalizedBeat);
}
}
public bool TryInput(bool force, double normalizedTime = double.NaN)
{
var cond = Conductor.instance;
if (IsCorrectInput(out double dt) || force) {
if (double.IsNaN(normalizedTime)) {
normalizedTime = GetNormalizedTime();
}
// dt is 0 when force == true
normalizedTime -= dt;
if (IsExpectingInputNow(cond))
{
double stateProg = (((normalizedTime - Minigame.JustEarlyTime(cond.SongPitch, margin)) / (Minigame.JustLateTime(cond.SongPitch, margin) - Minigame.JustEarlyTime(cond.SongPitch, margin))) - 0.5f) * 2;
Hit(stateProg, normalizedTime, cond.SongPitch);
}
else
{
Blank();
}
return true;
} else {
return false;
}
}
//The state parameter is either -1 -> Early, 0 -> Perfect, 1 -> Late
public void Hit(double state, double time, float pitch = 1)
{

View File

@ -29,7 +29,7 @@ namespace HeavenStudio.Games.Scripts_RhythmRally
void Update()
{
if (PlayerInput.CurrentControlStyle == InputController.ControlStyles.Touch && !GameManager.instance.autoplay)
if (PlayerInput.CurrentControlStyle == InputController.ControlStyles.Touch && !GameManager.instance.Autoplay)
{
if (PlayerInput.GetIsAction(RhythmRally.InputAction_BasicPress))
{

View File

@ -341,7 +341,7 @@ namespace HeavenStudio.Games
{
if (served)
{
if (PlayerInput.CurrentControlStyle != InputController.ControlStyles.Touch || GameManager.instance.autoplay)
if (PlayerInput.CurrentControlStyle != InputController.ControlStyles.Touch || GameManager.instance.Autoplay)
{
if ((playerState.IsName("Swing") && playerAnim.IsAnimationNotPlaying()) || (!playerState.IsName("Swing") && !playerState.IsName("Ready1")))
playerAnim.Play("Ready1");

View File

@ -747,7 +747,7 @@ namespace HeavenStudio.Games
{
if (JJ.together || Soshi.together) return;
JJ.PrepareTogether(true);
Soshi.PrepareTogether(GameManager.instance.autoplay);
Soshi.PrepareTogether(GameManager.instance.Autoplay);
}),
new BeatAction.Action(beat + 3, delegate
{
@ -802,7 +802,7 @@ namespace HeavenStudio.Games
{
if (JJ.together || Soshi.together) return;
JJ.PrepareTogether(true);
Soshi.PrepareTogether(GameManager.instance.autoplay);
Soshi.PrepareTogether(GameManager.instance.Autoplay);
}),
new BeatAction.Action(beat + 3, delegate
{
@ -872,7 +872,7 @@ namespace HeavenStudio.Games
{
if (JJ.together || Soshi.together) return;
JJ.PrepareTogether(goToMiddleBeat == muteBeat);
Soshi.PrepareTogether(goToMiddleBeat == muteBeat && GameManager.instance.autoplay);
Soshi.PrepareTogether(goToMiddleBeat == muteBeat && GameManager.instance.Autoplay);
}),
new BeatAction.Action(beat + muteBeat, delegate
{
@ -1011,7 +1011,7 @@ namespace HeavenStudio.Games
{
new BeatAction.Action(beat, delegate
{
if (GameManager.instance.autoplay) Soshi.UnHold();
if (GameManager.instance.Autoplay) Soshi.UnHold();
if (JJ.together || Soshi.together)
{
JJ.ReturnBack();
@ -1064,7 +1064,7 @@ namespace HeavenStudio.Games
}
if (whoMutes is (int)WhoMutes.Soshi or (int)WhoMutes.Both)
{
if (GameManager.instance.autoplay) Soshi.Mute();
if (GameManager.instance.Autoplay) Soshi.Mute();
}
}
@ -1076,7 +1076,7 @@ namespace HeavenStudio.Games
}
if (whoMutes is (int)WhoMutes.Soshi or (int)WhoMutes.Both)
{
if (GameManager.instance.autoplay) Soshi.UnHold(true);
if (GameManager.instance.Autoplay) Soshi.UnHold(true);
}
}

View File

@ -91,7 +91,7 @@ namespace HeavenStudio.Games.Scripts_Rockers
else
{
if (strumming) strumEffect.GetComponent<Animator>().Play("StrumIdle", 0, 0);
if (PlayerInput.GetIsAction(Rockers.InputAction_BasicPressing) || (GameManager.instance.autoplay && muted))
if (PlayerInput.GetIsAction(Rockers.InputAction_BasicPressing) || (GameManager.instance.Autoplay && muted))
{
DoScaledAnimationAsync("Crouch", 0.5f);
}

View File

@ -173,7 +173,7 @@ namespace HeavenStudio.Games
public void ForceReload()
{
if (hasArrowLoaded) return;
if (PlayerInput.CurrentControlStyle == InputController.ControlStyles.Touch && !GameManager.instance.autoplay)
if (PlayerInput.CurrentControlStyle == InputController.ControlStyles.Touch && !GameManager.instance.Autoplay)
{
bowAnim.DoScaledAnimationAsync("BowIdle", 1f);
}
@ -218,7 +218,7 @@ namespace HeavenStudio.Games
{
ScheduleInput(beat, length * 7, InputAction_FlickPress, JustNoSlowDown, Miss, Out);
}
if (PlayerInput.CurrentControlStyle == InputController.ControlStyles.Touch && !GameManager.instance.autoplay)
if (PlayerInput.CurrentControlStyle == InputController.ControlStyles.Touch && !GameManager.instance.Autoplay)
{
BeatAction.New(instance, new List<BeatAction.Action>()
{

View File

@ -91,7 +91,7 @@ namespace HeavenStudio.Games.Scripts_Spaceball
SoundByte.PlayOneShotGame("spaceball/hit");
// jank fix for a bug with autoplay - freeform
if (GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput)
if (GameManager.instance.Autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput)
{
SoundByte.PlayOneShotGame("spaceball/swing");
}

View File

@ -366,7 +366,7 @@ namespace HeavenStudio.Games
}
if (PlayerInput.CurrentControlStyle == InputController.ControlStyles.Touch)
{
if (PlayerInput.GetIsAction(InputAction_TouchRelease) && !gameManager.autoplay)
if (PlayerInput.GetIsAction(InputAction_TouchRelease) && !gameManager.Autoplay)
{
player.UnPrepare();
shouldHold = false;
@ -374,7 +374,7 @@ namespace HeavenStudio.Games
}
else
{
if (PlayerInput.GetIsAction(InputAction_BasicRelease) && shouldHold && (!gameManager.autoplay) && !IsExpectingInputNow(InputAction_FlickRelease))
if (PlayerInput.GetIsAction(InputAction_BasicRelease) && shouldHold && (!gameManager.Autoplay) && !IsExpectingInputNow(InputAction_FlickRelease))
{
if (doingPoses)
{

View File

@ -168,7 +168,7 @@ namespace HeavenStudio
public static bool PlayerHasControl()
{
if (GameManager.instance == null || Conductor.instance == null) return true;
return !GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput;
return !GameManager.instance.Autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput;
}
/*--------------------*/

View File

@ -328,13 +328,13 @@ namespace HeavenStudio.Editor.Track
public void AutoBtnUpdate()
{
var animName = GameManager.instance.autoplay ? "Idle" : "Disabled";
var animName = GameManager.instance.userAutoplay ? "Idle" : "Disabled";
AutoplayBTN.GetComponent<Animator>().Play(animName, 0, 0);
}
public void AutoPlayToggle()
{
if (!GameManager.instance.autoplay)
if (!GameManager.instance.userAutoplay)
{
AutoplayBTN.GetComponent<Animator>().Play("Idle", 0, 0);
GameManager.instance.ToggleAutoplay(true);

View File

@ -752,7 +752,7 @@ namespace HeavenStudio
/// <summary>
/// Class that decides how other parameters will be collapsed
/// </summary>
/// <param name="collapseOn">What values should make it collapse/uncollapse?</param>
/// <param name="collapseOn">What values should make it collapse/uncollapse? (False makes the parameters collapse.)</param>
/// <param name="collapseables">IDs of the parameters to collapse</param>
public CollapseParam(Func<object, RiqEntity, bool> collapseOn, params string[] collapseables)
{
@ -782,10 +782,11 @@ namespace HeavenStudio
new GameAction("end", "End Remix", "", 0.5f,
function: delegate {
Debug.Log("end");
if (Timeline.instance != null)
Timeline.instance?.Stop(Timeline.instance.PlaybackBeat);
else
if (Timeline.instance != null) {
Timeline.instance.Stop(Timeline.instance.PlaybackBeat);
} else {
GameManager.instance.Stop(eventCaller.currentEntity.beat);
}
}
),
new GameAction("skill star", "Skill Star", "", 1f, true)
@ -796,16 +797,15 @@ namespace HeavenStudio
Common.SkillStarManager.instance.DoStarIn(e.beat, e.length);
}
},
new GameAction("toggle inputs", "Toggle Inputs", "", 0.5f, true,
new List<Param>()
{
new Param("toggle", true, "Allow Inputs", "Toggle if the player is able to input. Any missed cues while this is disabled will not be counted as a miss and will not break a perfect.")
},
delegate
{
GameManager.instance.ToggleInputs(eventCaller.currentEntity["toggle"]);
}
// handled with entity checking; look at BlockChecker.cs
new GameAction("toggle inputs", "Toggle Inputs", "", 0.5f, false,
new() { new Param("toggle", false, "Allow Inputs", "Toggle if the player is able to input. Any missed cues while this is enabled will not be counted as a miss and will not break a perfect.") }
),
new GameAction("toggle inputs stretchy", "Toggle Inputs (Stretchy)", "", 1, true),
new GameAction("toggle autoplay", "Toggle Autoplay", "", 0.5f, false,
new() { new Param("toggle", true, "Autoplay", "Toggle if autoplay should be on. Any inputs while this is enabled will be hit with ace timing.") }
),
new GameAction("toggle autoplay stretchy", "Toggle Autoplay (Stretchy)", "", 1, true),
}),
new Minigame("countIn", "Count-Ins", "", false, true, new List<GameAction>()
@ -1455,6 +1455,15 @@ namespace HeavenStudio
GameManager.PlaySFXArbitrary(e.beat, e.length, e["game"].CurrentValue, e["sfxName"].CurrentValue, pitch, e["volume"], e["loop"], e["offset"]);
}
),
new GameAction("fake input", "Fake Input", "Play", 0.5f, true,
function : delegate {
if (GameManager.instance.minigame != null) {
foreach (var input in GameManager.instance.minigame.scheduledInputs) {
input.TryInput(true);
}
}
}
),
}),
};

View File

@ -21,6 +21,10 @@ namespace HeavenStudio
private void Awake()
{
_volume = GetComponent<PostProcessVolume>();
UpdateRetroTV();
UpdateAnalogNoise();
UpdateSobelNeons();
UpdatePixelizes();
}
private void Start()
@ -30,19 +34,66 @@ namespace HeavenStudio
public void OnBeatChanged(double beat)
{
_vignettes = EventCaller.GetAllInGameManagerList("vfx", new string[] { "vignette" });
_cabbs = EventCaller.GetAllInGameManagerList("vfx", new string[] { "cabb" });
_blooms = EventCaller.GetAllInGameManagerList("vfx", new string[] { "bloom" });
_lensDs = EventCaller.GetAllInGameManagerList("vfx", new string[] { "lensD" });
_grains = EventCaller.GetAllInGameManagerList("vfx", new string[] { "grain" });
_colorGradings = EventCaller.GetAllInGameManagerList("vfx", new string[] { "colorGrading" });
UpdateVignette();
UpdateChromaticAbberations();
UpdateBlooms();
UpdateLensDistortions();
UpdateGrain();
UpdateColorGrading();
_vignettes.Clear();
_cabbs.Clear();
_blooms.Clear();
_lensDs.Clear();
_grains.Clear();
_colorGradings.Clear();
_retroTvs.Clear();
_scanJitters.Clear();
_gaussBlurs.Clear();
_analogNoises.Clear();
_screenJumps.Clear();
_sobelNeons.Clear();
_pixelizeQuads.Clear();
foreach (var entity in GameManager.instance.Beatmap.Entities)
{
switch (entity.datamodel)
{
case "vfx/vignette":
_vignettes.Add(entity);
break;
case "vfx/cabb":
_cabbs.Add(entity);
break;
case "vfx/bloom":
_blooms.Add(entity);
break;
case "vfx/lensD":
_lensDs.Add(entity);
break;
case "vfx/grain":
_grains.Add(entity);
break;
case "vfx/colorGrading":
_colorGradings.Add(entity);
break;
case "vfx/retroTv":
_retroTvs.Add(entity);
break;
case "vfx/scanJitter":
_scanJitters.Add(entity);
break;
case "vfx/gaussBlur":
_gaussBlurs.Add(entity);
break;
case "vfx/analogNoise":
_analogNoises.Add(entity);
break;
case "vfx/screenJump":
_screenJumps.Add(entity);
break;
case "vfx/sobelNeon":
_sobelNeons.Add(entity);
break;
case "vfx/pixelQuad":
_pixelizeQuads.Add(entity);
break;
default: break;
}
}
Update();
}
private void Update()
@ -53,6 +104,13 @@ namespace HeavenStudio
UpdateLensDistortions();
UpdateGrain();
UpdateColorGrading();
UpdateRetroTV();
UpdateScanJitter();
UpdateGaussBlur();
UpdateAnalogNoise();
UpdateScreenJumps();
UpdateSobelNeons();
UpdatePixelizes();
}
private void UpdateVignette()
@ -223,6 +281,175 @@ namespace HeavenStudio
}
}
private void UpdateRetroTV()
{
if (!_volume.profile.TryGetSettings<CRT>(out var t)) return;
t.enabled.Override(false);
foreach (var e in _retroTvs)
{
float normalized = Conductor.instance.GetPositionFromBeat(e.beat, e.length);
if (normalized < 0) break;
float clampNormal = Mathf.Clamp01(normalized);
var func = Util.EasingFunction.GetEasingFunction((Util.EasingFunction.Ease)e["ease"]);
float newIntensity = func(e["intenStart"], e["intenEnd"], clampNormal);
t.enabled.Override(newIntensity != 0);
if (!t.enabled) continue;
t.distort.Override(newIntensity);
float newRGBBlend = func(e["rgbStart"], e["rgbEnd"], clampNormal);
t.RGBBlend.Override(newRGBBlend);
float newBottomCollapse = func(e["bottomStart"], e["bottomEnd"], clampNormal);
t.BottomCollapse.Override(newBottomCollapse);
float newNoiseAmount = func(e["noiseStart"], e["noiseEnd"], clampNormal);
t.NoiseAmount.Override(newNoiseAmount);
}
}
private void UpdateScanJitter()
{
if (!_volume.profile.TryGetSettings<GlitchScanLineJitter>(out var j)) return;
j.enabled.Override(false);
foreach (var e in _scanJitters)
{
float normalized = Conductor.instance.GetPositionFromBeat(e.beat, e.length);
if (normalized < 0) break;
float clampNormal = Mathf.Clamp01(normalized);
var func = Util.EasingFunction.GetEasingFunction((Util.EasingFunction.Ease)e["ease"]);
float newIntensity = func(e["intenStart"], e["intenEnd"], clampNormal);
j.enabled.Override(newIntensity != 0);
if (!j.enabled) continue;
j.JitterIndensity.Override(newIntensity);
}
}
private void UpdateGaussBlur()
{
if (!_volume.profile.TryGetSettings<GaussianBlur>(out var g)) return;
g.enabled.Override(false);
foreach (var e in _gaussBlurs)
{
float normalized = Conductor.instance.GetPositionFromBeat(e.beat, e.length);
if (normalized < 0) break;
float clampNormal = Mathf.Clamp01(normalized);
var func = Util.EasingFunction.GetEasingFunction((Util.EasingFunction.Ease)e["ease"]);
float newIntensity = func(e["intenStart"], e["intenEnd"], clampNormal);
g.enabled.Override(newIntensity != 0);
if (!g.enabled) continue;
g.BlurRadius.Override(newIntensity);
}
}
private void UpdateAnalogNoise()
{
if (!_volume.profile.TryGetSettings<GlitchAnalogNoise>(out var n)) return;
n.enabled.Override(false);
foreach (var e in _analogNoises)
{
float normalized = Conductor.instance.GetPositionFromBeat(e.beat, e.length);
if (normalized < 0) break;
float clampNormal = Mathf.Clamp01(normalized);
var func = Util.EasingFunction.GetEasingFunction((Util.EasingFunction.Ease)e["ease"]);
float newIntensity = func(e["intenStart"], e["intenEnd"], clampNormal);
n.enabled.Override(newIntensity != 0);
if (!n.enabled) continue;
n.NoiseSpeed.Override(newIntensity);
float newFading = func(e["fadingStart"], e["fadingEnd"], clampNormal);
n.NoiseFading.Override(newFading);
float newThreshold = func(e["thresholdStart"], e["thresholdEnd"], clampNormal);
n.LuminanceJitterThreshold.Override(newThreshold);
}
}
private void UpdateScreenJumps()
{
if (!_volume.profile.TryGetSettings<GlitchScreenJump>(out var sj)) return;
sj.enabled.Override(false);
foreach (var e in _screenJumps)
{
float normalized = Conductor.instance.GetPositionFromBeat(e.beat, e.length);
if (normalized < 0) break;
float clampNormal = Mathf.Clamp01(normalized);
var func = Util.EasingFunction.GetEasingFunction((Util.EasingFunction.Ease)e["ease"]);
float newIntensity = func(e["intenStart"], e["intenEnd"], clampNormal);
sj.enabled.Override(newIntensity != 0);
if (!sj.enabled) continue;
sj.ScreenJumpIndensity.Override(newIntensity);
}
}
private void UpdateSobelNeons()
{
if (!_volume.profile.TryGetSettings<EdgeDetectionSobelNeonV2>(out var sn)) return;
sn.enabled.Override(false);
foreach (var e in _sobelNeons)
{
float normalized = Conductor.instance.GetPositionFromBeat(e.beat, e.length);
if (normalized < 0) break;
float clampNormal = Mathf.Clamp01(normalized);
var func = Util.EasingFunction.GetEasingFunction((Util.EasingFunction.Ease)e["ease"]);
float newIntensity = func(e["intenStart"], e["intenEnd"], clampNormal);
sn.enabled.Override(newIntensity != 0.1);
if (!sn.enabled) continue;
sn.EdgeNeonFade.Override(newIntensity);
float newEdgeWidth = func(e["edgeWidthStart"], e["edgeWidthEnd"], clampNormal);
sn.EdgeWidth.Override(newEdgeWidth);
float newBgFade = func(e["bgFadeStart"], e["bgFadeEnd"], clampNormal);
sn.BackgroundFade.Override(newBgFade);
float newBrightness = func(e["brightnessStart"], e["brightnessEnd"], clampNormal);
sn.Brigtness.Override(newBrightness);
}
}
private void UpdatePixelizes()
{
if (!_volume.profile.TryGetSettings<PixelizeQuad>(out var pq)) return;
pq.enabled.Override(false);
foreach (var e in _pixelizeQuads)
{
float normalized = Conductor.instance.GetPositionFromBeat(e.beat, e.length);
if (normalized < 0) break;
float clampNormal = Mathf.Clamp01(normalized);
var func = Util.EasingFunction.GetEasingFunction((Util.EasingFunction.Ease)e["ease"]);
float newPixelSize = func(e["pixelSizeStart"], e["pixelSizeEnd"], clampNormal);
pq.enabled.Override(newPixelSize != 0);
if (!pq.enabled) continue;
pq.pixelSize.Override(newPixelSize);
float newPixelRatio = func(e["ratioStart"], e["ratioEnd"], clampNormal);
if (!pq.enabled) continue;
pq.pixelRatio.Override(newPixelRatio);
float newPixelXScale = func(e["xScaleStart"], e["xScaleEnd"], clampNormal);
if (!pq.enabled) continue;
pq.pixelScaleX.Override(newPixelXScale);
float newPixelYScale = func(e["yScaleStart"], e["yScaleEnd"], clampNormal);
if (!pq.enabled) continue;
pq.pixelScaleY.Override(newPixelYScale);
}
}
private Color ColorEase(Color start, Color end, float time, Util.EasingFunction.Function func)
{
float newR = func(start.r, end.r, time);

View File

@ -25,8 +25,21 @@ namespace HeavenStudio
public void OnBeatChanged(double beat)
{
_tileEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "screenTiling" });
_scrollEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "scrollTiles" });
_tileEvents.Clear();
_scrollEvents.Clear();
foreach (var entity in GameManager.instance.Beatmap.Entities)
{
switch (entity.datamodel)
{
case "vfx/screenTiling":
_tileEvents.Add(entity);
break;
case "vfx/scrollTiles":
_scrollEvents.Add(entity);
break;
default: break;
}
}
ResetUVRect();
Update();
}

View File

@ -80,10 +80,29 @@ namespace HeavenStudio
{
Reset();
panEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "pan view" });
scaleEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "scale view" });
rotationEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "rotate view" });
fitScreenEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "fitScreen" });
panEvents.Clear();
scaleEvents.Clear();
rotationEvents.Clear();
fitScreenEvents.Clear();
foreach (var entity in GameManager.instance.Beatmap.Entities)
{
switch (entity.datamodel)
{
case "vfx/pan view":
panEvents.Add(entity);
break;
case "vfx/scale view":
scaleEvents.Add(entity);
break;
case "vfx/rotate view":
rotationEvents.Add(entity);
break;
case "vfx/fitScreen":
fitScreenEvents.Add(entity);
break;
default: break;
}
}
panLast = defaultPan;
scaleLast = defaultScale;

View File

@ -16,7 +16,13 @@ namespace HeavenStudio
public void OnBeatChanged(double beat)
{
_events = EventCaller.GetAllInGameManagerList("vfx", new string[] { "stretch camera" });
_events.Clear();
foreach (var entity in GameManager.instance.Beatmap.Entities)
{
if (entity.datamodel == "vfx/stretch camera") {
_events.Add(entity);
}
}
Update();
}