mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 11:57:40 +02:00
Mannequin Factory (#499)
* everything yeah. everything..? just needs an icon * ass buns * clean up + split up the blocks * quick refresh just so this doesn't get stale and fall behind in the codebase * NOT DONE YET! gonna finish tomorrow * it's done!! * oh oops gotta actually load the game
This commit is contained in:
8
Assets/Scripts/Games/MannequinFactory.meta
Normal file
8
Assets/Scripts/Games/MannequinFactory.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fc314cb83e13a24a894d3465ad40476
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
233
Assets/Scripts/Games/MannequinFactory/MannequinFactory.cs
Normal file
233
Assets/Scripts/Games/MannequinFactory/MannequinFactory.cs
Normal file
@ -0,0 +1,233 @@
|
||||
using System.Collections.Generic;
|
||||
using HeavenStudio.Util;
|
||||
using HeavenStudio.InputSystem;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
using DG.Tweening;
|
||||
|
||||
namespace HeavenStudio.Games.Loaders
|
||||
{
|
||||
using static Minigames;
|
||||
public static class AgbMannequinFactoryLoader
|
||||
{
|
||||
public static Minigame AddGame(EventCaller eventCaller) {
|
||||
return new Minigame("mannequinFactory", "Mannequin Factory", "554899", false, false, new List<GameAction>()
|
||||
{
|
||||
new GameAction("headOut", "Send Head Out")
|
||||
{
|
||||
inactiveFunction = delegate {
|
||||
MannequinFactory.HeadOutSFX(eventCaller.currentEntity.beat, 0);
|
||||
},
|
||||
function = delegate {
|
||||
MannequinFactory.HeadOutSFX(eventCaller.currentEntity.beat, 0);
|
||||
if (eventCaller.gameManager.minigameObj.TryGetComponent(out MannequinFactory instance)) {
|
||||
instance.HeadOut(eventCaller.currentEntity.beat, 0);
|
||||
}
|
||||
},
|
||||
defaultLength = 7,
|
||||
},
|
||||
new GameAction("misalignedHeadOut", "Send Misaligned Head Out")
|
||||
{
|
||||
inactiveFunction = delegate {
|
||||
MannequinFactory.HeadOutSFX(eventCaller.currentEntity.beat, 1);
|
||||
},
|
||||
function = delegate {
|
||||
MannequinFactory.HeadOutSFX(eventCaller.currentEntity.beat, 1);
|
||||
if (eventCaller.gameManager.minigameObj.TryGetComponent(out MannequinFactory instance)) {
|
||||
instance.HeadOut(eventCaller.currentEntity.beat, 1);
|
||||
}
|
||||
},
|
||||
defaultLength = 7,
|
||||
},
|
||||
new GameAction("randomHeadOut", "Send Random Head Out")
|
||||
{
|
||||
// inactiveFunction = delegate {
|
||||
// int random = Random.Range(0, 2);
|
||||
// MannequinFactory.HeadOutSFX(eventCaller.currentEntity.beat, random);
|
||||
// },
|
||||
function = delegate {
|
||||
int random = Random.Range(0, 2);
|
||||
MannequinFactory.HeadOutSFX(eventCaller.currentEntity.beat, random);
|
||||
if (eventCaller.gameManager.minigameObj.TryGetComponent(out MannequinFactory instance)) {
|
||||
instance.HeadOut(eventCaller.currentEntity.beat, random);
|
||||
}
|
||||
},
|
||||
defaultLength = 7,
|
||||
},
|
||||
new GameAction("changeText", "Change Text")
|
||||
{
|
||||
function = delegate {
|
||||
if (eventCaller.gameManager.minigameObj.TryGetComponent(out MannequinFactory instance)) {
|
||||
instance.SignText.text = eventCaller.currentEntity["text"];
|
||||
}
|
||||
},
|
||||
defaultLength = 0.5f,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("text", "Mannequin Factory", "Text", "The text to be displayed on the sign"),
|
||||
}
|
||||
},
|
||||
new GameAction("bgColor", "Change Background Color")
|
||||
{
|
||||
function = delegate {
|
||||
if (eventCaller.gameManager.minigameObj.TryGetComponent(out MannequinFactory instance)) {
|
||||
var e = eventCaller.currentEntity;
|
||||
instance.BackgroundColor(e.beat, e.length, e["colorStart"], e["colorEnd"], e["ease"]);
|
||||
}
|
||||
},
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("colorStart", new Color(0.97f, 0.94f, 0.51f, 1f), "Start Color", "The color to start fading from."),
|
||||
new Param("colorEnd", new Color(0.97f, 0.94f, 0.51f, 1f), "End Color", "The color to end the fade."),
|
||||
new Param("ease", Util.EasingFunction.Ease.Linear, "Ease", "The ease to use for color fade", new() {
|
||||
new Param.CollapseParam((x, _) => (int)x != (int)Util.EasingFunction.Ease.Instant, new[] { "colorStart" }),
|
||||
}),
|
||||
},
|
||||
resizable = true
|
||||
},
|
||||
},
|
||||
new List<string>() {"agb", "normal"},
|
||||
"agbmannequin", "en",
|
||||
new List<string>() {}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace HeavenStudio.Games
|
||||
{
|
||||
using Scripts_MannequinFactory;
|
||||
public class MannequinFactory : Minigame
|
||||
{
|
||||
[Header("Animators")]
|
||||
public Animator HandAnim;
|
||||
public Animator StampAnim;
|
||||
|
||||
[Header("References")]
|
||||
[SerializeField] SpriteRenderer bg;
|
||||
public TMP_Text SignText;
|
||||
public GameObject MannequinHeadObject;
|
||||
|
||||
public double slapScheduledBeat = double.MinValue;
|
||||
|
||||
private double colorStartBeat = -1;
|
||||
private float colorLength = 0f;
|
||||
private Color colorStart, colorEnd = new Color(0.97f, 0.94f, 0.51f, 1f); // default bg color
|
||||
private Util.EasingFunction.Ease colorEase;
|
||||
|
||||
protected static bool IA_PadLeft(out double dt)
|
||||
{
|
||||
return PlayerInput.GetPadDown(InputController.ActionsPad.Left, out dt);
|
||||
}
|
||||
|
||||
public static PlayerInput.InputAction InputAction_First =
|
||||
new("AgbMannequinFactoryTouchFirst", new int[] { IAPressCat, IAPressCat, IAPressCat },
|
||||
IA_PadLeft, IA_TouchFlick, IA_Empty);
|
||||
|
||||
public static PlayerInput.InputAction InputAction_Second =
|
||||
new("AgbMannequinFactoryTouchSecond", new int[] { IAPressCat, IAPressCat, IAPressCat },
|
||||
IA_PadBasicPress, IA_TouchBasicPress, IA_Empty);
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (PlayerInput.GetIsAction(InputAction_First) && !IsExpectingInputNow(InputAction_First)
|
||||
&& !HandAnim.IsPlayingAnimationNames("SlapEmpty", "SlapJust"))
|
||||
{
|
||||
HandAnim.DoScaledAnimationAsync("SlapEmpty", 0.3f);
|
||||
}
|
||||
|
||||
bool canSlap = PlayerInput.CurrentControlStyle != InputController.ControlStyles.Touch || slapScheduledBeat < conductor.songPositionInBeatsAsDouble;
|
||||
|
||||
if (PlayerInput.GetIsAction(InputAction_Second) && !IsExpectingInputNow(InputAction_Second)
|
||||
&& !StampAnim.IsPlayingAnimationNames("StampEmpty", "StampJust") && canSlap)
|
||||
{
|
||||
StampAnim.DoScaledAnimationAsync("StampEmpty", 0.3f);
|
||||
}
|
||||
|
||||
float normalizedBeat = Mathf.Clamp01(Conductor.instance.GetPositionFromBeat(colorStartBeat, colorLength));
|
||||
|
||||
var func = Util.EasingFunction.GetEasingFunction(colorEase);
|
||||
|
||||
float newR = func(colorStart.r, colorEnd.r, normalizedBeat);
|
||||
float newG = func(colorStart.g, colorEnd.g, normalizedBeat);
|
||||
float newB = func(colorStart.b, colorEnd.b, normalizedBeat);
|
||||
|
||||
bg.color = new Color(newR, newG, newB);
|
||||
}
|
||||
|
||||
public override void OnPlay(double beat) => StartGame(beat, true);
|
||||
public override void OnGameSwitch(double beat) => StartGame(beat, false);
|
||||
|
||||
private void StartGame(double beat, bool isPlay)
|
||||
{
|
||||
var events = gameManager.Beatmap.Entities.FindAll(e => e.datamodel.Split('/')[0] == "mannequinFactory");
|
||||
|
||||
foreach (var e in events)
|
||||
{
|
||||
if (e.beat < beat && e.beat + 2.75 > beat && e.datamodel is "mannequinFactory/headOut" or "mannequinFactory/misalignedHeadOut" /* or "mannequinFactory/randomHeadOut" */) {
|
||||
int cueType = e.datamodel switch {
|
||||
"mannequinFactory/headOut" => 0,
|
||||
"mannequinFactory/misalignedHeadOut" => 1,
|
||||
"mannequinFactory/randomHeadOut" or _ => Random.Range(0, 2),
|
||||
};
|
||||
HeadOut(e.beat, cueType);
|
||||
if (isPlay) {
|
||||
HeadOutSFX(e.beat, cueType, beat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var bg = events.FindLast(e => e.datamodel == "mannequinFactory/bgColor" && e.beat < beat);
|
||||
if (bg != null) {
|
||||
BackgroundColor(bg.beat, bg.length, bg["colorStart"], bg["colorEnd"], bg["ease"]);
|
||||
} else {
|
||||
Color color = new Color(0.97f, 0.94f, 0.51f, 1f);
|
||||
BackgroundColor(0, 0, color, color, (int)EasingFunction.Ease.Instant);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HeadOutSFX(double beat, int cueType, double fromBeat = 0)
|
||||
{
|
||||
var sfx = new List<MultiSound.Sound>() {
|
||||
new("mannequinFactory/drum", beat ),
|
||||
new("mannequinFactory/drum", beat + 0.5),
|
||||
new("mannequinFactory/drum", beat + 1.5),
|
||||
new("mannequinFactory/drum", beat + 2 ),
|
||||
new("mannequinFactory/whoosh", beat + 5),
|
||||
};
|
||||
if (cueType == 0) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
sfx.Add(new($"mannequinFactory/drumroll{i + 1}", beat + 3 + (i * 0.1667)));
|
||||
}
|
||||
} else {
|
||||
sfx.AddRange(new MultiSound.Sound[] {
|
||||
new("mannequinFactory/drum", beat + 0.75),
|
||||
new("mannequinFactory/drum", beat + 1 ),
|
||||
new("mannequinFactory/whoosh", beat + 3),
|
||||
});
|
||||
}
|
||||
sfx.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
sfx.RemoveAll(x => x.beat < fromBeat);
|
||||
if (sfx.Count > 0) {
|
||||
MultiSound.Play(sfx.ToArray(), forcePlay: true);
|
||||
}
|
||||
}
|
||||
|
||||
public void HeadOut(double beat, int cueType)
|
||||
{
|
||||
MannequinHead head = Instantiate(MannequinHeadObject, transform).GetComponent<MannequinHead>();
|
||||
head.game = this;
|
||||
head.startBeat = beat;
|
||||
head.needSlap = cueType == 1;
|
||||
}
|
||||
|
||||
public void BackgroundColor(double beat, float length, Color colorStartSet, Color colorEndSet, int ease)
|
||||
{
|
||||
colorStartBeat = beat;
|
||||
colorLength = length;
|
||||
colorStart = colorStartSet;
|
||||
colorEnd = colorEndSet;
|
||||
colorEase = (Util.EasingFunction.Ease)ease;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0697b066afb3aa41a8bef8800523a8b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
136
Assets/Scripts/Games/MannequinFactory/MannequinHead.cs
Normal file
136
Assets/Scripts/Games/MannequinFactory/MannequinHead.cs
Normal file
@ -0,0 +1,136 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
using HeavenStudio.Util;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_MannequinFactory
|
||||
{
|
||||
public class MannequinHead : MonoBehaviour
|
||||
{
|
||||
public double startBeat;
|
||||
public bool needSlap;
|
||||
|
||||
[Header("Animators")]
|
||||
[SerializeField] SpriteRenderer headSr;
|
||||
[SerializeField] Sprite[] heads;
|
||||
[SerializeField] SpriteRenderer eyesSr;
|
||||
[SerializeField] Sprite[] eyes;
|
||||
[SerializeField] Animator headAnim;
|
||||
|
||||
int turnStatus;
|
||||
|
||||
public MannequinFactory game;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
game.slapScheduledBeat = startBeat + 4;
|
||||
|
||||
turnStatus = needSlap ? 0 : 1;
|
||||
headSr.sprite = heads[turnStatus];
|
||||
|
||||
BeatAction.New(game, new List<BeatAction.Action> {
|
||||
new(startBeat + 1, delegate { headAnim.DoScaledAnimationAsync("Move1", 0.3f); }),
|
||||
new(startBeat + 3, delegate { if (game.gameManager.autoplay) headAnim.DoScaledAnimationAsync("Move2", 0.3f); }),
|
||||
new(startBeat + 4, delegate {
|
||||
PlayerActionEvent input;
|
||||
if (turnStatus == 1) {
|
||||
input = game.ScheduleInput(startBeat, 5, MannequinFactory.InputAction_Second, StampJust, StampMiss, null);
|
||||
} else {
|
||||
input = game.ScheduleUserInput(startBeat, 5, MannequinFactory.InputAction_Second, StampUnJust, StampMiss, null);
|
||||
}
|
||||
input.IsHittable = () => !game.StampAnim.IsPlayingAnimationNames("StampEmpty", "StampJust");
|
||||
}),
|
||||
});
|
||||
|
||||
PlayerActionEvent input;
|
||||
if (needSlap) {
|
||||
input = game.ScheduleInput(startBeat, 3, MannequinFactory.InputAction_First, SlapJust, SlapMiss, null);
|
||||
} else {
|
||||
input = game.ScheduleUserInput(startBeat, 3, MannequinFactory.InputAction_First, SlapUnJust, SlapMiss, null);
|
||||
}
|
||||
input.IsHittable = () => !game.HandAnim.IsPlayingAnimationNames("SlapEmpty", "SlapJust");
|
||||
}
|
||||
|
||||
private void SlapJust(PlayerActionEvent caller, float state)
|
||||
{
|
||||
SlapHit(state);
|
||||
headSr.sprite = heads[turnStatus];
|
||||
}
|
||||
|
||||
private void SlapUnJust(PlayerActionEvent caller, float state)
|
||||
{
|
||||
eyesSr.transform.localScale = new Vector2(-1, 1);
|
||||
headSr.transform.localScale = new Vector2(-1, 1);
|
||||
headSr.sprite = heads[0];
|
||||
game.ScoreMiss();
|
||||
SlapHit(state);
|
||||
}
|
||||
|
||||
private void SlapHit(float state)
|
||||
{
|
||||
if (state >= 1f || state <= -1f) SoundByte.PlayOneShot("nearMiss");
|
||||
turnStatus++;
|
||||
SoundByte.PlayOneShotGame("mannequinFactory/slap");
|
||||
game.HandAnim.DoScaledAnimationAsync("SlapJust", 0.3f);
|
||||
headAnim.Play("Slapped", 0, 0);
|
||||
}
|
||||
|
||||
private void SlapMiss(PlayerActionEvent caller)
|
||||
{
|
||||
headAnim.DoScaledAnimationAsync("Move2", 0.3f);
|
||||
}
|
||||
|
||||
private void StampHit(float state)
|
||||
{
|
||||
if (state >= 1f || state <= -1f) SoundByte.PlayOneShot("nearMiss");
|
||||
headAnim.DoScaledAnimationAsync("Stamp", 0.3f);
|
||||
game.StampAnim.DoScaledAnimationAsync("StampJust", 0.3f);
|
||||
SoundByte.PlayOneShotGame("mannequinFactory/eyes");
|
||||
eyesSr.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
private void StampJust(PlayerActionEvent caller, float state)
|
||||
{
|
||||
StampHit(state);
|
||||
|
||||
MultiSound.Play(new MultiSound.Sound[] {
|
||||
new MultiSound.Sound("mannequinFactory/claw1", startBeat + 6),
|
||||
new MultiSound.Sound("mannequinFactory/claw2", startBeat + 6.5),
|
||||
});
|
||||
BeatAction.New(game, new List<BeatAction.Action> {
|
||||
new BeatAction.Action(startBeat + 5.75, delegate { headAnim.DoScaledAnimationAsync("Grabbed1", 0.3f); }),
|
||||
new BeatAction.Action(startBeat + 6 , delegate { headAnim.DoScaledAnimationAsync("Grabbed2", 0.3f); }),
|
||||
});
|
||||
}
|
||||
|
||||
private void StampUnJust(PlayerActionEvent caller, float state)
|
||||
{
|
||||
StampHit(state);
|
||||
eyesSr.sprite = eyes[1];
|
||||
|
||||
BeatAction.New(game, new List<BeatAction.Action> {
|
||||
new BeatAction.Action(startBeat + 6, delegate {
|
||||
SoundByte.PlayOneShotGame("mannequinFactory/miss");
|
||||
headAnim.DoScaledAnimationAsync("StampMiss", 0.3f);
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
private void StampMiss(PlayerActionEvent caller)
|
||||
{
|
||||
headAnim.DoScaledAnimationAsync("Move3", 0.3f);
|
||||
BeatAction.New(game, new List<BeatAction.Action> {
|
||||
new BeatAction.Action(startBeat + 6.5, delegate {
|
||||
SoundByte.PlayOneShotGame("mannequinFactory/miss");
|
||||
headAnim.DoScaledAnimationAsync("Miss", 0.3f);
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
// animation event
|
||||
public void DestroySelf()
|
||||
{
|
||||
Destroy(this);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/Games/MannequinFactory/MannequinHead.cs.meta
Normal file
11
Assets/Scripts/Games/MannequinFactory/MannequinHead.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6b776b7f3531104982259e4ca09d7d5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -266,6 +266,17 @@ namespace HeavenStudio
|
||||
Debug.LogWarning("Game loader NtrBackbeatLoader failed!");
|
||||
}
|
||||
|
||||
Debug.Log("Running game loader AgbMannequinFactoryLoader");
|
||||
game = AgbMannequinFactoryLoader.AddGame(eventCaller);
|
||||
if (game != null)
|
||||
{
|
||||
eventCaller.minigames.Add(game.name, game);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Game loader AgbMannequinFactoryLoader failed!");
|
||||
}
|
||||
|
||||
Debug.Log("Running game loader RvlManzaiLoader");
|
||||
game = RvlManzaiLoader.AddGame(eventCaller);
|
||||
if (game != null)
|
||||
|
@ -73,6 +73,10 @@ namespace HeavenStudio.Util
|
||||
if (!double.IsNaN(startBeat)) {
|
||||
var cond = Conductor.instance;
|
||||
var animClip = Array.Find(anim.runtimeAnimatorController.animationClips, x => x.name == animName);
|
||||
if (animClip == null) {
|
||||
Debug.LogError("Animation clip " + animName + " not found!");
|
||||
return;
|
||||
}
|
||||
double animLength = cond.SecsToBeats(animClip.length, cond.GetBpmAtBeat(startBeat));
|
||||
pos = cond.GetPositionFromBeat(startBeat, animLength) * timeScale;
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user