add event priority

fix crop stomp queuing inputs while chart is paused
fix rhythm tweezers not killing queued inputs when switching veggies
This commit is contained in:
minenice55 2023-01-18 20:40:45 -05:00
parent 8d707ecd4e
commit 019710669e
10 changed files with 76 additions and 21 deletions

View file

@ -82,6 +82,7 @@ namespace HeavenStudio
{
action.inactiveFunction.Invoke();
}
Debug.Log($"Running action {action.actionName} of priority {action.priority}");
}
catch (Exception ex)
{

View file

@ -190,7 +190,7 @@ namespace HeavenStudio
}
}
public void SeekAheadAndPreload(float start, float seekTime = 8f)
public void SeekAheadAndPreload(double start, float seekTime = 8f)
{
//seek ahead to preload games that have assetbundles
//check game switches first
@ -217,6 +217,7 @@ namespace HeavenStudio
if (start + seekTime >= entities[currentPreEvent])
{
var entitiesAtSameBeat = Beatmap.entities.FindAll(c => c.beat == Beatmap.entities[currentPreEvent].beat && !EventCaller.FXOnlyGames().Contains(EventCaller.instance.GetMinigame(c.datamodel.Split('/')[0])));
SortEventsByPriority(entitiesAtSameBeat);
foreach (DynamicBeatmap.DynamicEntity entity in entitiesAtSameBeat)
{
string gameName = entity.datamodel.Split('/')[0];
@ -233,7 +234,7 @@ namespace HeavenStudio
}
}
public void SeekAheadAndDoPreEvent(float start, float seekTime = 2f)
public void SeekAheadAndDoPreEvent(double start, float seekTime = 2f)
{
List<float> entities = Beatmap.entities.Select(c => c.beat).ToList();
if (currentPreSequence < Beatmap.entities.Count && currentPreSequence >= 0)
@ -242,8 +243,10 @@ namespace HeavenStudio
{
float beat = Beatmap.entities[currentPreSequence].beat;
var entitiesAtSameBeat = Beatmap.entities.FindAll(c => c.beat == Beatmap.entities[currentPreSequence].beat);
SortEventsByPriority(entitiesAtSameBeat);
foreach (DynamicBeatmap.DynamicEntity entity in entitiesAtSameBeat)
{
currentPreSequence++;
string gameName = entity.datamodel.Split('/')[0];
var inf = GetGameInfo(gameName);
if (inf.usesAssetBundle && inf.AssetsLoaded && !inf.SequencesPreloaded)
@ -251,8 +254,10 @@ namespace HeavenStudio
Debug.Log($"Preloading game {gameName}");
PreloadGameSequences(gameName);
}
eventCaller.CallPreEvent(entity);
currentPreSequence++;
else
{
eventCaller.CallPreEvent(entity);
}
}
}
}
@ -274,7 +279,7 @@ namespace HeavenStudio
List<float> tempoChanges = Beatmap.tempoChanges.Select(c => c.beat).ToList();
if (currentTempoEvent < Beatmap.tempoChanges.Count && currentTempoEvent >= 0)
{
if (Conductor.instance.songPositionInBeats >= tempoChanges[currentTempoEvent])
if (Conductor.instance.songPositionInBeatsAsDouble >= tempoChanges[currentTempoEvent])
{
Conductor.instance.SetBpm(Beatmap.tempoChanges[currentTempoEvent].tempo);
currentTempoEvent++;
@ -284,7 +289,7 @@ namespace HeavenStudio
List<float> volumeChanges = Beatmap.volumeChanges.Select(c => c.beat).ToList();
if (currentVolumeEvent < Beatmap.volumeChanges.Count && currentVolumeEvent >= 0)
{
if (Conductor.instance.songPositionInBeats >= volumeChanges[currentVolumeEvent])
if (Conductor.instance.songPositionInBeatsAsDouble >= volumeChanges[currentVolumeEvent])
{
Conductor.instance.SetVolume(Beatmap.volumeChanges[currentVolumeEvent].volume);
currentVolumeEvent++;
@ -294,7 +299,7 @@ namespace HeavenStudio
List<float> chartSections = Beatmap.beatmapSections.Select(c => c.beat).ToList();
if (currentSectionEvent < Beatmap.beatmapSections.Count && currentSectionEvent >= 0)
{
if (Conductor.instance.songPositionInBeats >= chartSections[currentSectionEvent])
if (Conductor.instance.songPositionInBeatsAsDouble >= chartSections[currentSectionEvent])
{
Debug.Log("Section " + Beatmap.beatmapSections[currentSectionEvent].sectionName + " started");
currentSection = Beatmap.beatmapSections[currentSectionEvent];
@ -309,18 +314,21 @@ namespace HeavenStudio
float seekTime = 8f;
//seek ahead to preload games that have assetbundles
SeekAheadAndPreload(Conductor.instance.songPositionInBeats, seekTime);
SeekAheadAndPreload(Conductor.instance.songPositionInBeatsAsDouble, seekTime);
SeekAheadAndDoPreEvent(Conductor.instance.songPositionInBeats, 2f);
SeekAheadAndDoPreEvent(Conductor.instance.songPositionInBeatsAsDouble, 2f);
if (currentEvent < Beatmap.entities.Count && currentEvent >= 0)
{
if (Conductor.instance.songPositionInBeats >= entities[currentEvent] /*&& SongPosLessThanClipLength(Conductor.instance.songPositionInBeats)*/)
if (Conductor.instance.songPositionInBeatsAsDouble >= entities[currentEvent])
{
// allows for multiple events on the same beat to be executed on the same frame, so no more 1-frame delay
var entitiesAtSameBeat = Beatmap.entities.FindAll(c => c.beat == Beatmap.entities[currentEvent].beat && !EventCaller.FXOnlyGames().Contains(EventCaller.instance.GetMinigame(c.datamodel.Split('/')[0])));
var fxEntities = Beatmap.entities.FindAll(c => c.beat == Beatmap.entities[currentEvent].beat && EventCaller.FXOnlyGames().Contains(EventCaller.instance.GetMinigame(c.datamodel.Split('/')[0])));
SortEventsByPriority(fxEntities);
SortEventsByPriority(entitiesAtSameBeat);
// FX entities should ALWAYS execute before gameplay entities
for (int i = 0; i < fxEntities.Count; i++)
{
@ -427,6 +435,19 @@ namespace HeavenStudio
Beatmap.volumeChanges.Sort((x, y) => x.beat.CompareTo(y.beat));
}
void SortEventsByPriority(List<DynamicBeatmap.DynamicEntity> entities)
{
entities.Sort((x, y) => {
Minigames.Minigame xGame = EventCaller.instance.GetMinigame(x.datamodel.Split(0));
Minigames.GameAction xAction = EventCaller.instance.GetGameAction(xGame, x.datamodel.Split(1));
Minigames.Minigame yGame = EventCaller.instance.GetMinigame(y.datamodel.Split(0));
Minigames.GameAction yAction = EventCaller.instance.GetGameAction(yGame, y.datamodel.Split(1));
return yAction.priority.CompareTo(xAction.priority);
});
}
public void SetCurrentEventToClosest(float beat)
{
SortEventsList();

View file

@ -25,7 +25,7 @@ namespace HeavenStudio.Games.Scripts_CropStomp
return;
Conductor cond = Conductor.instance;
if (stomp == null)
if (stomp == null && cond.isPlaying)
{
if (GameManager.instance.currentGame == "cropStomp")
stomp = game.ScheduleUserInput(nextStompBeat - 1f, 1f, InputType.STANDARD_DOWN, Just, Miss, Out);

View file

@ -37,7 +37,9 @@ namespace HeavenStudio.Games.Scripts_CropStomp
public void Init()
{
game = CropStomp.instance;
game.ScheduleInput(targetBeat - 1, 1f, InputType.STANDARD_DOWN, StompJust, StompMiss, Out);
if (Conductor.instance.isPlaying)
game.ScheduleInput(targetBeat - 1, 1f, InputType.STANDARD_DOWN, StompJust, StompMiss, Out);
if (!isMole)
{

View file

@ -15,7 +15,8 @@ namespace HeavenStudio.Games.Loaders
{
function = delegate { FirstContact.instance.SetIntervalStart(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); },
defaultLength = 4f,
resizable = true
resizable = true,
priority = 1,
},
new GameAction("alien speak", "Alien Speak")
{

View file

@ -15,6 +15,8 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
private Tweezers tweezers;
private bool plucked;
PlayerActionEvent pluckEvent;
private void Awake()
{
game = RhythmTweezers.instance;
@ -22,7 +24,7 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
}
private void Start() {
game.ScheduleInput(createBeat, game.tweezerBeatOffset + game.beatInterval, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, Just, Miss, Out);
pluckEvent = game.ScheduleInput(createBeat, game.tweezerBeatOffset + game.beatInterval, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, Just, Miss, Out);
}
private void Update()
@ -58,5 +60,11 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
}
private void Out(PlayerActionEvent caller) {}
void OnDestroy()
{
if (pluckEvent != null)
pluckEvent.Disable();
}
}
}

View file

@ -21,6 +21,7 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
private Sound pullSound;
PlayerActionEvent pluckEvent;
PlayerActionEvent endEvent;
InputType endInput;
@ -122,5 +123,13 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
}
EndAce();
}
void OnDestroy()
{
if (pluckEvent != null)
pluckEvent.Disable();
if (endEvent != null)
endEvent.Disable();
}
}
}

View file

@ -19,7 +19,8 @@ namespace HeavenStudio.Games.Loaders
{
function = delegate { RhythmTweezers.instance.SetIntervalStart(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); },
defaultLength = 4f,
resizable = true
resizable = true,
priority = 1
},
new GameAction("short hair", "Short Hair")
{
@ -41,7 +42,8 @@ namespace HeavenStudio.Games.Loaders
new Param("type", RhythmTweezers.VegetableType.Onion, "Type", "The vegetable to switch to"),
new Param("colorA", RhythmTweezers.defaultOnionColor, "Onion Color", "The color of the onion"),
new Param("colorB", RhythmTweezers.defaultPotatoColor, "Potato Color", "The color of the potato")
}
},
priority = 3
},
new GameAction("change vegetable", "Change Vegetable (Instant)")
{
@ -57,12 +59,14 @@ namespace HeavenStudio.Games.Loaders
new GameAction("set tweezer delay", "Offset Tweezer")
{
function = delegate { RhythmTweezers.instance.tweezerBeatOffset = eventCaller.currentEntity.length; },
resizable = true
resizable = true,
priority = 2
},
new GameAction("reset tweezer delay", "Reset Tweezer Offset")
{
function = delegate { RhythmTweezers.instance.tweezerBeatOffset = 0f; },
defaultLength = 0.5f
defaultLength = 0.5f,
priority = 2
},
new GameAction("set background color", "Background Colour")
{
@ -350,7 +354,10 @@ namespace HeavenStudio.Games
if (transitioning)
{
if (transitionTween != null)
transitionTween.Kill(true);
{
transitionTween.Complete(true);
transitionTween.Kill();
}
}
}
}

View file

@ -19,7 +19,8 @@ namespace HeavenStudio.Games.Loaders
{
function = delegate { WizardsWaltz.instance.SetIntervalStart(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); },
defaultLength = 4f,
resizable = true
resizable = true,
priority = 1
},
new GameAction("plant", "Plant")
{

View file

@ -152,6 +152,7 @@ namespace HeavenStudio
public bool resizable = false;
public List<Param> parameters = null;
public bool hidden = false;
public int priority = 0;
public EventCallback inactiveFunction = delegate { };
public EventCallback preFunction = delegate { };
@ -169,7 +170,9 @@ namespace HeavenStudio
/// <param name="inactiveFunction">What the block does when read while the game it's associated with isn't loaded.</param>
/// <param name="prescheduleFunction">What the block does when the GameManager seeks to this cue for pre-scheduling.</param>
/// <param name="hidden">Prevents the block from being shown in the game list. Block will still function normally if it is in the timeline.</param>
public GameAction(string actionName, string displayName, float defaultLength = 1, bool resizable = false, List<Param> parameters = null, EventCallback function = null, EventCallback inactiveFunction = null, EventCallback prescheduleFunction = null, bool hidden = false)
/// <param name="preFunction">Runs two beats before this event is reached.</param>
/// <param name="priority">Priority of this event. Higher priority events will be run first.</param>
public GameAction(string actionName, string displayName, float defaultLength = 1, bool resizable = false, List<Param> parameters = null, EventCallback function = null, EventCallback inactiveFunction = null, EventCallback prescheduleFunction = null, bool hidden = false, EventCallback preFunction = null, int priority = 0)
{
this.actionName = actionName;
if (displayName == String.Empty) this.displayName = actionName;
@ -182,6 +185,8 @@ namespace HeavenStudio
this.function = function ?? delegate { };
this.inactiveFunction = inactiveFunction ?? delegate { };
this.preFunction = prescheduleFunction ?? delegate { };
this.priority = priority;
//todo: converting to new versions of GameActions
}