Catch of the Day (bugfixes) (#814)

* Freeze Frame

Hey, I'm about done with Freeze Frame and I'm just gonna commit the game as it is right now, it's almost done thx
-playinful

* Freeze Frame - finishing touches before finalized assets

Still waiting to implement the upscaled assets and the sound effects. Code-wise this is as much as I can do for now.

* i fixed a couple bugs

the dim screen is back and no input duplication when switching games. hallelujah

* FreezeFrame randomness update

hey AJ so i was cleaning my room when i was struck by an idea for how to make the randomization more consistent without seeding. *yes unfortunately* it requires a static variable but i promise u i used it responsibly.

* initial commit

* mar 13

* Updated cloud particles

* 3/22

* First PR

* corrected a mistake

* forgot to change that goofy ahh icon

* Bugfixes

Fixed a bug where fishes could be reeled in before the bite animation played and get stuck in the bite animation.
Fixed a bug where the count-in for the pausegill played at the incorrect time.
Fixed a bug where the threefish would cause a scene transition at the incorrect time.

* Crossfade close to done

* The Long Awaited Crossfade Update

* added sort key

* one last quick bugfix (hopefully)

---------

Co-authored-by: minenice55 <star.elementa@gmail.com>
This commit is contained in:
playinful
2024-04-04 21:28:01 -04:00
committed by GitHub
parent 80ae5eaf6b
commit 75e248c97b
11 changed files with 58576 additions and 56674 deletions

View File

@ -1,17 +1,13 @@
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HeavenStudio.Util;
using HeavenStudio.InputSystem;
using Jukebox;
using System.Runtime.CompilerServices;
using HeavenStudio.Games.Scripts_CatchOfTheDay;
using UnityEngine.AI;
using HeavenStudio.Common;
namespace HeavenStudio.Games.Loaders
{
@ -25,8 +21,8 @@ namespace HeavenStudio.Games.Loaders
{
new GameAction("fish1", "Quicknibble")
{
function = delegate {var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish01(e); CatchOfTheDay.Instance.NewLake(e); },
inactiveFunction = delegate {var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish01(e); },
function = delegate { var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish01(e); CatchOfTheDay.Instance.NewLake(e); },
inactiveFunction = delegate { var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish01(e); },
defaultLength = 3f,
parameters = new List<Param>()
{
@ -37,7 +33,7 @@ namespace HeavenStudio.Games.Loaders
}),
new Param("colorTop", new Color(0.7098039f, 0.8705882f, 0.8705882f), "Top Color", "The color for the top part of the background."),
new Param("colorBottom", new Color(0.4666667f, 0.7372549f, 0.8196079f), "Bottom Color", "The color for the bottom part of the background."),
new Param("sceneDelay", new EntityTypes.Float(0f, 32f, 1f), "Scene Change Delay", "Amount of beats to wait before changing to the next scene."),
new Param("sceneDelay", new EntityTypes.Float(0f, 32f, 2f), "Scene Change Delay", "Amount of beats to wait before changing to the next scene."),
new Param("fgManta", false, "Foreground Stingray", "Spawn a stingray in the foreground of the scene."),
new Param("bgManta", false, "Background Stingray", "Spawn a stingray in the background of the scene."),
new Param("schoolFish", false, "School of Fish", "Spawn a school of fish to as a distraction.", new List<Param.CollapseParam>()
@ -49,8 +45,8 @@ namespace HeavenStudio.Games.Loaders
},
new GameAction("fish2", "Pausegill")
{
function = delegate {var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish02(e); CatchOfTheDay.Instance.NewLake(e); },
inactiveFunction = delegate {var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish02(e); },
function = delegate { var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish02(e); CatchOfTheDay.Instance.NewLake(e); },
inactiveFunction = delegate { var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish02(e); },
defaultLength = 4f,
parameters = new List<Param>()
{
@ -62,7 +58,7 @@ namespace HeavenStudio.Games.Loaders
}),
new Param("colorTop", new Color(0.7098039f, 0.8705882f, 0.8705882f), "Top Color", "The color for the top part of the background."),
new Param("colorBottom", new Color(0.4666667f, 0.7372549f, 0.8196079f), "Bottom Color", "The color for the bottom part of the background."),
new Param("sceneDelay", new EntityTypes.Float(0f, 32f, 1f), "Scene Change Delay", "Amount of beats to wait before changing to the next scene."),
new Param("sceneDelay", new EntityTypes.Float(0f, 32f, 2f), "Scene Change Delay", "Amount of beats to wait before changing to the next scene."),
new Param("fgManta", false, "Foreground Stingray", "Spawn a stingray in the foreground of the scene."),
new Param("bgManta", false, "Background Stingray", "Spawn a stingray in the background of the scene."),
new Param("schoolFish", false, "School of Fish", "Spawn a school of fish to as a distraction.", new List<Param.CollapseParam>()
@ -74,8 +70,8 @@ namespace HeavenStudio.Games.Loaders
},
new GameAction("fish3", "Threefish")
{
function = delegate {var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish03(e); CatchOfTheDay.Instance.NewLake(e); },
inactiveFunction = delegate {var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish03(e); },
function = delegate { var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish03(e); CatchOfTheDay.Instance.NewLake(e); },
inactiveFunction = delegate { var e = eventCaller.currentEntity; CatchOfTheDay.Cue_Fish03(e); },
defaultLength = 5.5f,
parameters = new List<Param>()
{
@ -88,7 +84,7 @@ namespace HeavenStudio.Games.Loaders
}),
new Param("colorTop", new Color(0.7098039f, 0.8705882f, 0.8705882f), "Top Color", "The color for the top part of the background."),
new Param("colorBottom", new Color(0.4666667f, 0.7372549f, 0.8196079f), "Bottom Color", "The color for the bottom part of the background."),
new Param("sceneDelay", new EntityTypes.Float(0f, 32f, 1f), "Scene Change Delay", "Amount of beats to wait before changing to the next scene."),
new Param("sceneDelay", new EntityTypes.Float(0f, 32f, 2f), "Scene Change Delay", "Amount of beats to wait before changing to the next scene."),
new Param("fgManta", false, "Foreground Stingray", "Spawn a stingray in the foreground of the scene."),
new Param("bgManta", false, "Background Stingray", "Spawn a stingray in the background of the scene."),
new Param("schoolFish", false, "School of Fish", "Spawn a school of fish to as a distraction.", new List<Param.CollapseParam>()
@ -98,10 +94,54 @@ namespace HeavenStudio.Games.Loaders
new Param("fishDensity", new EntityTypes.Float(0f, 1f, 1f), "Fish Density", "Set the density for the fish in the school."),
},
},
new GameAction("moveAngler", "Move Angler")
{
function = delegate { var e = eventCaller.currentEntity; CatchOfTheDay.Instance.SetAnglerMovement(e); },
defaultLength = 1f,
resizable = true,
parameters = new List<Param>()
{
new Param("doMove", false, "Move", "Select this option if you want to move Ann.", 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 which to move."),
new Param("endMoveY", new EntityTypes.Float(-20f, 20f, 0f), "End Y", "Set the Y position to which to move."),
new Param("doRotate", false, "Rotate", "Select this option if you want to rotate Ann.", 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 amount of degrees at which to begin rotating."),
new Param("endRotDegrees", new EntityTypes.Float(-360f, 360f, 0f), "End Rotation", "Set the amount of degrees at which to finish rotating."),
new Param("doScale", false, "Scale", "Select this option if you want to change Ann'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" }),
}),
new Param("sticky", false, "Follow Camera", "Select this to make Ann follow the camera."),
}
}
},
new List<string>() {"rvl", "normal"},
"rvlfishing", "en"
//, chronologicalSortIndex: 21
, chronologicalSortKey: 21
);
}
}
@ -113,11 +153,10 @@ namespace HeavenStudio.Games
{
/*
BIG LIST OF TODOS
- ping @hexiedecimal
- scene transitions
- wait for upscale
- make ann movable
*/
protected const int MAX_LAKES = 50;
public static CatchOfTheDay Instance
{
get
@ -137,6 +176,28 @@ namespace HeavenStudio.Games
public static Dictionary<RiqEntity, MultiSound> FishSounds = new();
private List<RiqEntity> _AllFishes;
[SerializeField] Transform AnglerTransform;
private bool _AnglerIsMoving = false;
private AnglerMoveArgs _CurrentAnglerMoveArgs;
private bool _AnglerIsRotating = false;
private AnglerRotateArgs _CurrentAnglerRotateArgs;
private bool _AnglerIsScaling = false;
private AnglerScaleArgs _CurrentAnglerScaleArgs;
private Vector3 _AnglerBasePosition;
private Vector3 _AnglerBaseEulerAngles;
private Vector3 _AnglerBaseScale;
[SerializeField] StickyCanvas _StickyCanvas;
void Awake()
{
_AnglerBasePosition = AnglerTransform.localPosition;
_AnglerBaseEulerAngles = AnglerTransform.localEulerAngles;
_AnglerBaseScale = AnglerTransform.localScale;
}
private void Update()
{
if (!conductor.isPlaying && !conductor.isPaused && ActiveLakes.Count <= 0)
@ -147,6 +208,60 @@ namespace HeavenStudio.Games
else
SpawnNextFish(conductor.songPositionInBeatsAsDouble);
}
// Moving Ann
if (_AnglerIsMoving)
{
float normalizedBeat = Conductor.instance.GetPositionFromBeat(_CurrentAnglerMoveArgs.StartBeat, _CurrentAnglerMoveArgs.Length);
Util.EasingFunction.Function func = Util.EasingFunction.GetEasingFunction(_CurrentAnglerMoveArgs.Ease);
float newPos = func(0f, 1f, normalizedBeat);
Vector3 diff = _CurrentAnglerMoveArgs.EndPosition - _CurrentAnglerMoveArgs.StartPosition;
AnglerTransform.localPosition = _AnglerBasePosition + _CurrentAnglerMoveArgs.StartPosition + (diff * newPos);
if (normalizedBeat >= 1f)
{
AnglerTransform.localPosition = _AnglerBasePosition + _CurrentAnglerMoveArgs.EndPosition;
_AnglerIsMoving = false;
}
}
if (_AnglerIsRotating)
{
float normalizedBeat = Conductor.instance.GetPositionFromBeat(_CurrentAnglerRotateArgs.StartBeat, _CurrentAnglerRotateArgs.Length);
Util.EasingFunction.Function func = Util.EasingFunction.GetEasingFunction(_CurrentAnglerRotateArgs.Ease);
float newPos = func(0f, 1f, normalizedBeat);
float diff = _CurrentAnglerRotateArgs.EndRotation - _CurrentAnglerRotateArgs.StartRotation;
AnglerTransform.localEulerAngles = _AnglerBaseEulerAngles + new Vector3(0, 0, _CurrentAnglerRotateArgs.StartRotation + (diff * newPos));
if (normalizedBeat >= 1f)
{
AnglerTransform.localEulerAngles = _AnglerBaseEulerAngles + new Vector3(0, 0, _CurrentAnglerRotateArgs.EndRotation);
_AnglerIsRotating = false;
}
}
if (_AnglerIsScaling)
{
float normalizedBeat = Conductor.instance.GetPositionFromBeat(_CurrentAnglerScaleArgs.StartBeat, _CurrentAnglerScaleArgs.Length);
Util.EasingFunction.Function func = Util.EasingFunction.GetEasingFunction(_CurrentAnglerScaleArgs.Ease);
float newPos = func(0f, 1f, normalizedBeat);
Vector3 diff = _CurrentAnglerScaleArgs.EndScale - _CurrentAnglerScaleArgs.StartScale;
AnglerTransform.localScale = new Vector3
(
_AnglerBaseScale.x * (_CurrentAnglerScaleArgs.StartScale.x + (diff.x * newPos)),
_AnglerBaseScale.y * (_CurrentAnglerScaleArgs.StartScale.y + (diff.y * newPos)),
0
);
if (normalizedBeat >= 1f)
{
AnglerTransform.localScale = new Vector3
(
_AnglerBaseScale.x * _CurrentAnglerScaleArgs.EndScale.x,
_AnglerBaseScale.y * _CurrentAnglerScaleArgs.EndScale.y,
0
);
_AnglerIsScaling = false;
}
}
}
public override void OnPlay(double beat)
{
@ -156,6 +271,13 @@ namespace HeavenStudio.Games
{
DestroyOrphanedLakes();
CleanupFishSounds();
// set ann movement
foreach (RiqEntity e in EventCaller.GetAllInGameManagerList("catchOfTheDay", new string[] { "moveAngler" }).Where(e => e.beat <= beat).OrderBy(e => e.beat))
{
SetAnglerMovement(e);
}
// get active fishes
foreach (RiqEntity e in GetActiveFishes(beat))
{
@ -198,7 +320,7 @@ namespace HeavenStudio.Games
{
MultiSound.Play(new MultiSound.Sound[]{
new MultiSound.Sound("count-ins/and", beat + 2),
new MultiSound.Sound(UnityEngine.Random.Range(0.0f, 1.0f) > 0.5 ? "count-ins/go1" : "count-ins/go2", beat + 2),
new MultiSound.Sound(UnityEngine.Random.Range(0.0f, 1.0f) > 0.5 ? "count-ins/go1" : "count-ins/go2", beat + 3),
}, forcePlay: true, game: false);
}
@ -232,6 +354,41 @@ namespace HeavenStudio.Games
Instance.ActiveLakes[e]._MultiSound = FishSounds[e];
}
public void SetAnglerMovement(RiqEntity e)
{
if (e["doMove"])
{
_AnglerIsMoving = true;
_CurrentAnglerMoveArgs = new AnglerMoveArgs(
e.beat, e.length,
new Vector3(e["startMoveX"], e["startMoveY"], 0),
new Vector3(e["endMoveX"], e["endMoveY"], 0),
e["ease"]
);
}
if (e["doRotate"])
{
_AnglerIsRotating = true;
_CurrentAnglerRotateArgs = new AnglerRotateArgs(
e.beat, e.length,
e["startRotDegrees"],
e["endRotDegrees"],
e["ease"]
);
}
if (e["doScale"])
{
_AnglerIsScaling = true;
_CurrentAnglerScaleArgs = new AnglerScaleArgs(
e.beat, e.length,
new Vector3(e["startScaleX"], e["startScaleY"], 1),
new Vector3(e["endScaleX"], e["endScaleY"], 1),
e["ease"]
);
}
_StickyCanvas.Sticky = (bool)e["sticky"];
}
public void DoPickAnim()
{
Angler.DoScaledAnimationAsync("Pick", 0.5f);
@ -280,30 +437,36 @@ namespace HeavenStudio.Games
}
public List<RiqEntity> GetActiveFishes(double beat)
{
return EventCaller.GetAllInGameManagerList("catchOfTheDay", new string[] { "fish1", "fish2", "fish3" }).FindAll(e => e.beat <= beat && e.beat + e.length - 1 + e["sceneDelay"] >= beat);
return CacheFishes().FindAll(e => e.beat <= beat && e.beat + e.length - 1 + e["sceneDelay"] >= beat);
}
public RiqEntity GetNextFish(double beat)
{
RiqEntity gameSwitch = GetNextGameSwitch(beat);
return EventCaller.GetAllInGameManagerList("catchOfTheDay", new string[] { "fish1", "fish2", "fish3" }).OrderBy(e => e.beat).FirstOrDefault(e => e.beat >= beat && (gameSwitch is null || e.beat < gameSwitch.beat));
return CacheFishes().FirstOrDefault(e => e.beat >= beat && (gameSwitch is null || e.beat < gameSwitch.beat));
}
public RiqEntity GetNextGameSwitch(double beat)
{
return EventCaller.GetAllInGameManagerList("gameManager", new string[] { "switchGame" }).OrderBy(e => e.beat).FirstOrDefault(e => e.beat > beat && e.datamodel != "gameManager/switchGame/catchOfTheDay");
}
public LakeScene NewLake(RiqEntity e)
{
if (ActiveLakes.ContainsKey(e))
return null;
int sort = EventCaller.GetAllInGameManagerList("catchOfTheDay", new string[] { "fish1", "fish2", "fish3" }).FindIndex(x => e == x);
if (ActiveLakes.Count >= MAX_LAKES)
return null;
int sort = CacheFishes().FindIndex(x => e == x);
if (sort < 0)
return null;
CleanupFishSounds();
Debug.Log($"Spawning Lake {sort}");
LakeScene lake = Instantiate(LakeScenePrefab, LakeSceneHolder).GetComponent<LakeScene>();
LastLayout = lake.Setup(e, this, LastLayout, int.MaxValue - sort);
LastLayout = lake.Setup(e, this, LastLayout, 0 - sort);
ActiveLakes.Add(e, lake);
if (FishSounds.ContainsKey(e))
lake._MultiSound = FishSounds[e];
@ -319,17 +482,22 @@ namespace HeavenStudio.Games
}
return false;
}
public void DisposeLake(LakeScene lake)
public void DisposeLake(LakeScene lake, double beat)
{
ActiveLakes.Remove(lake.Entity);
if (ActiveLakes.Count <= 0)
{
if (SpawnNextFish(conductor.songPositionInBeatsAsDouble))
Destroy(lake.gameObject);
lake.Crossfade(beat);
}
else
Destroy(lake.gameObject);
lake.Crossfade(beat);
}
public List<RiqEntity> CacheFishes()
{
return _AllFishes ??= EventCaller.GetAllInGameManagerList("catchOfTheDay", new string[] { "fish1", "fish2", "fish3" }).OrderBy(e => e.beat).ToList();
}
public enum FishLayout : int
@ -339,7 +507,59 @@ namespace HeavenStudio.Games
LayoutB = 1,
LayoutC = 2
}
private struct AnglerMoveArgs
{
public Vector3 StartPosition;
public Vector3 EndPosition;
public double StartBeat;
public double Length;
public Util.EasingFunction.Ease Ease;
public AnglerMoveArgs(double startBeat, double length, Vector3 startPosition, Vector3 endPosition, int ease)
{
StartPosition = startPosition;
EndPosition = endPosition;
StartBeat = startBeat;
Length = length;
Ease = (Util.EasingFunction.Ease)ease;
}
}
private struct AnglerRotateArgs
{
public float StartRotation;
public float EndRotation;
public double StartBeat;
public double Length;
public Util.EasingFunction.Ease Ease;
public AnglerRotateArgs(double startBeat, double length, float startRotation, float endRotation, int ease)
{
StartRotation = startRotation;
EndRotation = endRotation;
StartBeat = startBeat;
Length = length;
Ease = (Util.EasingFunction.Ease)ease;
}
}
private struct AnglerScaleArgs
{
public Vector3 StartScale;
public Vector3 EndScale;
public double StartBeat;
public double Length;
public Util.EasingFunction.Ease Ease;
public AnglerScaleArgs(double startBeat, double length, Vector3 startScale, Vector3 endScale, int ease)
{
StartScale = startScale;
EndScale = endScale;
StartBeat = startBeat;
Length = length;
Ease = (Util.EasingFunction.Ease)ease;
}
}
}
}
// This minigame ported by playinful. ☆
// This minigame ported by Yin. ☆